scipy.ndimage.convolve 背后的数学

Dam*_*oiu 5 python scipy

虽然我已经找到了关于 scipy.ndimage.convolve 函数的文档并且我“实际上知道它是做什么的”,但当我尝试计算结果数组时,我无法遵循数学公式。让我们举个例子:

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]]) 
Run Code Online (Sandbox Code Playgroud)

我将不胜感激逐步计算。

小智 5

NDImage.convolve 上的详细信息

尽管我知道基本的 np.convolve,但我还是偶然发现了这个 NDImage 卷积,而且文档没有太多自我解释,所以我努力阅读并补充了之前的解释性帖子:

A. 基础知识:

参考:如果你的卷积概念不是很扎实,请参考以下

https://en.wikipedia.org/wiki/Kernel_(image_processing)

https://en.wikipedia.org/wiki/Convolution

  1. 本质上 NDimage.convolve 有 4 种模式,这篇文章专注于 Constant 模式,您可以使用 cval=0 或其他指定的值并根据需要添加填充的行和列(稍后会解释)

  2. 卷积本质上是从左和右滑动内核,然后再次从左到右逐步下降,直到达到所需(相同数量)数量的卷积元素

  3. 该函数将计算所需的填充行/列。在这种情况下,过滤器 K 是 3 x 3 矩阵,源图像是矩阵 a 是 4 x 4,因此您需要在顶部和底部填充两行,在左右两侧填充行(4 + 2 = 6,并且所需的行数或列数为 3 + 1 + 1 + 1 = 6,每张幻灯片将需要额外的一行或一列)

B. 操作:

  1. 在数组 a 的顶部和左侧添加一行和一列零(将 3 x 3 均匀地卷积到 4 x 4,

您需要在第 1 个和第 4 个滑动窗口中添加额外的填充行/列)以及底部和右侧填充零的行/列

  1. Flip the kernel K as Kflip: [[0,0,1], [0,1,1], [1,1,1]] 可以使用numpy np.flip (为什么需要翻转基本上与卷积与相关的概念,就像相反方向的双胞胎)

  2. 将翻转的 K 矩阵滑动到这个大小为 6 x 6 的扩展矩阵 [[0,0,0,0,0], [0,1,2,0,0], [0,5,3,0,4,0] ], [0,0,0,0,7], [0,9,3,0,0,0], [0,0,0,0,0]]

  3. 对于滑动窗口的第一步(注意内核的第一行列将与填充的零进行卷积),您将得到:

翻转 K 点和 [[0,0,0], [0,1,2], [0,5,3]] = 11 (1*1+1*2+1*5+1*3, 其他都是零)

(点和是指内部点元素相乘的总和,基本上只是将两个给定矩阵的相同位置的对应元素相乘)

  1. 向右滑动 K 一步,您将有 10 个(第一行由于填充零而全为零,第二行:1*2+,第三行 1*3 + 1*4,第四行由于 [0,0 ,0,0,7])

  2. 同样,您向右滑动另外两个步骤以获得卷积矩阵的所有四个元素(注意本行的第 4 行,我们再次对扩展的填充行/列进行了部分卷积)(

  3. 然后将 K 过滤器向下滑动一行并重置到“扩展/填充矩阵”的最左侧

您将再次拥有相同的 10(第一行:1*2+,第二行 1*3 + 1*4),依此类推