代码之家  ›  专栏  ›  技术社区  ›  Bn.F76

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

  •  1
  • Bn.F76  · 技术社区  · 8 年前

    我有一个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. 。然而,对于每个维度,我想乘以 B 在“窗口”中,每次滑动1 A. 直到我不能再往前走了,这时我回到开头,向下滑动1个单位,然后再逐个乘以 B 具有 A. ,直到结束,然后向下移动并重复,直到你不越过边界。结果存储在矩阵的相应“三维”中 C 。所以我的结果是 [3x4x4] 矩阵

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

    想象 B “overtop”of A. ,从右角开始,我乘以 A. 具有 B 存储结果的s[1x3x3]部分 C 。。。

    参考第1个尺寸中的第1个单元(位于第1行和第1列) C 。。。

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

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

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

    然后重复这一过程,滑过、滑下、滑过和。。。,对于 B[2,:,:] B[3,:,:] 结束 A. 同样,存储在 C2,:,:] C[3,:,:] 分别地

    做这件事的好方法是什么?

    1 回复  |  直到 8 年前
        1
  •  3
  •   Praveen    8 年前

    我想你是在问三种不同核的二维互相关,而不是简单的矩阵乘法。

    下面的代码并不是实现这一点的最有效方法,但这是否为您提供了您想要的答案?我正在使用 scipy.signal.correlate2d 要在此处实现2D关联。。。

    >>> 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]]])
    

    这里有一种更“有趣”的方法,它不使用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