我正在研究使用Numpy的图像处理,并面临一个用卷积滤波的问题。
我想卷积一个灰度图像。(用较小的二维数组卷积二维数组)
有没有人想改进我的方法?
我知道scipy支持卷积2d,但我只想使用Numpy生成卷积2d。
首先,我制作了一个二维阵列子矩阵。
a = np.arange(25).reshape(5,5) # original matrix
submatrices = np.array([
[a[:-2,:-2], a[:-2,1:-1], a[:-2,2:]],
[a[1:-1,:-2], a[1:-1,1:-1], a[1:-1,2:]],
[a[2:,:-2], a[2:,1:-1], a[2:,2:]]])
子矩阵看起来很复杂,但我正在做的是在下面的图纸。
接下来,我将每个子矩阵与一个过滤器相乘。
conv_filter = np.array([[0,-1,0],[-1,4,-1],[0,-1,0]])
multiplied_subs = np.einsum('ij,ijkl->ijkl',conv_filter,submatrices)
并总结了它们。
np.sum(np.sum(multiplied_subs, axis = -3), axis = -3)
#array([[ 6, 7, 8],
# [11, 12, 13],
# [16, 17, 18]])
因此这个过程可以称为我的卷积2d
def my_convolve2d(a, conv_filter):
submatrices = np.array([
[a[:-2,:-2], a[:-2,1:-1], a[:-2,2:]],
[a[1:-1,:-2], a[1:-1,1:-1], a[1:-1,2:]],
[a[2:,:-2], a[2:,1:-1], a[2:,2:]]])
multiplied_subs = np.einsum('ij,ijkl->ijkl',conv_filter,submatrices)
return np.sum(np.sum(multiplied_subs, axis = -3), axis = -3)
然而,我发现这个我的卷积有三个原因。
谢谢你读到这里。
有点更新。我给自己写了一个conv3d。我会把这个作为公共领域。
def convolve3d(img, kernel):
# calc the size of the array of submatracies
sub_shape = tuple(np.subtract(img.shape, kernel.shape) + 1)
# alias for the function
strd = np.lib.stride_tricks.as_strided
# make an array of submatracies
submatrices = strd(img,kernel.shape + sub_shape,img.strides * 2)
# sum the submatraces and kernel
convolved_matrix = np.einsum('hij,hijklm->klm', kernel, submatrices)
return convolved_matrix
使用上面的
as_strided
和@Crispin的einsum
技巧清理。将筛选器大小强制为展开形状。如果索引兼容,甚至应该允许非方形输入。您也可以使用fft(执行卷积的更快方法之一)
干杯, 丹
可以使用
as_strided
[1]生成子阵列:为了去掉第二个“丑陋”的和,改变
einsum
,这样输出数组只有j
和k
。这意味着你的第二个总结。相关问题 更多 >
编程相关推荐