Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从cv2解读索贝尔_Python_Cv2_Sobel - Fatal编程技术网

Python 从cv2解读索贝尔

Python 从cv2解读索贝尔,python,cv2,sobel,Python,Cv2,Sobel,我试图理解Python中cv2中的索贝尔卷积 根据Sobel的内核是 -1 0 1 -2 0 2 -1 0 1 因此,我尝试将其应用于以下img(二进制3x3数组): 现在,我有一个解释输出的问题。我手工计算,得到了不同的结果。据我所知,我必须将内核集中在每个像素(I,j)上,然后按元素进行乘法和求和 因此,输出中的第一个条目应该是2。程序返回0 我错了吗?我希望如此 代码 import cv2 import numpy as np img = np.array([[0,1,0],[1,0,

我试图理解Python中
cv2
中的索贝尔卷积

根据Sobel的内核是

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

现在,我有一个解释输出的问题。我手工计算,得到了不同的结果。据我所知,我必须将内核集中在每个像素
(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]]

阅读页面的第二段:

本节中描述的函数和类的另一个常见特征是,与简单的算术函数不同,它们需要外推一些不存在的像素的值。例如,如果要使用Gaussian 3x3滤波器平滑图像,则在处理每行中最左侧的像素时,需要它们左侧的像素,即图像外部的像素。您可以让这些像素与最左边的图像像素相同(“复制边界”外推方法),或者假设所有不存在的像素都是零(“恒定边界”外推方法),依此类推。OpenCV允许您指定外推方法。有关详细信息,请参阅函数
borderInterpolate()
以及下面部分中对
borderType
参数和各种函数的讨论

让它像你期望的那样工作 要使其按预期工作,必须明确指定要使用零值插值边界。像这样:

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.]]
BORDER_DEFAULT == BORDER_DEFAULT
BORDER_DEFAULT == BORDER_REFLECT101
BORDER_DEFAULT == BORDER_REFLECT_101
默认边框类型
borderType
的默认值是
BORDER\u default
,它在我的机器上与
BORDER\u REFLECT\u 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
输出:

img
[[ 0.  1.  0.]
 [ 1.  0.  1.]
 [ 0.  1.  0.]]
sobelx64f
[[ 2.  0. -2.]
 [ 2.  0. -2.]
 [ 2.  0. -2.]]
BORDER_DEFAULT == BORDER_DEFAULT
BORDER_DEFAULT == BORDER_REFLECT101
BORDER_DEFAULT == BORDER_REFLECT_101
BORDER\u REFLECT\u 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\u REFLECT\u 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像素后的正确值均为零–这就是运行脚本得到的结果。

噢,非常感谢您的解释。