如何在OpenCV中进行卷积

时间:2019-10-20 20:58:11

标签: python opencv convolution

我正在尝试使用filter2D方法在OpenCV中查找卷积,但结果不正确

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))

由scipy.signal.convolve2D生成的第一个输出正确。第二个输出是由OpenCV filter2D生成的,不正确。我如何获得正确的结果。

[[ 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]]

1 个答案:

答案 0 :(得分:0)

我假设您想在w_r调用中使用一些旋转的内核cv.filter2d,正如filter2d文档中所述:

  

如果需要真正的卷积,请使用flip和[...]

翻转内核

因此,第一个问题是,您手动设置的w_r不是正确的w翻转版本,您在那里忘记了2

第二个问题来自scipy.sig.convolve2d如何处理边界:

  

边界:str {'fill','wrap','symm'},可选

     

一个标志,指示如何处理边界:

     

fill

     

使用fillvalue填充输入数组。 (默认)

从卷积后获得的值看来,边界用0填充。 OpenCV的filter2d有一个类似的选项,请参见BorderTypes,特别是cv.BORDER_CONSTANT。从测试看来,0是此处的默认值!? (目前找不到任何相关文档。)

因此,更正后的代码可能如下所示(此处省略了不必要的内容):

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))

现在,两个输出都显示相同的结果:

[[ 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]]

希望有帮助!