使用python和numpy的二维卷积

2024-05-13 23:41:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用numpy在python中执行二维卷积

我有一个二维数组,如下所示,行是内核H_r,列是H_c

data = np.zeros((nr, nc), dtype=np.float32)

#fill array with some data here then convolve

for r in range(nr):
    data[r,:] = np.convolve(data[r,:], H_r, 'same')

for c in range(nc):
    data[:,c] = np.convolve(data[:,c], H_c, 'same')

data = data.astype(np.uint8);

它不会产生我期望的输出,这段代码看起来还好吗,我认为问题在于从float32转换到8bit。最好的方法是什么

谢谢


Tags: innumpyfordatanprange数组内核
3条回答

因为您已经将内核分离了,所以应该只使用scipy中的sepfir2d函数:

from scipy.signal import sepfir2d
convolved = sepfir2d(data, H_r, H_c)

另一方面,你的代码看起来很好。。。

也许这不是最优化的解决方案,但这是我以前在numpy library for Python中使用的一个实现:

def convolution2d(image, kernel, bias):
    m, n = kernel.shape
    if (m == n):
        y, x = image.shape
        y = y - m + 1
        x = x - m + 1
        new_image = np.zeros((y,x))
        for i in range(y):
            for j in range(x):
                new_image[i][j] = np.sum(image[i:i+m, j:j+m]*kernel) + bias
return new_image

我希望这个代码能帮助其他有同样疑问的人。

问候。

编辑[2019年1月]

@Tashus comment bellow是正确的,因此@dudemeister's answer可能更为重要。他建议的函数也更有效,因为它避免了直接的二维卷积和需要的运算次数。

可能的问题

我相信您正在做两个一维卷积,第一个是每列卷积,第二个是每行卷积,并将第一个卷积的结果替换为第二个卷积的结果。

请注意,带'same'参数的^{}返回一个与所提供的最大值形状相等的数组,因此在进行第一次卷积时,已经填充了整个data数组。

在这些步骤中可视化数组的一个好方法是使用Hinton diagrams,这样就可以检查哪些元素已经有了值。

可能的解决方案

如果您的卷积矩阵是使用一维H_rH_c矩阵的结果,那么您可以尝试添加这两个卷积的结果(使用data[:,c] += ..而不是第二个data[:,c] =循环):

convolution core addition

另一种方法是对二维卷积数组使用^{},这可能是您最初想要做的。

相关问题 更多 >