有 关于sobel和canny的区别_sobel方面的知识,小编在此整里出来,给大家作为参考,下面就详细的介绍一下关于sobel和canny的区别_sobel的相关内容。
1、思想:
(相关资料图)
2、算子使用两个3*3的矩阵算子分别和原始图片作卷积,分别得到横向Gx和纵向格雷的梯度值,如果梯度值大于某一个阈值,则认为该点为边缘点;
3、矩阵转换:
4、事实上卷积矩阵也可以由两个一维矩阵卷积而成,在opencv源码中就是用两个一维矩阵卷积生成一个卷积矩阵:
5、梯度值:
6、图像的梯度低茄值由以下公式计算:
7、图像近似梯度值如下:
8、对于原始图像,P5的梯度值为:
9、OpenCV2410,sobel算子函数原型:
10、void Sobel(InputArray src,
11、输出数组夏令时,
12、中间深度,
13、int dx,
14、int dy,
15、int ksize=3,
16、双刻度=1,
17、双=0,
18、int borderType=BORDER_DEFAULT)
19、函数参数解释:
20、输入数组src:输入的原图像,Mat类型
21、输出数组夏令时:输出的边缘检测结果图像,Mat类型,大小与原图像相同。
22、中间深度:输出图像的深度,针对不同的输入图像,输出目标图像有不同的深度,具救吐速体组合如下:
23、-若src.depth()=CV_8U,取ddepth=-1/CV_16S/CV_32F/CV_64F
24、-若src.depth()=CV_16U/CV_16S,取ddepth=-1/CV_32F/CV_64F
25、-若src.depth()=CV_32F,取ddepth=-1/CV_32F/CV_64F
26、-若src.depth()=CV_64F,取ddepth=-1/CV_64F
27、注:ddepth=-1时,代表输出图像与输入图像相同的深度。冷敏
28、int dx:int类型dx,x方向上的差分阶数,1或0
29、int dy:int类型dy,y方向上的差分阶数,1或0
30、其中,dx=1,dy=0,表示计算X方向的导数,检测出的是垂直方向上的边缘;
31、dx=0,dy=1,表示计算Y方向的导数,检测出的是水平方向上的边缘。
32、int ksize:为进行边缘检测时的模板大小为ksize*ksize,取值为1、3、5和7,其中默认值为3。特殊情况:ksize=1时,采用的模板为3*1或1*3。
33、当ksize=3时索贝尔内核可能产生比较明显的误差;
34、双刻度:默认1。
35、双德尔塔:默认0。
36、int borderType:默认值为边框_默认。
37、索贝尔调用格式:
38、sobel算法代码实现过程为:
39、//求X方向梯度
40、Sobel( src_gray,grad_x,ddepth,1,0,3,scale,delta,BORDER _ DEFAULT);
41、//求Y方向梯度
42、Sobel( src_gray,grad_y,ddepth,0,1,3,scale,delta,BORDER _ DEFAULT);
43、convertScaleAbs( grad_x,ABS _ grad _ x);
44、convertScaleAbs( grad_y,ABS _ grad _ y);
45、addWeighted( dst_x,0.5,dst_y,0.5,0,dst);//一种近似的估计
46、索贝尔算子实现:
47、#包含opencv2\opencv.hpp
48、使用命名空间标准
49、使用名称空间cv;
50、int main( int argc,char** argv)
51、{
52、Mat in_img=imread("raw.jpg ",0);
53、如果(!in_img.data)
54、{
55、return-1;
56、}
57、Mat out _ img _ dx=Mat:zeros(in _ img。size()、CV _ 16sc 1);
58、Mat out _ img _ dy=Mat:zeros(in _ img。size()、CV _ 16sc 1);
59、Mat out _ img _ dxy=Mat:zeros(in _ img。size()、CV _ 16sc 1);
60、GaussianBlur(in_img,in_img,Size(3,3),0);
61、无符号char * p _ data=(无符号char *)in _ img。数据;
62、无符号char* p_data_dx=(无符号char *)out _ img _ dx。数据;
63、无符号char * p _ data _ dy=(无符号char *)out _ img _ dy。数据;
64、int step=in _ img.step
65、for(int I=1;iin _ img。第1行;我)
66、{
67、for(int j=1;Jin _ img。cols-1;j)
68、{
69、//通过指针遍历图像上每一个像素
70、p _ data _ dx[I * out _ img _ dx。步骤j *(out _ img _ dx。step/in _ img。step)]=ABS(p _ data[(I-1)* in _ img。step j 1]2 * p _ data[I * in _ img。step j 1]p _ data[(I 1)* in _ img。步骤j 1]
71、-p _ data[(I-1)* in _ img。步骤j-1]-2 * p _ data[I * in _ img。步骤j-1]-p _ data[(I 1)* in _ img。步骤j-1]);
72、p _ data _ dy[I * out _ img _ dy。步骤j *(out _ img _ dy。step/in _ img。step)]=ABS(p _ data[I * in _ img。步骤j-1]2 * p _ data[I * in _ img。步骤j]p _ data[I * in _ img。步骤j 1]
73、-p _ data[(I 1)* in _ img。步骤j-1]-2 * p _ data[(I 1)* in _ img。step j]-p _ data[(I 1)* in _ img。步骤j 1]);
74、}
75、}
76、addWeighted(out_img_dx,0.5,out_img_dy,0.5,0,out _ img _ dxy);
77、Mat img_dx,img_dy,img _ dxy
78、convertScaleAbs(out_img_dx,img _ dx);
79、convertScaleAbs(out_img_dy,img _ dy);
80、convertScaleAbs(out_img_dxy,img _ dxy);
81、imshow("raw img ",in _ img);
82、imshow("x方向,img _ dx);
83、imshow("y方向,img _ dy);
84、imshow("xy方向,img _ dxy);
85、matsobel _ img;
86、索贝尔(in_img,sobel_img,CV_8UC1,1,1,3);
87、imshow("opencvsobel ",sobel _ img);
88、等待键(0);
89、返回0;
90、}
91、OpenCV内源码:
92、静态void getSobelKernels(output array _ kx,OutputArray _ky,int dx,int dy,int _ksize,bool normalize,int ktype)
93、{
94、int i,j,ksizeX=_ksize,ksizeY=_ ksize
95、if( ksizeX==1 dx 0)
96、ksizeX=3;
97、if( ksizeY==1 dy 0)
98、ksizeY=3;
99、CV _ Assert(ktype==CV _ 32F | | ktype==CV _ 64F);
100、_kx.create(ksizeX,1,ktype,-1,true);
101、_ky.create(ksizeY,1,ktype,-1,true);
102、mat kx=_ kx。getmat();
103、mat ky=_ ky。getmat();
104、if( _ksize % 2==0 || _ksize 31)
105、CV_Error( CV_StsOutOfRange,"内核大小必须是奇数且不大于31 ");
106、STD:vector int kerI(STD:max(ksizeX,ksizeY)1);
107、CV _ Assert(dx=0 dy=0 dx dy 0);
108、for(int k=0;k2;k)
109、{
110、Mat* kernel=k==0?kx:ky;
111、int order=k==0?dx:dy;
112、int ksize=k==0?ksizeX:ksizeY;
113、CV _ Assert(ksize order);
114、如果(ksize==1)
115、kerI[0]=1;
116、else if( ksize==3)
117、{
118、if( order==0)
119、kerI[0]=1,kerI[1]=2,kerI[2]=1;
120、else if( order==1)
121、kerI[0]=-1,kerI[1]=0,kerI[2]=1;
122、其他
123、kerI[0]=1,kerI[1]=-2,kerI[2]=1;
124、}
125、其他
126、{
127、int oldval,newval
128、kerI[0]=1;
129、for(I=0;我ksize我)
130、kerI[I 1]=0;
131、for(I=0;I ksize-order-1;我)
132、{
133、旧val=kerI[0];
134、for(j=1;j=ksizej)
135、{
136、new val=kerI[j]kerI[j-1];
137、kerI[j-1]=老瓦尔;
138、旧瓦尔=新瓦尔
139、}
140、}
141、for(I=0;我点菜;我)
142、{
143、旧val=-kerI[0];
144、for(j=1;j=ksizej)
145、{
146、new val=kerI[j-1]-kerI[j];
147、kerI[j-1]=老瓦尔;
148、旧瓦尔=新瓦尔
149、}
150、}
151、}
152、Mat temp(kernel-rows,kernel-cols,CV_32S,kerI[0]);
153、双倍尺度=!正常化?1. 1./(1(ksize-order-1));
154、temp.convertTo(*kernel,ktype,scale);
155、}
156、}
本文到此结束,希望对大家有所帮助。
Copyright © 2015-2023 港澳频道网版权所有 备案号:京ICP备2023022245号-31 联系邮箱:435 226 40 @qq.com