MATLAB实验报告.docx
《MATLAB实验报告.docx》由会员分享,可在线阅读,更多相关《MATLAB实验报告.docx(9页珍藏版)》请在冰豆网上搜索。
MATLAB实验报告
基于canny算子的边缘检测
报告题目:
基于canny算子的边缘检测
学院:
专业:
年级:
学号:
学生:
指导教师:
日期:
摘要
图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个阶跃,既从一个灰度值在很小的缓冲区域内急剧变化到另一个灰度相差较大的灰度值。
图象的边缘部分集中了图象的大部分信息,图象边缘确实定与提取对于整个图象场景的识别与理解是非常重要的,同时也是图象分割所依赖的重要特征,边缘检测主要是图象的灰度变化的度量、检测和定位,自从1959提出边缘检测以来,经过五十多年的发展,已有许多中不同的边缘检测方法。
本文主要讨论通过canny算子,来获取图像的边缘区域的方法。
1Canny边缘检测基本原理
具有既能滤去噪声又保持边缘特性的边缘检测最优滤波器,其采用一阶微分滤波器。
采用二维高斯函数的任意方向上的一阶方向导数为噪声滤波器,通过与图像卷积进行滤波;然后对滤波后的图像寻找图像梯度的局部最大值,以此来确定图像边缘。
根据对信噪比与定位乘积进行测度,得到最优化逼近算子,这就是Canny边缘检测算子。
类似与Marr(LOG)边缘检测方法,也属于先平滑后求导数的方法。
2Canny边缘检测算法〔数学描述〕
step1:
用高斯滤波器平滑图象。
二维为高斯函数为:
在某一方向n上是G(x,y)的一阶方向导数为:
式中:
n式方向矢量,是梯度矢量。
将图像f(x,y)与Gn作卷积,同时改变n的方向,Gn*f(x,y)取得最大值时的n就是正交于检测边缘的方向。
step2:
用一阶偏导的有限差分来计算梯度的幅值和方向。
A(x,y)反映了图像(x,y)点处的边缘强
度,θ是图像(x,y)点处的法向矢量。
step3:
对梯度幅值进行非极大值抑制。
仅仅得到全局的梯度并不足以确定边缘,因此为确定边缘,必须保留局部梯度最大的点,而抑制非极大值,如图1。
解决方法:
利用梯度的方向。
四个扇区的标号为0到3,对应3*3邻域的四种可能组合。
在每一点上,邻域的中心像素M与沿着梯度线的两个像素相比。
如果M的梯度值不比沿梯度线的两个相邻像素梯度值大,则令M=0,即G(x,y)=NMS(M[x,y],§[x,y])。
step4:
用双阈值算法检测和连接边缘。
减少假边缘段数量的典型方法是对G(x,y)使用一个阈值,并将低于阈值的所有值赋零值。
通常选取阈值的方法:
双阈值算法进行边缘判别和连接边缘。
①首先是边缘判别:
但凡边缘强度大于高阈值的一定是边缘点;但凡边缘强度小于低阈值的一定不是边缘点;如果边缘强度大于低阈值又小于高阈值,则看这个像素的邻接像素中有没有超过高阈值的边缘点,如果有,它就是边缘点,如果没有,它就不是边缘点。
②其次是连接边缘:
双阈值算法对非极大值抑制图像作用两个阈值τ1和τ2,且2τ1≈τ2,从而可以得到两个阈值边缘图像G1(x,y)和G2(x,y)。
由于G2(x,y)使用高阈值得到,因而含有很少的假边缘,但有间断(不闭合)。
双阈值法要在G2(x,y)中把边缘连接成轮廓,当到达轮廓的端点时,该算法就在G1(x,y)的8邻点位置寻找可以连接到轮廓上的边缘,这样,算法不断地在G1(x,y)中收集边缘,直到将G1(x,y)连接起来为止。
检测阶跃边缘的基本思想是在图像中找出具有局部最大梯度幅值的像素点。
虽然Canny边缘检测算法也有本身的针对性和局限性,但canny算子边缘检测算法则既能滤去噪声又保持边缘特性的边缘检测的一阶微分算法中的最正确选择方法。
3算法过程
4实现过程
1〕读入图像:
clear;
clc;
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
2〕用3x3高斯滤波器进行滤波,消除噪声;
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;%横向高斯滤波
end
end
利用上面自定义的gaosi函数对图像进行二维3x3滤波,
k1=gaosi(k);%横向滤波
k1=k1';%对图像进行转置,为下一步纵向滤波作准备〔纵向滤波==转置后横向滤波〕
k1=gaosi(k1);
k1=k1';%复原
3〕针对每一个像素,计算横向与纵向两方向的微分近似,以得到像素的梯度大小和方向;
利用上式,易知p,q分别为计算出的横向、纵向的微分近似,由此再计算出梯度的大小和方向。
%计算梯度的大小和方向
[h,w]=size(k);
form=2:
h-1
forn=2:
w-1
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
end
end
4〕对梯度进行"非极大抑制"〔非局部最大值置0〕;
1.先将梯度方向归类为四个主要方向,左右、上下、左斜、右斜。
%非极大值抑制
%首先将梯度方向划分为4个方向0,45,90,135〔以及他们的反向延长线〕
form=2:
h-1
forn=2:
w-1
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;
elseifkjiao(m,n)>=-3/8*pi
kjiao(m,n)=3;
else
kjiao(m,n)=2;
end
end
end
end
end
end
根据划分后的4个方向,判断该点是否是8邻域的局部最大值〔梯度方向〕,比方,梯度方向为左右方向的点,判断其是否比左右两点的值来的大,如果不是,使该点的值为0.
%按照各个方向分别判断
k2=k1;
form=2:
h-1
forn=2:
w-1
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
ifk1(m,n)>k1(m+1,n-1)&&k1(m,n)>k1(m-1,n+1);
elsek2(m,n)=0;
end
end
ifkjiao(m,n)==2
ifk1(m,n)>k1(m-1,n)&&k1(m,n)>k1(m+1,n);
elsek2(m,n)=0;
end
end
ifkjiao(m,n)==3
ifk1(m,n)>k1(m-1,n-1)&&k1(m,n)>k1(m+1,n+1);
elsek2(m,n)=0;
end
end
end
end
5〕对梯度取两次阈值;
用两个阈值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;
form=2:
h-1
forn=2:
w-1
ifkfu(m,n)k3(m,n)=0;
end
ifkfu(m,n)k4(m,n)=0;
end
end
end
5〕对边缘进行连接;
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:
3
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
end
end
m=m1;n=n1;
end
ff=k4;
主函数里写上:
figure;
subplot(221);imshow(i);title('原图像');
subplot(222);imshow(k3,[]);title('阈值为50的分割图像');
subplot(223);imshow(k4,[]);title('阈值为100的分割图像');
flag=zeros(h,w);%标记该点是否以检测过,1表示检测过
form=2:
h-1
forn=2:
w-1
ifk4(m,n)~=0&&flag(m,n)==0
[k4,flag]=findline(k3,k4,flag,m,n);
end
end
end
subplot(224);imshow(k4,[]);title('修正后的分割图像');
5结果显示
6总结和体会
通过完成这次数字图像的大作业,对canny算子的原理及算法有了更加清晰的认识。
并通过实际的运行程序,对课上所学到的知识有了更加深刻和直观的了解。
这学期学习了数字图像处理这门课程,对各种图像处理方法有了一些基本的了解,并学习了matlab图像处理的一些基本应用方法。
在使用matlab后,给我的感觉就是这个软件的功能十分强大。
我们现在学习的只能算简单的基础应用,但依然会遇到一些错误,这时我们应该灵活运用软件自带的help功能,通常问题都能够得到有效地解决。
图像是人类获取和交换信息的主要来源,因此,图像处理的应用领域涉及到人类的生活和工作等的方方面面。
进一步的在图像处理方面进行学习研究,可以在各个领域内得到很好地运用,能够更好的为社会做奉献。
7参考文献
[1]贾永红编《数字图像处理〔第二版〕》武汉大学出版社
[2]王忠礼段慧达高玉峰《MATLAB应用技术》清华大学出版社
[4]《matlab程序设计与实例应用》高等教育出版社
[5]维基百科