pythonopencvconvolution

# How to do convolution in OpenCV

I am trying to find convolution in OpenCV using filter2D method but the result is not correct

``````import cv2 as cv
import scipy.signal as sig
import numpy as np
b=np.asarray([[1,2,0,1,2],
[2,3,1,1,2],
[1,4,2,2,0],
[3,2,3,3,0],
[1,0,0,2,1]
],dtype=np.uint8)

w=np.asarray([[1,1,1],
[1,1,2],
[2,1,1]],dtype=np.uint8)
w_r=np.asarray([[1,1,1],
[2,1,1],
[1,1,1]
],dtype=np.uint8)
print(sig.convolve2d(b,w,mode="same"))
kernel_r=np.asarray([[1,1,1],[1,1,2],[2,1,1]])
print("-------")
print(cv.filter2D(b,-1,w_r))
``````

First output is generated by scipy.signal.convolve2D that is correct. The second output is generated by OpenCV filter2D which is not correct. how can i get the correct results.

``````[[ 8 10 10  7  7]
[15 18 20 14  9]
[18 23 26 18 10]
[15 21 22 16 11]
[ 8 13 13  9  8]]
-------
[[23 16 15 11 13]
[25 18 19 12 13]
[28 22 25 16 16]
[19 19 20 16 18]
[15 18 18 15 19]]
``````

Solution

• I assume, you wanted to use some rotated kernel `w_r` in your `cv.filter2d` call as also mentioned in the `filter2d` documentation:

If you need a real convolution, flip the kernel using `flip` and [...]

So, first problem is, that your manually set `w_r` is not the correct, flipped version of `w`, you forgot a `2` there.

Second problem comes from, how `scipy.sig.convolve2d` handles boundaries:

boundary : str {‘fill’, ‘wrap’, ‘symm’}, optional

A flag indicating how to handle boundaries:

`fill`

pad input arrays with fillvalue. (default)

From the obtained values after convolution, it seems that the boundary is padded with `0`. There's a similar option for OpenCV's `filter2d`, see the `BorderTypes`, specifically `cv.BORDER_CONSTANT`. From tests it seems, that `0` is the default value here!? (Couldn't find any documentation on that by now.)

So, the corrected code could look like this (unnecessary stuff omitted here):

``````import cv2 as cv
import scipy.signal as sig
import numpy as np

b=np.asarray([[1,2,0,1,2],
[2,3,1,1,2],
[1,4,2,2,0],
[3,2,3,3,0],
[1,0,0,2,1]
], dtype=np.uint8)

w=np.asarray([[1,1,1],
[1,1,2],
[2,1,1]], dtype=np.uint8)

print(sig.convolve2d(b, w, mode="same"))
print("-------")
print(cv.filter2D(b, -1, cv.flip(w, -1), borderType=cv.BORDER_CONSTANT))
``````

Now, both outputs show the same result:

``````[[ 8 10 10  7  7]
[15 18 20 14  9]
[18 23 26 18 10]
[15 21 22 16 11]
[ 8 13 13  9  8]]
-------
[[ 8 10 10  7  7]
[15 18 20 14  9]
[18 23 26 18 10]
[15 21 22 16 11]
[ 8 13 13  9  8]]
``````

Hope that helps!