从cv2解读索贝尔

2024-05-19 03:03:04 发布

您现在位置:Python中文网/ 问答频道 /正文

{l}试图理解卷积。在

根据documentation,Sobel核是

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

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

^{pr2}$

现在,我有一个问题来解释输出。我用手工计算得到了不同的结果。据我所知,我必须将核心放在每个像素的中心,然后乘以元素和。在

因此,输出中的第一个条目应该是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]]

Tags: importimgoutputnpabscv2cvprint
1条回答
网友
1楼 · 发布于 2024-05-19 03:03:04

阅读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

输出:

^{pr2}$

默认边框类型

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像素后的正确值都是零–这就是通过运行脚本得到的结果。在

相关问题 更多 >

    热门问题