具有三个 3x3 核的 6x6 阵列的二维互相关

2D cross-correlation of a 6x6 array with three 3x3 kernels

我有一个 6x6 矩阵:例如矩阵 A

array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23],
       [24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35]])

我还有一个 3x3x3 矩阵:例如矩阵 B

array([[[ 1, 7, 2],
        [ 5, 9, 3],
        [ 2, 8, 6]],

       [[ 3, 4, 6],
        [ 6, 8, 9],
        [ 4, 2, 8]],

       [[ 6, 4, 7],
        [ 8, 7, 8],
        [ 4, 4, 7]]])

最后,我有一个 3x4x4 矩阵 C,(4 行,4 列,3 维),它是空的(填充有 0s)

我想将 B 的每个“第三维”(即 [1,:,:][2,:,:][3,:,:])与 A 相乘。但是,对于每个维度,我想在 "windows" 中乘以 B,每次在 A 上滑动 1,直到我不能再进一步,此时我回到开头,幻灯片 1单位向下并再次滑动,将 BA 相乘,直到结束,然后向下移动并重复,直到你不越过边界。结果存储在矩阵 C 的相应“第三维”中。所以我的结果将是一个 [3x4x4] 矩阵。

例如。 (乘法是给出标量值的点积,np.sum((np.multiply(x,y)))),所以...

想象 AB "overtop",从右上角开始,我将 A 的 3x3 部分乘以 Bs [1x3x3]将结果存储在 C...

中的部分

参考C的第一个维度中的第一个单元(位于第1行第1列)...

C[1,0,0] = 340。因为 [[0,1,2],[6,7,8],[12,13,4]] 点积 [[1,7,2],[5,9,3],[2,8,6]]

A 上将 B 矩阵滑动 1,并将我的第二个结果存储在 C...

C[1,0,1] = 383。因为 [[1,2,3],[7,8,9],[13,14,15]] 点积 [[1,7,2],[5,9,3],[2,8,6]]

然后重复这个上下滑动和...的过程,再次B[2,:,:]B[3,:,:]超过A,存储在C2,:,:]C[3,:,:]分别。

执行此操作的好方法是什么?

我认为您问的是具有三个不同内核的二维 cross-correlation,而不是直接的矩阵乘法。

下面的一段代码不是最有效的方法,但是它能给您想要的答案吗?我在这里使用 scipy.signal.correlate2d 实现二维相关...

>>> from scipy.signal import correlate2d
>>> C = np.dstack([correlate2d(A, B[:, :, i], 'valid') for i in range(B.shape[2])])
>>> C.shape
(4, 4, 3)
>>> C
array([[[ 333,  316,  464],
        [ 372,  369,  520],
        [ 411,  422,  576],
        [ 450,  475,  632]],

       [[ 567,  634,  800],
        [ 606,  687,  856],
        [ 645,  740,  912],
        [ 684,  793,  968]],

       [[ 801,  952, 1136],
        [ 840, 1005, 1192],
        [ 879, 1058, 1248],
        [ 918, 1111, 1304]],

       [[1035, 1270, 1472],
        [1074, 1323, 1528],
        [1113, 1376, 1584],
        [1152, 1429, 1640]]])

这里有一个更 "fun" 的方法,它不使用 scipy,而是使用 stride_tricks。我不确定它是否更有效率:

>>> import numpy.lib.stride_tricks as st
>>> s, t = A.strides
>>> i, j = A.shape
>>> k, l, m = B.shape
>>> D = st.as_strided(A, shape=(i-k+1, j-l+1, k, l), strides=(s, t, s, t))
>>> E = np.einsum('ijkl,klm->ijm', D, B)
>>> (E == C).all()
True