I am studying image processing using Numpy and am facing a convolution filtering issue.
I would like to collapse the gray image. (flatten a 2d array with a smaller 2d array)
Anyone have an idea to refine my method?
I know that scipy supports convolve2d, but I want to make convolve2d only with Numpy.
What I've done
First I made a 2d array of submatrices.
a = np.arange(25).reshape(5,5)
the submatrices seem complicated, but what I'm doing is shown in the following figure.

Then I multiplied each sub-matrix using a filter.
conv_filter = np.array([[0,-1,0],[-1,4,-1],[0,-1,0]]) multiplied_subs = np.einsum('ij,ijkl->ijkl',conv_filter,submatrices)

and let them down.
np.sum(np.sum(multiplied_subs, axis = -3), axis = -3)
Thus, this procedure can be called my convolve2d.
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)
However, I find this my_convolve2d unpleasant for 3 reasons.
- The generation of submatrices is too inconvenient, which makes it difficult to read, and it can be used only with a filter value of 3 * 3.
- The size of the variable submatrix seems too large because it is approximately 9 times larger than the original matrix.
- Summing up seems a bit unintuitive. Simply put, ugly.
Thanks for reading this far.
Type of update. I wrote conv3d for myself. I will leave it as the public domain.
def convolve3d(img, kernel):