我知道可以使用各种优化的现成函数来执行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列表推导,但是我正在寻找一种更快的方法,如果有的话)
答案 0 :(得分:1)
我认为您正在寻找这个:
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循环中的行,对于删除循环来说更优雅)。此代码和您的代码的输出应该相同。如果您设置为不使用其中任何一个,请告诉我们您编辑帖子的限制。
另一种不使用skimage软件包(仅使用numpy但稍长的代码)的类似方法是here。