使用python和numpy的2d卷积

mik*_*kip 14 python numpy convolution

我试图使用numpy在python中执行2d卷积

我有一个2d数组,如下所示,行内核为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);
Run Code Online (Sandbox Code Playgroud)

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

谢谢

omo*_*tto 6

也许它不是最优化的解决方案,但这是我之前在python的numpy库中使用的实现:

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
Run Code Online (Sandbox Code Playgroud)

我希望这段代码可以帮助其他有同样疑问的人。

问候。

  • 在`image[i:i+m, j:j+m]`中不应该有`j:j+n`而不是`j:j+m`吗? (2认同)

小智 5

由于你已经将内核分开了,你应该只使用scipy中的sepfir2d函数:

from scipy.signal import sepfir2d
convolved = sepfir2d(data, H_r, H_c)
Run Code Online (Sandbox Code Playgroud)

另一方面,你在那里的代码看起来很好......


ber*_*111 5

编辑[2019年1月]

@Tashus发表评论是正确的,因此@dudemeister的回答可能更多.通过避免直接2D卷积和需要的操作次数,他建议的功能也更有效.

可能的问题

我相信你正在进行两次1d卷积,每列第一次,每行第二次,并用第二次的结果替换第一次的结果.

请注意,numpy.convolve'same'参数返回相同形状的阵列所提供的最大的一个,所以当你做第一个卷积您已经填充了整个data阵列.

在这些步骤中可视化阵列的一种好方法是使用Hinton图,这样您就可以检查哪些元素已经有值.

可能解决方案

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

卷积核心加法

另一种方法是使用scipy.signal.convolve2d2d卷积数组,这可能是你想要做的第一个.