gpt4 book ai didi

python - 从 cv2 解读索贝尔

转载 作者:行者123 更新时间:2023-12-02 08:43:38 24 4
gpt4 key购买 nike

我正在尝试理解 Python 中的 cv2 的索贝尔卷积。

根据documentation索贝尔核是

-1 0 1
-2 0 2
-1 0 1

因此,我尝试将其应用于以下 img (二进制 3x3 数组):

0 1 0
1 0 1
0 1 0

现在,我在解释输出时遇到问题。我手工计算并得到了不同的结果。据我所知,我必须将内核集中在每个像素 (i,j) 上,并按元素相乘并求和。

因此,输出中的第一个条目应该是 2。程序返回0

我错了吗?我希望如此。

代码

import cv2
import numpy as np

img = np.array([[0,1,0],[1,0,1],[0,1,0]]).astype(float)

# Output dtype = cv2.CV_8U
sobelx8u = cv2.Sobel(img,cv2.CV_8U,1,0,ksize=3)

# Output dtype = cv2.CV_64F. Then take its absolute and convert to cv2.CV_8U
sobelx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)

abs_sobel64f = np.absolute(sobelx64f)
sobel_8u = np.uint8(abs_sobel64f)

print 'img'
print img

print 'sobelx8u'
print sobelx8u

print 'sobelx64f'
print sobelx64f

print 'abs_sobel64f'
print abs_sobel64f

print 'sobel_8u'
print sobel_8u

输出

img
[[ 0. 1. 0.]
[ 1. 0. 1.]
[ 0. 1. 0.]]
sobelx8u
[[0 0 0]
[0 0 0]
[0 0 0]]
sobelx64f
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
abs_sobel64f
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
sobel_8u
[[0 0 0]
[0 0 0]
[0 0 0]]

最佳答案

阅读您的 documentation 的第二段页面:

Another common feature of the functions and classes described in this section is that, unlike simple arithmetic functions, they need to extrapolate values of some non-existing pixels. For example, if you want to smooth an image using a Gaussian 3x3 filter, then, when processing the left-most pixels in each row, you need pixels to the left of them, that is, outside of the image. You can let these pixels be the same as the left-most image pixels (“replicated border” extrapolation method), or assume that all the non-existing pixels are zeros (“constant border” extrapolation method), and so on. OpenCV enables you to specify the extrapolation method. For details, see the function borderInterpolate() and discussion of the borderType parameter in the section and various functions below.

使其按您的预期工作

为了让它按照您期望的方式工作,您必须明确指定您想要用零值插入边框。像这样:

import cv2
import numpy as np

img = np.array([[0,1,0],[1,0,1],[0,1,0]]).astype(float)

border = cv2.borderInterpolate(0, 1, cv2.BORDER_CONSTANT)
sobelx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3, borderType=border)

print 'img'
print img

print 'sobelx64f'
print sobelx64f

输出:

img
[[ 0. 1. 0.]
[ 1. 0. 1.]
[ 0. 1. 0.]]
sobelx64f
[[ 2. 0. -2.]
[ 2. 0. -2.]
[ 2. 0. -2.]]

默认边框类型

borderType 的默认值为 BORDER_DEFAULT,在我的机器上与 BORDER_REFLECT_101 相同。您可以运行此脚本在您的计算机上进行确认:

import cv2

for var in dir(cv2):
if not var.startswith('BORDER_'): continue
if cv2.__dict__[var] == cv2.BORDER_DEFAULT:
print 'BORDER_DEFAULT ==', var

输出:

BORDER_DEFAULT == BORDER_DEFAULT
BORDER_DEFAULT == BORDER_REFLECT101
BORDER_DEFAULT == BORDER_REFLECT_101

并且 BORDER_REFLECT_101 的工作方式与您的结果完全一致。以下是不同边框类型的说明:

BORDER_REPLICATE:     aaaaaa|abcdefgh|hhhhhhh
BORDER_REFLECT: fedcba|abcdefgh|hgfedcb
BORDER_REFLECT_101: gfedcb|abcdefgh|gfedcba
BORDER_WRAP: cdefgh|abcdefgh|abcdefg
BORDER_CONSTANT: iiiiii|abcdefgh|iiiiiii with some specified 'i'

对您得到的内容的说明

因此,默认的边框插值类型(BORDER_REFLECT_101)使您的数组在计算之前看起来像这样:

0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0

通过简单的算术,您可以确认将 Sobel 内核应用于内部 3x3 像素后的正确值全部为零 - 这就是您通过运行脚本得到的结果。

关于python - 从 cv2 解读索贝尔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51179926/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com