大家好,欢迎来到IT知识分享网。
索贝尔算子(Sobel operator)
主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量。
Sobel算子是一种常用的边缘检测算子,是一阶的梯度算法;Sobel算子是结合了高斯平滑与微分运算的结合方法,所以它的抗噪声能力很强。用户可以设定求导方向,水平或者垂直(通过参数yorder和xorder)。也可以指定卷积核大小,通过参数ksize。如果ksize=-1,那么一个3*3的scharr滤波器会被使用,该滤波器会得到比Sobel滤波器更好的效果。
对噪声具有倾斜作用,提供精确的边缘信息,边缘定位精度不够高;当对精度要求不是很高时,是一种多种常用的边缘检测方法。
常见的应用和物理意义是边缘检测。
Sobel卷积因子为:
该算子包含两组3×3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像灰度值,其公式如下:
具体计算如下:
其中f(a,b), 表示图像(a,b)点的灰度值;
G x = ( − 1 ) ∗ f ( x − 1 , y − 1 ) + 0 ∗ f ( x , y − 1 ) + 1 ∗ f ( x + 1 , y − 1 ) G_x=(-1)*f(x-1,y-1)+0*f(x,y-1)+1*f(x+1,y-1) Gx=(−1)∗f(x−1,y−1)+0∗f(x,y−1)+1∗f(x+1,y−1)
+ ( − 2 ) ∗ f ( x − 1 , y ) + 0 ∗ f ( x , y ) + 2 ∗ f ( x + 1 , y ) + (-2)*f(x-1,y)+0*f(x,y)+2*f(x+1,y) +(−2)∗f(x−1,y)+0∗f(x,y)+2∗f(x+1,y)
+ ( − 1 ) ∗ f ( x − 1 , y + 1 ) + 0 ∗ f ( x , y + 1 ) + 1 ∗ f ( x + 1 , y + 1 ) +(-1)*f(x-1,y+1)+0*f(x,y+1)+1*f(x+1,y+1) +(−1)∗f(x−1,y+1)+0∗f(x,y+1)+1∗f(x+1,y+1)结果: [f(x+1,y-1)+2f(x+1,y)+f(x+1,y+1)]-[f(x-1,y-1)+2f(x-1,y)+f(x-1,y+1)]
G y = 1 ∗ f ( x − 1 , y − 1 ) + 2 ∗ f ( x , y − 1 ) + 1 ∗ f ( x + 1 , y − 1 ) G_y=1*f(x-1,y-1)+2*f(x,y-1)+1*f(x+1,y-1) Gy=1∗f(x−1,y−1)+2∗f(x,y−1)+1∗f(x+1,y−1)
+ 0 ∗ f ( x − 1 , y ) + 0 ∗ f ( x , y ) + 0 ∗ f ( x + 1 , y ) + 0*f(x-1,y)+0*f(x,y)+0*f(x+1,y) +0∗f(x−1,y)+0∗f(x,y)+0∗f(x+1,y)
+ ( − 1 ) ∗ f ( x − 1 , y + 1 ) + ( − 2 ) ∗ f ( x , y + 1 ) + ( − 1 ) ∗ f ( x + 1 , y + 1 ) +(-1)*f(x-1,y+1)+(-2)*f(x,y+1)+(-1)*f(x+1,y+1) +(−1)∗f(x−1,y+1)+(−2)∗f(x,y+1)+(−1)∗f(x+1,y+1)结果:[f(x-1,y-1) + 2f(x,y-1) + f(x+1,y-1)]-[f(x-1, y+1) + 2*f(x,y+1)+f(x+1,y+1)]
- 图像的每一个像素的横向及纵向灰度值通过以下公式结合,来计算该点灰度的大小:
G = G x 2 + G y 2 G=\sqrt {G_x^2+G_y^2} G=Gx2+Gy2
通常,为了提高效率 使用不开平方的近似值:
∣ G ∣ = ∣ G x ∣ + ∣ G y ∣ |G|=|G_x|+|G_y| ∣G∣=∣Gx∣+∣Gy∣
如果梯度G大于某一阀值 则认为该点(x,y)为边缘点。
梯度方向:
角 度 值 = a r c t a n ( G y G x ) 角度值=arctan(\frac{G_y}{G_x}) 角度值=arctan(GxGy)
Sobel提取边缘步骤:
-
高斯模糊平滑降噪
-
转灰度空间
-
求X和Y方向的梯度(求导)
Sobel(src,xsrc,CV_16S,1,0,3); Sobel(src,ysrc,CV_16S,0,1,3);
-
像素取绝对值
convertScaleAbs(A,B);//计算图像A的像素绝对值,输出到图像B -
相加X和Y,得到综合梯度,称为振幅图像。
addWeighted(A,0.5,B,0.5,0,AB);//混合权重相加,效果较差
OpenCV中的API
1. Sobel
- 函数说明
使用扩展的Sobel运算符计算第一,第二,第三或混合图像导数。 - 函数声明
void Sobel( InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT );
- 函数参数
src 输入图像。 dst 输出与src相同大小和相同通道数的图像。 ddepth 输出图像深度 dx 表示x方向上的差分阶数,1或0 。 dy 表示y 方向上的差分阶数,1或0 。 ksize 表示Sobel算子的大小;它必须是1、3、5或7。注意:只可以是小于7 的奇数。 scale 表示缩放导数的比例常数,默认情况下没有伸缩系数。 delta 表示一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中。 ddepth参数表示输出图像深度,针对不同的输入图像,输出目标图像有不同的深度。
具体组合如下:- src.depth() = CV_8U,
ddepth = -1 / CV_16S / CV_32F / CV_64F - src.depth() = CV_16U/CV_16S,
ddepth = -1/CV_32F/CV_64F - src.depth() = CV_32F,
ddepth = -1/CV_32F/CV_64F - src.depth() = CV_64F,
ddepth = -1/CV_64F - 当 ddepth为-1时, 输出图像将和输入图像有相同的深度。输入8位图像则会截取顶端的导数。
- src.depth() = CV_8U,
2. convertScaleAbs
-
函数说明
缩放,计算绝对值,然后将结果转换为8位。在输入数组的每个元素上,函数convertScaleAbs依次执行三个操作:缩放,获取绝对值,转换为无符号的8位类型:
d s t ( I ) = s a t u r a t e _ c a s t < u c h a r > ( ∣ s r c ( I ) ∗ a l p h a + b e t a ∣ ) dst(I)=saturate\_cast<uchar>(|src(I)∗alpha+beta|) dst(I)=saturate_cast<uchar>(∣src(I)∗alpha+beta∣)
如果是多通道阵列,该函数将独立处理每个通道。当输出不是8位时,可以通过调用Mat :: convertTo方法(或使用矩阵表达式),然后通过计算结果的绝对值来模拟该操作。 -
函数声明
void convertScaleAbs( InputArray src, OutputArray dst, double alpha = 1, double beta = 0 );
-
函数参数
src 输入数组 dst 输出数组 alpha 可选比例因子。 beta 可选增量添加到缩放值。
3. addWeighted
-
函数说明
计算两个数组的加权和。函数addWeighted计算两个数组的加权和,如下所示:
d s t ( I ) = s a t u r a t e ( s r c 1 ( I ) ∗ a l p h a + s r c 2 ( I ) ∗ b e t a + g a m m a ) dst(I)=saturate(src1(I)∗alpha+src2(I)∗beta+gamma) dst(I)=saturate(src1(I)∗alpha+src2(I)∗beta+gamma)
I是数组元素的多维索引。在多通道阵列的情况下,每个通道都是独立处理的。该函数可以替换为矩阵表达式:
d s t = s r c 1 ∗ a l p h a + s r c 2 ∗ b e t a + g a m m a dst = src1 * alpha + src2 * beta + gamma dst=src1∗alpha+src2∗beta+gamma注意
当输出数组的深度为CV_32S时,不应用Saturation。在溢出的情况下,您甚至可能会得到错误符号的结果。 -
函数声明
void addWeighted( InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1 )
-
函数参数
src1 第一个输入数组 alpha 第一个数组元素的权重 src2 第二个输入数组 beta 第二个数组元素的权重 gamma 参数表示一个加到权重总和上的标量值 dst 输出数组,其大小和通道数与输入数组相同 dtype 输出数组的可选深度;当两个输入数组的深度相同时,dtype可以设置为-1,等效于src1.depth() -
应用举例
Mat src=imread("D:/test/src.jpg",0); Mat dst_x, dst_y,dst; GaussianBlur(src, dst_x, Size(3,3), 0,0); imshow("src", src); Sobel(src, dst_x, CV_16S,1, 0, 3); Sobel(src, dst_y, CV_16S,0, 1, 3); convertScaleAbs(dst_x , dst_x); convertScaleAbs(dst_y , dst_y); addWeighted(dst_x, 0.5, dst_y, 0.5,0, dst); imshow("src", src); imshow("dst_x", dst_x); imshow("dst_y", dst_y); imshow("dst", dst);
x梯度:
y梯度:
仔细观察三张图不难发现,X方向梯度在Y方向上边缘较为清晰,而Y方向梯度在X方向上边缘较为清晰,合并后的图像则综合了两张图的特征。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/15986.html