Python NumPy中的二维卷积矢量化

Python NumPy中的二维卷积矢量化,python,numpy,computer-vision,vectorization,convolution,Python,Numpy,Computer Vision,Vectorization,Convolution,我知道有各种优化的现成函数可用于执行2D卷积,但为了理解,我正在尝试实现我自己的2D卷积函数 以下是我目前所做的工作: convoluted = [] # TODO: Vectorize for i in range(0, M - m + 1): for j in range(0, N - n + 1): submatrix = x[i:i+m, j:j+n] convoluted.append(np.sum

我知道有各种优化的现成函数可用于执行2D卷积,但为了理解,我正在尝试实现我自己的2D卷积函数

以下是我目前所做的工作:

    convoluted = []
    # TODO: Vectorize
    for i in range(0, M - m + 1):
        for j in range(0, N - n + 1):
            submatrix = x[i:i+m, j:j+n]
            convoluted.append(np.sum([submatrix*kernel]))
    convoluted = np.array(convoluted).reshape(M - m + 1, N - n + 1)
请注意,
x
是输入图像数组,
(M,N)
是输入图像的形状,
(M,N)
是所用内核的形状

两个显式for循环相当慢。
有没有办法将其矢量化?感谢您的帮助

(我知道python列表理解可以使用,至少对于内部循环是这样,但我正在寻找一种更快的方法,如果有的话)

我想您正在寻找以下方法:

from skimage.util.shape import view_as_windows
sub_matrices = view_as_windows(x, (m,n), 1)
convoluted = np.einsum('ij,klij->kl',kernel,sub_matrices)
第一行从原始数组创建内核大小的窗口。第二行是简单的乘法和加法(与for循环中的行类似,删除for循环更加优雅)。此代码和您的代码的输出应该是相同的。如果您被设置为不使用其中任何一个,请告诉我们您编辑文章的限制


另一种不使用skimage包的类似方法(只使用numpy,但代码稍长)是

矢量化总是意味着Numpy。这是您所称的现成功能。其他人尝试了你正在做的事情,你应该能够找到一些源代码。添加到列表似乎效率低下。为什么不直接写入NumPy数组?@CrisLuengo你认为这样会更快吗?因为我读过解释np.append如何比list.append慢得多的帖子。或者你的意思是取一个numpy数组a并写一个[i,j]=?是的,您知道输出的大小,您可以创建一个预期大小的数组,并用您的计算结果填充它。