此函数是否正确计算卷积?

时间:2015-07-22 20:23:45

标签: python numpy matrix convolution

我需要编写一个基本函数来计算矩阵和内核之间的2D卷积。 我最近加入了Python,所以我很抱歉我的错误。 我的论文老师说我应该自己写一个,这样我就可以更好地处理它,并能够修改它以便将来改进。 我在网站上找到了这个函数的一个例子,但我不明白如何获得返回的值。

这是代码(来自http://docs.cython.org/src/tutorial/numpy.html

from __future__ import division
import numpy as np
def naive_convolve(f, g):
    # f is an image and is indexed by (v, w)
    # g is a filter kernel and is indexed by (s, t),
    #   it needs odd dimensions
    # h is the output image and is indexed by (x, y),
    #   it is not cropped
    if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1:
        raise ValueError("Only odd dimensions on filter supported")
    # smid and tmid are number of pixels between the center pixel
    # and the edge, ie for a 5x5 filter they will be 2.
    #
    # The output size is calculated by adding smid, tmid to each
    # side of the dimensions of the input image.
    vmax = f.shape[0]
    wmax = f.shape[1]
    smax = g.shape[0]
    tmax = g.shape[1]
    smid = smax // 2
    tmid = tmax // 2
    xmax = vmax + 2*smid
    ymax = wmax + 2*tmid
    # Allocate result image.
    h = np.zeros([xmax, ymax], dtype=f.dtype)
    # Do convolution
    for x in range(xmax):
        for y in range(ymax):
            # Calculate pixel value for h at (x,y). Sum one component
            # for each pixel (s, t) of the filter g.
            s_from = max(smid - x, -smid)
            s_to = min((xmax - x) - smid, smid + 1)
            t_from = max(tmid - y, -tmid)
            t_to = min((ymax - y) - tmid, tmid + 1)
            value = 0
            for s in range(s_from, s_to):
                for t in range(t_from, t_to):
                    v = x - smid + s
                    w = y - tmid + t
                    value += g[smid - s, tmid - t] * f[v, w]
            h[x, y] = value
    return h

我不知道这个函数是否从输入和滤波器中得到加权和,因为我在这里看不到总和。 我用

应用了这个
kernel = np.array([(1, 1, -1), (1, 0, -1), (1, -1, -1)])
file = np.ones((5,5))
naive_convolve(file, kernel)

我得到了这个矩阵:

[[ 1.  2.  1.  1.  1.  0. -1.]
 [ 2.  3.  1.  1.  1. -1. -2.]
 [ 3.  3.  0.  0.  0. -3. -3.]
 [ 3.  3.  0.  0.  0. -3. -3.]
 [ 3.  3.  0.  0.  0. -3. -3.]
 [ 2.  1. -1. -1. -1. -3. -2.]
 [ 1.  0. -1. -1. -1. -2. -1.]]

我尝试在函数的第一次完整迭代中进行手动计算(在纸上),并得到'h [0,0] = 0',因为矩阵乘积:'filter [0,0] * matrix [0,0]',但函数返回1.我对此非常困惑。 如果有人能帮我理解这里发生的事情,我将非常感激。谢谢! :)

1 个答案:

答案 0 :(得分:1)

是的,该函数正确计算卷积。您可以使用scipy.signal.convolve2d

进行检查
import numpy as np
from scipy.signal import convolve2d

kernel = np.array([(1, 1, -1), (1, 0, -1), (1, -1, -1)])
file = np.ones((5,5))

x = convolve2d(file, kernel)
print x

给出了:

[[ 1.  2.  1.  1.  1.  0. -1.]
 [ 2.  3.  1.  1.  1. -1. -2.]
 [ 3.  3.  0.  0.  0. -3. -3.]
 [ 3.  3.  0.  0.  0. -3. -3.]
 [ 3.  3.  0.  0.  0. -3. -3.]
 [ 2.  1. -1. -1. -1. -3. -2.]
 [ 1.  0. -1. -1. -1. -2. -1.]]

我不可能知道如何解释这一切,因为我不知道从哪里开始,而且我不知道所有其他解释如何对你不起作用。不过,我认为你正在做所有这些作为学习练习,所以你可以自己解决这个问题。从我在SO上看到的情况来看,在SO上提出重大问题并不能代替你自己解决问题。

您具体的问题

h[0,0] = 0 

在你的计算中不匹配这个矩阵是一个很好的矩阵。事实上,两者都是正确的。不匹配的原因是卷积的输出没有指定数学索引,而是暗示它们。中心由指数[0,0]在数学上表示,对应于上面矩阵中的x[3,3]