回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我正在研究使用Numpy的图像处理,并面临一个用卷积滤波的问题。</p>
<p><strong>我想卷积一个灰度图像。(用较小的二维数组卷积二维数组)</strong></p>
<p>有没有人想改进我的方法?</p>
<p>我知道<a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.convolve2d.html" rel="noreferrer">scipy</a>支持卷积2d,但我只想使用Numpy生成卷积2d。</p>
<h2>我所做的</h2>
<p>首先,我制作了一个二维阵列子矩阵。</p>
<pre><code>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:]]])
</code></pre>
<p>子矩阵看起来很复杂,但我正在做的是在下面的图纸。</p>
<p><a href="https://i.stack.imgur.com/VLRnQ.png" rel="noreferrer"><img src="https://i.stack.imgur.com/VLRnQ.png" alt="submatrices"/></a></p>
<p>接下来,我将每个子矩阵与一个过滤器相乘。</p>
<pre><code>conv_filter = np.array([[0,-1,0],[-1,4,-1],[0,-1,0]])
multiplied_subs = np.einsum('ij,ijkl->ijkl',conv_filter,submatrices)
</code></pre>
<p><a href="https://i.stack.imgur.com/lh8Ym.png" rel="noreferrer"><img src="https://i.stack.imgur.com/lh8Ym.png" alt="multiplied_subs"/></a></p>
<p>并总结了它们。</p>
<pre><code>np.sum(np.sum(multiplied_subs, axis = -3), axis = -3)
#array([[ 6, 7, 8],
# [11, 12, 13],
# [16, 17, 18]])
</code></pre>
<p>因此这个过程可以称为我的卷积2d</p>
<pre><code>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)
</code></pre>
<p>然而,我发现这个我的卷积有三个原因。</p>
<ol>
<li>子矩阵的生成过于笨拙,难以读取,只能在过滤器为3*3时使用</li>
<li>各种子矩阵的大小似乎太大了,因为它大约比原始矩阵大9倍。</li>
<li>这个总结似乎有点不直观。简单地说,丑。</li>
</ol>
<p>谢谢你读到这里。</p>
<p>有点更新。我给自己写了一个conv3d。我会把这个作为公共领域。</p>
<pre><code>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
</code></pre>