卷积算法的幼稚实现 [英] Naive Implementation of Convolution algorithm

查看:184
本文介绍了卷积算法的幼稚实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前正在通过斯坦福CS131的免费在线课程学习计算机视觉和机器学习。遇到了一些沉重的数学公式,并想知道是否有人可以只知道图像的高度,宽度和核的高度和宽度,来向我解释如何为卷积算法实现幼稚的4个嵌套的for循环。通过在线研究,我提出了这个解决方案。

Currently learning about computer vision and machine learning through the free online course by stanford CS131. Came across some heavy math formulas and was wondering if anyone could explain to me how one would go on about in implementing a naive 4 nested for loops for the convolution algorithm using only knowing the image height, width and kernel height and width. I was able to come up with this solution by researching online.

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循环将如何实现。而且,如果可以的话,可以将公式分解为更容易理解的公式,然后再从网上找到给定的数学公式。

I was able to understand this based on some website examples using this type of algorithm however, I can't seem to grasp how a 4 nested for loops would do it. And if you could, break down the formula into something more digestible then the given mathematical equation found online.

编辑:
只是为了澄清代码片段I在某种程度上,left可以正常工作了,我正在尝试提出一种优化程度较低,对初学者更友好的解决方案,例如以下代码所要求的内容:

Just to clarify while the code snippet I left works to a certain degree I'm trying to come up with a solution that's a bit less optimized and a bit more beginner friendly such as what this code is asking:

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


推荐答案

对于此任务 scipy.signal.correlate2d 是您的朋友。

For this task scipy.signal.correlate2d is your friend.

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

I wrapped your code in a function named 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

请注意,您的代码段引发了错误因为 out 未初始化。

Notice that your snippet throws an error because out is not initialized.

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

If you wish to perform convolution rather than correlation you could use 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

这篇关于卷积算法的幼稚实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆