Python scipy.ndimage.convalve背后的数学

Python scipy.ndimage.convalve背后的数学,python,scipy,Python,Scipy,虽然我已经找到了关于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 i

虽然我已经找到了关于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]]) 

我想一步一步的计算。

< P>只是热身考虑

k=np.数组([[1,0,0],[0,1,0],[0,0,0]]

而不是你的k,那么如果你

ndimage.convolve(a,k,mode='constant',cval=0.0)

你得到

array([[4, 2, 4, 0],
       [5, 3, 7, 4],
       [3, 0, 0, 7],
       [9, 3, 0, 0]])
请注意,任何元素都是其自身位置(由于k中的第二个1)与下方和右侧的位置(由于k中的第一个1)的总和,即上角的4是从上角的原始1加上从其对角向下的3

(可能)令人困惑的是,k的效果与您可能期望的相反,即对于上面的k,您可能期望第一个1将值添加到上方和左侧,而不是向下和右侧

现在回到你的:12(3向下,2横向)是9+3+0+0+0+0的和


请注意,矩阵之外的任何内容都假定为0。

有关NDImage.convalve的详细信息

尽管我知道基本的np.convalve,但我还是无意中发现了这个NDImage卷积,而且文档也不是那么自解释的,所以我努力仔细阅读并补充了前面的解释性文章:

A.基础知识:

参考:如果你对卷积的概念没有很好的基础,请参考以下内容

,

  • 本质上NDimage.convalve有4种模式,这篇文章主要关注常量模式,您可以使用cval=0或其他指定的值,并根据需要添加填充的行和列(将在稍后进行解释)

  • 卷积本质上是从左到右滑动内核,然后再从左到右向下移动,直到达到所需(相同数量)的卷积元素

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

  • B.操作:

  • 在数组a的顶部和左侧添加一行和一列零(要将a 3 x 3均匀卷积到4 x 4
  • 您需要在第一个和第四个滑动窗口中添加额外的填充行/列),并且在底部和右侧添加一行/列填充零

  • 将内核K翻转为Kflip:[[0,0,1],[0,1,1],[1,1,1]] 您可以使用numpy np.flip(为什么需要翻转它基本上与卷积与相关的概念有关,卷积与相关就像相反方向的孪生兄弟)

  • 将翻转后的K矩阵滑动到尺寸为6 x 6的扩展矩阵上[[0,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,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,7]而全零)

  • 同样,您可以向右滑动两步,以获得卷积矩阵的所有四个元素(注意,对于此行的第四行,我们在扩展的填充行/列上再次部分卷积)(

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


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

    我非常感谢您的解释。我终于明白了这些值是如何计算的/