将图像与内核 returns 空图像进行卷积

Convolving an image with kernel returns empty image

我接受了挑战,在 Python 中自己实现了一些 OpenCV 函数。这些函数中有很多都需要将图像与内核进行卷积,所以这是我为此编写的函数:

def convolve(img, kernel):  # img should have zero padding 
    kx, ky = kernel.shape  # kernel is square so kx == ky
    start, end = floor(kx / 2), ceil(kx / 2)
    x, y = img.shape
    convolved = np.zeros((x, y))

    for i in range(kx, x - kx):
        for j in range(kx, y - kx):
            convolved_area = img[i - start:i + end, j - start:j + end] * kernel
            convolved[i][j] = np.sum(convolved_area)

    return convolved

当我 运行 在我制作的图像和内核上执行此操作时,我收到了一张白色图像,唯一的颜色是黑色填充。

为了测试,我使用的内核是高斯内核:

for x in range(radius):
    for y in range(radius):     # Generate kernel with formula
        kernel[x][y] = exp( -0.5 * (pow((x-mean)/sigma, 2.0) + pow((y-mean)/sigma,2.0)) ) / (2 * pi * sigma * sigma)
        magnitude += kernel[x][y]

for x in range(radius):     # normalize kernel
    for y in range(radius):
        kernel[x][y] /= magnitude

我知道内核可以工作,因为使用 OpenCV 的 filter2D 函数对我有用:

convolved = cv2.filter2D(img, -1, kernel)

我的问题是为什么我的 convolve 功能不起作用?

您需要为位于

的图像指定 uint8 的数据类型
convolved = np.zeros((x, y))

成功

convolved = np.zeros((x, y), 'uint8')

但是我建议使用np.zeros_like()方法,它接受一个数组,returns数组用零填充,保留原始数据类型数组,这样您就不必指定 uint8:

convolved = np.zeros_like(img)

以上是最实用的,还有几个备选方案

convolved = np.zeros((x, y)).astype('uint8')

convolved = np.uint8(np.zeros((x, y))