canny 算子实现图像边缘检测(详细过程附源码Word文档下载推荐.docx

上传人:b****1 文档编号:13031989 上传时间:2022-10-03 格式:DOCX 页数:12 大小:125.09KB
下载 相关 举报
canny 算子实现图像边缘检测(详细过程附源码Word文档下载推荐.docx_第1页
第1页 / 共12页
canny 算子实现图像边缘检测(详细过程附源码Word文档下载推荐.docx_第2页
第2页 / 共12页
canny 算子实现图像边缘检测(详细过程附源码Word文档下载推荐.docx_第3页
第3页 / 共12页
canny 算子实现图像边缘检测(详细过程附源码Word文档下载推荐.docx_第4页
第4页 / 共12页
canny 算子实现图像边缘检测(详细过程附源码Word文档下载推荐.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

canny 算子实现图像边缘检测(详细过程附源码Word文档下载推荐.docx

《canny 算子实现图像边缘检测(详细过程附源码Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《canny 算子实现图像边缘检测(详细过程附源码Word文档下载推荐.docx(12页珍藏版)》请在冰豆网上搜索。

canny 算子实现图像边缘检测(详细过程附源码Word文档下载推荐.docx

i=imread('

light.jpg'

);

k=rgb2y(i);

%获取h分量,即亮度分量

根据边缘的定义,边缘检测的目的是标识数字图像中亮度变化明显的点。

(参考维基百科);

又根据公式Brightness=0.3*R+0.6*G+0.1*B;

计算出亮度分量y;

functionk=rgb2y(z)

%i必须为rgb三维矩阵

[m,n,p]=size(z);

k=zeros(m,n);

z=double(z);

fori=1:

m

forj=1:

n

k(i,j)=0.3*z(i,j,1)+0.6*z(i,j,2)+0.1*z(i,j,3);

end

end

functionj=gaosi(i);

%i必须为二维double矩阵

j=i;

[h,w]=size(i);

form=2;

h-1

forn=2:

w-1

j(m,n)=(i(m,n-1)+2*i(m,n)+i(m,n+1))/4;

%横向高斯滤波

利用上面自定义的gaosi函数对图像进行二维3x3滤波,

k1=gaosi(k);

%横向滤波

k1=k1'

;

%对图像进行转置,为下一步纵向滤波作准备(纵向滤波==转置后横向滤波)

k1=gaosi(k1);

%还原

利用上式,易知p,q分别为计算出的横向、纵向的微分近似,由此再计算出梯度的大小和方向。

%计算梯度的大小和方向

[h,w]=size(k);

form=2:

zz1=k1(m,n-1)+k1(m+1,n-1);

zz2=k1(m,n)+k1(m+1,n);

zz3=k1(m,n-1)+k1(m,n);

zz4=k1(m+1,n-1)+k1(m+1,n);

kp(m,n)=0.5*(zz2-zz1);

kq(m,n)=0.5*(zz3-zz4);

kfu(m,n)=sqrt((kp(m,n)^2)+(kq(m,n)^2));

%梯度大小

kjiao(m,n)=atan(kq(m,n)/(kp(m,n)+0.001));

%梯度方向,0.001防止分母为0

1.先将梯度方向归类为四个主要方向,左右、上下、左斜、右斜。

%非极大值抑制

%首先将梯度方向划分为4个方向0,45,90,135(以及他们的反向延长线)

ifkjiao(m,n)>

=3/8*pi

kjiao(m,n)=2;

elseifkjiao(m,n)>

=1/8*pi

kjiao(m,n)=1;

elseifkjiao(m,n)>

=-1/8*pi

kjiao(m,n)=0;

=-3/8*pi

kjiao(m,n)=3;

else

kjiao(m,n)=2;

end

end

根据划分后的4个方向,判断该点是否是8邻域的局部最大值(梯度方向),比如,梯度方向为左右方向的点,判断其是否比左右两点的值来的大,如果不是,使该点的值为0.

%按照各个方向分别判断

k2=k1;

ifkjiao(m,n)==0

ifk1(m,n)>

k1(m,n-1)&

&

k1(m,n)>

k1(m,n+1);

elsek2(m,n)=0;

end

end

ifkjiao(m,n)==1

k1(m+1,n-1)&

k1(m-1,n+1);

ifkjiao(m,n)==2

k1(m-1,n)&

k1(m+1,n);

ifkjiao(m,n)==3

k1(m-1,n-1)&

k1(m+1,n+1);

用两个阈值t1和t2(t2>

t1,一般取t2=2*t1),我们把梯度值小于t1的像素的灰度设为0,得到图像1,然后我们把梯度值小于t2的像素的灰度设为0,得到图像2。

由于图像2的阈值较高,噪音较少(但同时也损失了有用的边缘信息,而图像1的阈值较低,保留了较多信息,因此我们可以以图像2为基础,以图像1为补充来连接图像的边缘。

%两次阈值分割

k3=k2;

%以t1为阈值分割后的矩阵

k4=k2;

%以t2为阈值分割后的矩阵

t1=50;

t2=2*t1;

ifkfu(m,n)<

t1

k3(m,n)=0;

t2

k4(m,n)=0;

a.扫描图像2,当我们遇到一个非零值的像素p时(跟踪以p为开始点的轮廓线直到该轮廓线的终点q;

b.在图像1中,考察与图像2中p点位置对应的点p'

的8邻域,如果在p'

点的8邻域中有非零像素q'

存在,将其包括到图像2中,作为点r,从r开始(重复第a步,直到我们在图像1和图像2中都无法继续为止;

c.我们已经结束了对包含p的轮廓线的连接,将这条轮廓标记为已访问过,回到第a步,寻找下一条轮廓线,重复第(a)(b)(c)步直到图像2中再也找不到新轮廓线为止.

findline.m:

function[ff,flag1]=findline(k3,k4,flag,m,n)

flag1=flag;

m1=m+1;

n1=n+1;

while(m~=m1||n~=n1)%若m和n都不发生变化,表明line已到终点

flagg=0;

fori=1:

3

if(flagg==1)break;

end

forj=1:

ifk3(m-2+i,n-2+j)~=0

k4(m-2+i,n-2+j)=255;

m1=m-2+i;

n1=n-2+j;

%新的[m,n]点

flag1(m,n)=1;

%标记已检测过

flagg=1;

break;

end

m=m1;

n=n1;

ff=k4;

主函数里写上:

figure;

subplot(221);

imshow(i);

title('

原图像'

subplot(222);

imshow(k3,[]);

阈值为50的分割图像'

subplot(223);

imshow(k4,[]);

阈值为100的分割图像'

flag=zeros(h,w);

%标记该点是否以检测过,1表示检测过

ifk4(m,n)~=0&

flag(m,n)==0

[k4,flag]=findline(k3,k4,flag,m,n);

end

subplot(224);

修正后的分割图像'

至此,程序完成。

效果如下:

至于程序中阈值的求取,大家自己定义就好了。

希望前辈们能给点学习图像处理的经验,谢谢了。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 初中作文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1