【问题标题】:Naive Implementation of Convolution algorithm卷积算法的朴素实现
【发布时间】:2019-02-07 22:47:48
【问题描述】:

目前正在通过 stanford CS131 的免费在线课程学习计算机视觉和机器学习。遇到了一些繁重的数学公式,想知道是否有人可以向我解释如何在只知道图像高度、宽度和内核高度和宽度的情况下为卷积算法实现一个简单的 4 嵌套 for 循环。通过在线研究,我能够提出这个解决方案。

image_padded = np.zeros((image.shape[0] + 2, image.shape[1] + 2))
image_padded[1:-1, 1:-1] = image
for x in range(image.shape[1]):  # Loop over every pixel of the image
    for y in range(image.shape[0]):
        # element-wise multiplication of the kernel and the image
        out[y, x] = (kernel * image_padded[y:y + 3, x:x + 3]).sum()

我能够根据一些使用这种算法的网站示例来理解这一点,但是,我似乎无法理解 4 个嵌套的 for 循环是如何做到的。如果可以的话,把公式分解成比网上找到的给定数学方程更容易理解的东西。

编辑: 只是为了澄清我留下的代码 sn-p 在一定程度上有效,我正在尝试提出一个优化程度较低且对初学者更友好的解决方案,例如这段代码所要求的:

def conv_nested(image, kernel):
    """A naive implementation of convolution filter.

    This is a naive implementation of convolution using 4 nested for-loops.
    This function computes convolution of an image with a kernel and outputs
    the result that has the same shape as the input image.

    Args:
        image: numpy array of shape (Hi, Wi)
        kernel: numpy array of shape (Hk, Wk)

    Returns:
        out: numpy array of shape (Hi, Wi)
    """
    Hi, Wi = image.shape
    Hk, Wk = kernel.shape
    out = np.zeros((Hi, Wi))
    ### YOUR CODE HERE

    ### END YOUR CODE

    return out

【问题讨论】:

  • 首先,尝试手动操作。

标签: python image-processing scipy computer-vision convolution


【解决方案1】:

对于这个任务scipy.signal.correlate2d是你的朋友。

演示

我将您的代码包装在一个名为 naive_correlation 的函数中:

import numpy as np

def naive_correlation(image, kernel):
    image_padded = np.zeros((image.shape[0] + 2, image.shape[1] + 2))
    image_padded[1:-1, 1:-1] = image
    out = np.zeros_like(image)
    for x in range(image.shape[1]):image
        for y in range(image.shape[0]):
            out[y, x] = (kernel * image_padded[y:y + 3, x:x + 3]).sum()
    return out

请注意,您的 sn-p 会引发错误,因为 out 未初始化。

In [67]: from scipy.signal import correlate2d

In [68]: img = np.array([[3, 9, 5, 9],
    ...:                 [1, 7, 4, 3],
    ...:                 [2, 1, 6, 5]])
    ...: 

In [69]: kernel = np.array([[0, 1, 0],
    ...:                    [0, 0, 0],
    ...:                    [0, -1, 0]])
    ...: 

In [70]: res1 = correlate2d(img, kernel, mode='same')

In [71]: res1
Out[71]: 
array([[-1, -7, -4, -3],
       [ 1,  8, -1,  4],
       [ 1,  7,  4,  3]])

In [72]: res2 = naive_correlation(img, kernel)

In [73]: np.array_equal(res1, res2)
Out[73]: True

如果您希望执行卷积而不是相关,您可以使用convolve2d

编辑

这是你要找的吗?

def explicit_correlation(image, kernel):
    hi, wi= image.shape
    hk, wk = kernel.shape
    image_padded = np.zeros(shape=(hi + hk - 1, wi + wk - 1))    
    image_padded[hk//2:-hk//2, wk//2:-wk//2] = image
    out = np.zeros(shape=image.shape)
    for row in range(hi):
        for col in range(wi):
            for i in range(hk):
                for j in range(wk):
                    out[row, col] += image_padded[row + i, col + j]*kernel[i, j]
    return out

【讨论】:

  • 欣赏对这些库的洞察力,它并不是我想要的,但它确实给了我新的选择。不幸的是,我不能投票。
  • 编辑了我的答案以更好地满足您的需求
  • 谢谢老兄,真希望我能投票,但我的帐户达不到那个级别。
猜你喜欢
  • 2021-04-09
  • 2015-07-23
  • 2018-03-07
  • 1970-01-01
  • 2019-02-15
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多