Python 使用numpy/scipy计算矩阵中每个单元的邻域乘积

Python 使用numpy/scipy计算矩阵中每个单元的邻域乘积,python,numpy,Python,Numpy,我正在尝试实现一个图像处理算法,其中包括计算每个细胞的4个相邻邻域的乘积。也就是说,计算X的新矩阵Y,其中Y[i,j]=X[i-1,j]*X[i,j-1]*X[i+1,j]*X[i,j+1]。不受约束的邻居应该被忽略 现在我只能想到这种方法:使用scipy.ndimage.filters.correlate并用0和1传递权重,得到四个矩阵,每个矩阵包含每个单元格在一个方向上的邻居,就像传递weight=[[0,0,0],[1,0,0],[1,1]一样,我得到a[I,j]=x[I-1,j],通过其

我正在尝试实现一个图像处理算法,其中包括计算每个细胞的4个相邻邻域的乘积。也就是说,计算X的新矩阵Y,其中
Y[i,j]=X[i-1,j]*X[i,j-1]*X[i+1,j]*X[i,j+1]
。不受约束的邻居应该被忽略

现在我只能想到这种方法:使用
scipy.ndimage.filters.correlate
并用0和1传递权重,得到四个矩阵,每个矩阵包含每个单元格在一个方向上的邻居,就像传递
weight=[[0,0,0],[1,0,0],[1,1]
一样,我得到
a[I,j]=x[I-1,j]
,通过其他权重,我可以得到
b[I,j]=x[I,j-1]
c[I,j]=x[I+1,j]
d[I,j]=x[I,j+1]
。然后我使用
np.multiply
计算这四个矩阵的乘积


然而,这种方法有点太慢了,我不能忽略边界。有没有其他方法可以使用numpy/scipy来实现这一点,这样我就不必求助于for循环?

您需要单独写出边,但这与您对数组中心部分的要求相同,并且可能明显快于关联:

y = np.empty_like(x)
y[1:-1, 1:-1] = x[1:-1, 1:-1]
y[1:-1, 1:-1] *= x[:-2, 1:-1]
y[1:-1, 1:-1] *= x[2:, 1:-1]
y[1:-1, 1:-1] *= x[1:-1, :-2]
y[1:-1, 1:-1] *= x[1:-1, 2:]

我认为这更符合你的要求:

import numpy as np

x = np.array([
    [1, 2, 3, 4, 5],
    [6, 7, 8, 9, 1],
    [2, 3, 4, 5, 6],
    [7, 8, 9, 1, 2]
])

y = np.ones_like(x)
y[+1:, :] *= x[:-1, :]
y[:-1, :] *= x[+1:, :]
y[:, +1:] *= x[:, :-1]
y[:, :-1] *= x[:, +1:]

y
#>>> array([[  12,   21,   64,  135,    4],
#>>>        [  14,  288,  756,  160,  270],
#>>>        [ 126,  448, 1080,  216,   10],
#>>>        [  16,  189,   32,   90,    6]])

请注意,如果需要额外的速度,第一个
*=
可以是一个赋值。

如果首先获取日志,则它将是一个加法。2x2卷积离散拉普拉斯算子一旦是加法,将非常接近。只需要取消中心术语@Paul谢谢你的帮助,但是矩阵中可能有负数,所以我不能先获取日志。不应该是
y=numpy。像
这样的,然后删除第二行吗?