如何在 OpenCV 中进行卷积
How to do convolution in OpenCV
我正在尝试使用 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]]
我假设,你想在你的 cv.filter2d
调用中使用一些旋转内核 w_r
正如 filter2d
文档中也提到的那样:
If you need a real convolution, flip the kernel using flip
and [...]
所以,第一个问题是,您手动设置的 w_r
不是 w
的正确翻转版本,您在那里忘记了 2
。
第二个问题来自,scipy.sig.convolve2d
如何处理边界:
boundary : str {‘fill’, ‘wrap’, ‘symm’}, optional
A flag indicating how to handle boundaries:
fill
pad input arrays with fillvalue. (default)
从卷积后得到的值来看,似乎边界被填充了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]]
希望对您有所帮助!
我正在尝试使用 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]]
我假设,你想在你的 cv.filter2d
调用中使用一些旋转内核 w_r
正如 filter2d
文档中也提到的那样:
If you need a real convolution, flip the kernel using
flip
and [...]
所以,第一个问题是,您手动设置的 w_r
不是 w
的正确翻转版本,您在那里忘记了 2
。
第二个问题来自,scipy.sig.convolve2d
如何处理边界:
boundary : str {‘fill’, ‘wrap’, ‘symm’}, optional
A flag indicating how to handle boundaries:
fill
pad input arrays with fillvalue. (default)
从卷积后得到的值来看,似乎边界被填充了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]]
希望对您有所帮助!