具有三个 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 维),它是空的(填充有 0
s)
我想将 B
的每个“第三维”(即 [1,:,:]
、[2,:,:]
、[3,:,:]
)与 A
相乘。但是,对于每个维度,我想在 "windows" 中乘以 B
,每次在 A
上滑动 1,直到我不能再进一步,此时我回到开头,幻灯片 1单位向下并再次滑动,将 B
与 A
相乘,直到结束,然后向下移动并重复,直到你不越过边界。结果存储在矩阵 C
的相应“第三维”中。所以我的结果将是一个 [3x4x4]
矩阵。
例如。 (乘法是给出标量值的点积,np.sum((np.multiply(x,y)))
),所以...
想象 A
的 B
"overtop",从右上角开始,我将 A
的 3x3 部分乘以 B
s [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
我有一个 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 维),它是空的(填充有 0
s)
我想将 B
的每个“第三维”(即 [1,:,:]
、[2,:,:]
、[3,:,:]
)与 A
相乘。但是,对于每个维度,我想在 "windows" 中乘以 B
,每次在 A
上滑动 1,直到我不能再进一步,此时我回到开头,幻灯片 1单位向下并再次滑动,将 B
与 A
相乘,直到结束,然后向下移动并重复,直到你不越过边界。结果存储在矩阵 C
的相应“第三维”中。所以我的结果将是一个 [3x4x4]
矩阵。
例如。 (乘法是给出标量值的点积,np.sum((np.multiply(x,y)))
),所以...
想象 A
的 B
"overtop",从右上角开始,我将 A
的 3x3 部分乘以 B
s [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