虽然我已经找到了关于scipy.ndimage.convalve函数的文档,而且我“实际上知道它的作用”,但是当我试图计算得到的数组时,我无法遵循数学公式。举个例子:
a = np.array([[1, 2, 0, 0],`
[5, 3, 0, 4],
[0, 0, 0, 7],
[9, 3, 0, 0]])
k = np.array([[1,1,1],[1,1,0],[1,0,0]])
from scipy import ndimage
ndimage.convolve(a, k, mode='constant', cval=0.0)
# Why is the result like this ?
array([[11, 10, 7, 4],
[10, 3, 11, 11],
[15, 12, 14, 7],
[12, 3, 7, 0]])
我希望你能一步一步地计算。
最佳答案
ndimage.convalve的详细信息
我偶然发现了这个NDImage卷积,虽然我知道基本的np卷积,而且文档并不是很好地解释,所以我花了很大的努力来理解和补充前面的解释:
A.基础知识:
参考文献:如果你对卷积的概念没有很好的基础,请参考以下内容
https://en.wikipedia.org/wiki/Kernel_(image_processing),
https://en.wikipedia.org/wiki/Convolution
实际上ndimage.convalve有4种模式,本文主要关注常量模式,对于常量模式,您可以使用cval=0或其他指定的值,并根据需要添加填充的行和列(将在一小部分中进行说明)
卷积实质上是将内核从左到右滑动,然后再从左到右一步一步地向下移动,直到达到所需的(相同数量的)卷积元素数
函数将计算所需的填充行/列在这种情况下,过滤器k是3x 3矩阵,而源图像是matrix a是4x 4,因此您需要在顶部和底部加两个填充行,在左侧和右侧加两个填充行(4+2=6,需要的行数或列数是3+1+1+1=6,每个幻灯片将需要额外的一行或列)
B.操作:
在数组A的顶部和左侧添加一行零和一列零(要均匀地卷积一个3 x 3到4 x 4,
您需要在第一个和第四个滑动窗口处添加额外的填充行/列)以及在底部和右侧添加一行/列的填充零
将内核k翻转为k flip:[[0,0,1],[0,1,1],[1,1,1]]
你可以使用numpy np.flip(为什么它需要被翻转,基本上与卷积和相关的概念有关,卷积和相关就像相反方向的孪生兄弟)
将翻转后的K矩阵滑到这个尺寸为6 x 6的展开矩阵上[[0,0,0,0,0],[0,1,2,0,0],[0,5,3,0,4,0],[0,0,0,7],[0,9,3,0,0,0,0],[0,0,0]]
对于滑动窗口的第一步(请注意,内核的第一列将与填充的零卷积),您将得到:
翻转K点和[[0,0,0],[0,1,2],[0,5,3]]=11(1*1+1*2+1*5+1*3,其他为零)
(点和是指内部点元素相乘的和,基本上只需将两个给定矩阵的相同位置上的相应元素相乘)
将k向右滑动一步,您将有10个(第一行由于填充零而全部为零,第二行:1*2+,第三行1*3+1*4,第四行由于[0,0,0,0,7]而全部为零)
同样,您可以向右滑动两步,以获得卷积矩阵的所有四个元素(注意,对于这一行的第4个元素,我们再次部分卷积到展开的填充行/列上)(
然后将k过滤器向下滑动一行,并重置到“展开/填充矩阵”的最左边。
您将再次得到相同的10(第一行:1*2+,第二行:1*3+1*4),依此类推