Saj*_*bal 3 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))
Run Code Online (Sandbox Code Playgroud)
第一个输出是由 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]]
Run Code Online (Sandbox Code Playgroud)
w_r我假设您想在调用中使用一些旋转内核,cv.filter2d正如filter2d文档中提到的:
\n\n\n如果您需要真正的卷积,请使用和翻转内核
\nflip[...]
所以,第一个问题是,您的手动设置w_r不是正确的翻转版本w,您忘记了2那里。
第二个问题来自,如何scipy.sig.convolve2d处理边界:
\n\n\n边界:str {\xe2\x80\x98fill\xe2\x80\x99,\xe2\x80\x98wrap\xe2\x80\x99,\xe2\x80\x98symm\xe2\x80\x99},可选
\n\n指示如何处理边界的标志:
\n\n\n\n
fill用 fillvalue 填充输入数组。(默认)
\n
从卷积后得到的值来看,边界似乎是用 填充的0。OpenCV 有一个类似的选项filter2d,BorderTypes具体请参见cv.BORDER_CONSTANT。从测试看来,这0是这里的默认值!?(目前找不到任何相关文档。)
因此,更正后的代码可能如下所示(此处省略了不必要的内容):
\n\nimport cv2 as cv\nimport scipy.signal as sig\nimport numpy as np\n\nb=np.asarray([[1,2,0,1,2],\n [2,3,1,1,2],\n [1,4,2,2,0],\n [3,2,3,3,0],\n [1,0,0,2,1]\n ], dtype=np.uint8)\n\nw=np.asarray([[1,1,1],\n [1,1,2],\n [2,1,1]], dtype=np.uint8)\n\nprint(sig.convolve2d(b, w, mode="same"))\nprint("-------")\nprint(cv.filter2D(b, -1, cv.flip(w, -1), borderType=cv.BORDER_CONSTANT))\nRun Code Online (Sandbox Code Playgroud)\n\n现在,两个输出显示相同的结果:
\n\n[[ 8 10 10 7 7]\n [15 18 20 14 9]\n [18 23 26 18 10]\n [15 21 22 16 11]\n [ 8 13 13 9 8]]\n-------\n[[ 8 10 10 7 7]\n [15 18 20 14 9]\n [18 23 26 18 10]\n [15 21 22 16 11]\n [ 8 13 13 9 8]]\nRun Code Online (Sandbox Code Playgroud)\n\n希望有帮助!
\n| 归档时间: |
|
| 查看次数: |
15557 次 |
| 最近记录: |