今天来说说im2col和col2im函数,这是MATLAB中两个内置函数,经常用于数字图像处理中。其中im2col函数在《MATLAB中的im2col函数》一文中已经进行了简单的介绍。

一般来说:

  1. 如是将图像分割成块的时候用的im2col参数为'distinct',那么用col2im函数时参数也是'distinct',即可将转换后的数组复原。
  2. 如果将图像分割成块的时候用的im2col参数为'sliding',我目前还不知道MATLAB中使用内置函数是如何复原的。

今天,来看看Python中是如何实现这两个函数的(sliding类型)。

  1. 对于im2col的实现,我们沿着原始矩阵逐行计算,将得到的新的子矩阵展开成列,放置在列块矩阵中。
  2. 对于col2im的实现,我们沿着列块矩阵逐行计算,将得到的行展成子矩阵,然后将子矩阵放置在最终结果对应的位置(每次当前值进行相加),同时记录每个位置的值放置的次数。最后,将当前位置的值除以放置的次数,即可得到结果(原始矩阵)。
def im2col(mtx, block_size):
mtx_shape = mtx.shape
sx = mtx_shape[0] - block_size[0] + 1
sy = mtx_shape[1] - block_size[1] + 1
# 如果设A为m×n的,对于[p q]的块划分,最后矩阵的行数为p×q,列数为(m−p+1)×(n−q+1)。
result = np.empty((block_size[0] * block_size[1], sx * sy))
# 沿着行移动,所以先保持列(i)不动,沿着行(j)走
for i in range(sy):
for j in range(sx):
result[:, i * sx + j] = mtx[j:j + block_size[0], i:i + block_size[1]].ravel(order='F')
return result def col2im(mtx, image_size, block_size):
p, q = block_size
sx = image_size[0] - p + 1
sy = image_size[1] - q + 1
result = np.zeros(image_size)
weight = np.zeros(image_size) # weight记录每个单元格的数字重复加了多少遍
col = 0
# 沿着行移动,所以先保持列(i)不动,沿着行(j)走
for i in range(sy):
for j in range(sx):
result[j:j + p, i:i + q] += mtx[:, col].reshape(block_size, order='F')
weight[j:j + p, i:i + q] += np.ones(block_size)
col += 1
return result / weight

测试代码:

if __name__ == '__main__':
mtx = np.around(np.random.rand(5, 5) * 100)
print('原始矩阵:')
print(mtx) a1 = im2col(mtx, (2, 3))
print('im2col(分块大小2x3):')
print(a1)
b1 = col2im(a1, (5, 5), (2, 3))
print('col2im复原:')
print(b1) a2 = im2col(mtx, (3, 3))
print('im2col(分块大小3x3):')
print(a2)
b2 = col2im(a2, (5, 5), (3, 3))
print('col2im复原:')
print(b2)

运行结果:

原始矩阵:
[[ 48. 38. 38. 59. 38.]
[ 38. 11. 25. 52. 44.]
[ 60. 69. 49. 93. 66.]
[ 88. 8. 47. 14. 47.]
[ 96. 37. 56. 86. 54.]]
im2col(分块大小2x3):
[[ 48. 38. 60. 88. 38. 11. 69. 8. 38. 25. 49. 47.]
[ 38. 60. 88. 96. 11. 69. 8. 37. 25. 49. 47. 56.]
[ 38. 11. 69. 8. 38. 25. 49. 47. 59. 52. 93. 14.]
[ 11. 69. 8. 37. 25. 49. 47. 56. 52. 93. 14. 86.]
[ 38. 25. 49. 47. 59. 52. 93. 14. 38. 44. 66. 47.]
[ 25. 49. 47. 56. 52. 93. 14. 86. 44. 66. 47. 54.]]
col2im复原:
[[ 48. 38. 38. 59. 38.]
[ 38. 11. 25. 52. 44.]
[ 60. 69. 49. 93. 66.]
[ 88. 8. 47. 14. 47.]
[ 96. 37. 56. 86. 54.]]
im2col(分块大小3x3):
[[ 48. 38. 60. 38. 11. 69. 38. 25. 49.]
[ 38. 60. 88. 11. 69. 8. 25. 49. 47.]
[ 60. 88. 96. 69. 8. 37. 49. 47. 56.]
[ 38. 11. 69. 38. 25. 49. 59. 52. 93.]
[ 11. 69. 8. 25. 49. 47. 52. 93. 14.]
[ 69. 8. 37. 49. 47. 56. 93. 14. 86.]
[ 38. 25. 49. 59. 52. 93. 38. 44. 66.]
[ 25. 49. 47. 52. 93. 14. 44. 66. 47.]
[ 49. 47. 56. 93. 14. 86. 66. 47. 54.]]
col2im复原:
[[ 48. 38. 38. 59. 38.]
[ 38. 11. 25. 52. 44.]
[ 60. 69. 49. 93. 66.]
[ 88. 8. 47. 14. 47.]
[ 96. 37. 56. 86. 54.]]

Python实现im2col和col2im函数的更多相关文章

  1. Python中如何实现im2col和col2im函数(sliding类型)

    今天来说说im2col和col2im函数,这是MATLAB中两个内置函数,经常用于数字图像处理中.其中im2col函数在<MATLAB中的im2col函数>一文中已经进行了简单的介绍. 一 ...

  2. [python学习] 语言基础—排序函数(sort()、sorted()、argsort()函数)

    python的内建排序函数有 sort.sorted两个. 1.基础的序列升序排序直接调用sorted()方法即可 ls = list([5, 2, 3, 1, 4]) new_ls = sorted ...

  3. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  4. Python 函数式编程 & Python中的高阶函数map reduce filter 和sorted

    1. 函数式编程 1)概念 函数式编程是一种编程模型,他将计算机运算看做是数学中函数的计算,并且避免了状态以及变量的概念.wiki 我们知道,对象是面向对象的第一型,那么函数式编程也是一样,函数是函数 ...

  5. Python中的高阶函数与匿名函数

    Python中的高阶函数与匿名函数 高阶函数 高阶函数就是把函数当做参数传递的一种函数.其与C#中的委托有点相似,个人认为. def add(x,y,f): return f( x)+ f( y) p ...

  6. Python的函数式编程-传入函数、排序算法、函数作为返回值、匿名函数、偏函数、装饰器

    函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. ...

  7. python学习第十天 -- 函数

    稍微学过其他编程语言的人都应该了解函数的概念.在这里就不做过多的介绍. Python内置了很多有用的函数,我们可以也直接调用. 可以直接从Python的官方网站查看文档: http://docs.py ...

  8. Python新手学习基础之函数-概念与定义

    什么是函数? 函数是可以实现一些特定功能的方法或是程序,简单的理解下函数的概念,就是你编写了一些语句,为了方便使用,把这些语句组合在一起,给它起一个名字,即函数名.使用的时候只要调用这个名字,就可以实 ...

  9. 初学 Python(十三)——匿名函数

    初学 Python(十三)--匿名函数 初学 Python,主要整理一些学习到的知识点,这次是匿名函数. # -*- coding:utf-8 -*- #关键字lambda定义的函数都是匿名函数 #做 ...

随机推荐

  1. JS 实现打印

    <input id="btnPrint" type="button" value="打印预览" onclick=preview(1) ...

  2. php xml格式对象 返回->对应格式数组

    /*     * $objXml xml格式对象      * 返回 : 对应格式数组     */    public function XmlString2Arr($xml)    {       ...

  3. BZOJ2596 : [Wc2007]疯狂赛车

    根据光路最快原理以及斯涅尔定律,可以得到从定点$P$进入某条直线的最佳入射角. 求出每个端点到每条线段的最佳点,建图求最短路即可. 时间复杂度$O(n^2\log n)$. #include<c ...

  4. BZOJ4966 : 总统选举

    线段树维护每个点的最有可能是答案的数以及它的权重. 合并两个节点的时候,将权重互相抵消,保留较大的那一个. 得到答案后,再在对应权值的Treap中查询出现次数,检查是否真正是答案. 时间复杂度$O(n ...

  5. 关于setTimeout和setInterval的函数参数问题

    今天在写验证码倒计时小demo时,用了如下代码: window.setTimeout(count(num),1000); 这样直接使用将使count函数立即执行,并将返回值传递给setTimeout函 ...

  6. es6学习笔记一:迭代器和for-of循环

    我们如何遍历一个数组呢?在20年前,我们是这样遍历一个数组的: var myArr = []; for (var i = 0; i < arr.length; i++) { console.lo ...

  7. GMA Round 1 简单的线性规划

    传送门 简单的线性规划 已知D(x,y)满足$\left\{\begin{matrix}x>-3\\ y>1\\ x+y<12\end{matrix}\right.$ 求$\frac ...

  8. fzu1050 Number lengths(对数公式)

    http://acm.fzu.edu.cn/problem.php?pid=1050 cmath头文件里有两种对数log()和log10(),一个是自然对数,一个是以10为底, 求n!的位数,根据对数 ...

  9. SpringBoot无废话入门01:最简SpringBoot应用

    虽然本篇讲的是一个最简的SpringBoot应用,但是要说明的是:学习SpringBoot是有门槛的,这个门槛就是, 1:首先得有框架的基础,比如SSM: 2:MAVEN基础. 在学好上面两者的基础上 ...

  10. Unsupervised pre-training

    如图所示: 假设你想要解决一个复杂的任务,你没有太多的标记的训练数据,但不幸的是,你不能找到一个类似的任务训练模型. 不要失去所有希望! 首先,你当然应该尝试收集更多的有标签的训练数据,但是如果这太难 ...