图像边缘检测算法代码程序及其结果.docx
《图像边缘检测算法代码程序及其结果.docx》由会员分享,可在线阅读,更多相关《图像边缘检测算法代码程序及其结果.docx(11页珍藏版)》请在冰豆网上搜索。
图像边缘检测算法代码程序及其结果
图像边缘检测算法研究
一、边缘检测:
边缘是指图像局部亮度变化最显著的部分,边缘主要存在于目标与目标、目标与背景、区域与区域(包括不同色彩)之间,是图像分割、纹理特征提取和形状特征提取等图像分析的重要基础。
边缘的检测正是利用物体和背景在某种图像特性上的差异来实现的。
这些差异包括灰度、颜色或纹理特征。
边缘检测实际上就是检测图像特性发生变化的位置。
二、图像的边缘大致可分为两种:
阶跃状和屋顶状;阶跃状的边缘处于图像中两个不同灰度的相邻区域之间,屋顶状的边缘上升和下降都比较缓慢。
阶跃状边缘的位置在一阶导数的峰值点,在二阶导数的过零点;屋顶状边缘(有一定的宽度范围)的位置在一阶导数的两峰值之间,在二阶导数的两个过零点之间。
三、基于一阶导数法的边缘检测
梯度算子
求梯度的运算可近似为微分模板与图像的卷积。
常用一阶边缘检测算子有简单梯度算子、Roberts算子、priwitt算子、sobel算子。
梯度算子包含着微分运算,对噪声比较敏感。
以上各算子都只包含x,y两个方向的模板,每种模板只对相应的方向敏感,而对其他方向的变化响应不大。
①Roberts算子
Roberts算子是一种利用局部差分算子寻找边缘的算子,它由下式给出:
它是由两个2×2模板作用的结果(标注•的是当前像素的位置):
(1)用卷积函数conv2处理的Matlab程序代码:
a=imread('lena','tif');
b=[01;-10]/126;c=[10;0-1]/126;%参数126是实验时为增强图像对比度试验出来的
d=conv2(a,b,'same');d=abs(d);%处理水平方向算子的结果,参数'same'使得得到的图像与原图大小相等。
e=conv2(a,c,'same');e=abs(e);%处理垂直方向算子的结果
f=max(d,e);%取水平及垂直方向上的大值
subplot(1,3,1),imshow(d),title('roberts水平')
subplot(1,3,2),imshow(e),title('roberts垂直')
subplot(1,3,3),imshow(f),title('roberts综合')
由图可知,用单个方向的算子则对该方向比较敏感。
(2)用edge函数处理的Matlab程序代码:
a=imread('tuxing','tif');%读取图像
a=imnoise(a,'salt&pepper',;%对图像加椒盐噪声
b=edge(a,'roberts',;%以阈值为进行roberts边缘检测
c=edge(a,'roberts',;%阈值为
[d,e]=edge(a,'roberts');%该处可得阈值的默认值e
subplot(2,2,1),imshow(a),axison;title('原图')
subplot(2,2,2),imshow(b),axison;title('roberts阈值=')
subplot(2,2,3),imshow(c),axison;title('roberts阈值=')
subplot(2,2,4),imshow(d),axison;title('默认')
运行结果:
②Prewitt算子
为了在边缘检测中减少噪声的影响,1970年Prewitt和Sobel分别提出Prewitt算子和Sobel算子。
Prewitt算子加大了边缘检测算子的模板,扩大到3x3来计算差分算子。
Prewitt边缘检测算子使用两个有向算子(一个水平的,一个是垂直的,一般称为模板),每一个逼近一个偏导数:
如果我们用Prewitt算子检测图像M的边缘的话,我们可以先分别用水平算子和垂直算子对图像进行卷积,得到的是两个矩阵,在不考虑边界的情形下也是和原图像同样大小的M1,M2,他们分别表示图像M中相同位置处的两个偏导数。
然后把M1,M2对应位置的两个数平方后相加得到一个新的矩阵G,G表示M中各个像素的灰度的梯度值(一个逼近)。
然后就可以通过阀值处理得到边缘图像。
(1)用卷积函数conv2处理的Matlab程序代码:
a=imread('lena','tif');
b=[-1-1-1;000;111]/256;c=[-101;-101;-101]/256;%参数256是实验时为增强图像对比度试验出来的
d=conv2(a,b,'same');d=abs(d);%处理水平方向算子的结果
e=conv2(a,c,'same');e=abs(e);%处理垂直方向算子的结果
f=max(d,e);%取水平及垂直方向上的大值
subplot(1,3,1),imshow(d),title('prewitt水平')
subplot(1,3,2),imshow(e),title('prewitt垂直')
subplot(1,3,3),imshow(f),title('prewitt综合')
由图可知,用单个方向的算子则对该方向比较敏感。
(2)用edge函数处理的Matlab程序代码:
a=imread('tuxing','tif');%读取图像
a=imnoise(a,'salt&pepper',;
b=edge(a,'prewitt',;
c=edge(a,'prewitt',;
[d,e]=edge(a,'prewitt');%该处可得阈值的默认值e
subplot(2,2,1),imshow(a),axison;title('原图')
subplot(2,2,2),imshow(b),axison;title('prewitt阈值=')
subplot(2,2,3),imshow(c),axison;title('prewitt阈值=')
subplot(2,2,4),imshow(d),axison;title('默认')
③sobel算子
Sobel算子和Prewitt算子的不同就在于使用的模板不一样:
(1)用卷积函数conv2处理的Matlab程序代码:
a=imread('lena','tif');
b=[-1-2-1;000;121]/256;c=[-101;-202;-101]/256;%参数256是实验时为增强图像对比度试验出来的
d=conv2(a,b,'same');d=abs(d);%处理水平方向算子的结果
e=conv2(a,c,'same');e=abs(e);%处理垂直方向算子的结果
f=max(d,e);%取水平及垂直方向上的大值
subplot(1,3,1),imshow(d),title('sobel水平')
subplot(1,3,2),imshow(e),title('sobel垂直')
subplot(1,3,3),imshow(f),title('sobel综合')
由图可知,用单个方向的算子则对该方向比较敏感。
用sobel算子得到的图像边缘较宽。
(2)用edge函数处理的Matlab程序代码:
a=imread('tuxing','tif');%读取图像
a=imnoise(a,'salt&pepper',;
b=edge(a,'sobel',;
c=edge(a,'sobel',;
[d,e]=edge(a,'sobel');%该处可得阈值的默认值e
subplot(2,2,1),imshow(a),axison;title('原图')
subplot(2,2,2),imshow(b),axison;title('sobel阈值=')
subplot(2,2,3),imshow(c),axison;title('sobel阈值=')
subplot(2,2,4),imshow(d),axison;title('默认阈值')
实验结果:
由Roberts算子、priwitt算子、sobel算子处理的图像结果可以看出,三者处理效果差不多。
由于梯度算子包含着微分运算,因此对图像的噪声有一定的放大作用。
阈值的大小决定了像素点赋值为‘1’的点的多少。
阈值越大,留下的‘1’点越少。
canny算子
Canny算子具体实现的步骤是:
①、用高斯滤波器平滑图像;②、用一阶偏导的有限差分来计算梯度的幅值和方向;③、对梯度幅值进行非极大值抑制;④、用双阈值算法检测和连接边缘。
(双阈值检测原理:
两个阈值可得两个边缘图像,首先由大阈值把边缘连接成轮廓,当到达轮廓的端点时,就从小阈值图像中寻找可以连接到轮廓上的边缘。
)
Matlab程序代码:
a=imread('tuxing','tif');%读取图像
a=imnoise(a,'salt&pepper',;
b=edge(a,'canny',[,]);%edge(I,'canny',thresh,sigma),sigmaσ默认为1
c=edge(a,'canny',[,]);%σ=3
d=edge(a,'canny',[,],2);
subplot(2,2,1),imshow(a);
subplot(2,2,2),imshow(b);title('canny双阈值=[,]σ=1')
subplot(2,2,3),imshow(c);title('canny双阈值=[,]σ=1')
subplot(2,2,4),imshow(d);title('canny双阈值=[,]σ=2')
实验结果:
Canny算子由于进行了高斯滤波,因此可以滤除噪声。
而且Canny算子是双阈值检测,所以图像连续性较好。
高斯滤波器标准差σ的大小决定了滤除噪声的能力;阈值的大小决定了像素点赋值为‘1’的点的多少。
方向算子
Roberts算子、priwitt算子、sobel算子都只包含两个方向的模板,每种模板只对相应的方向敏感,对该方向上的变化有明显的输出,而对其他方向的变化响应不大。
为了检测各个方向的边缘,需要有各个方向的微分模板。
8个方向的kirsch模板较为常用,这8个方向依次成45°夹角,其3*3的模板为[-533;-503;-533],[333;-503;-5-53],[333;303;-5-5-5],[333;30-5;3-5-5],[33-5;30-5;33-5],[3-5-5;30-5;333],[-5-5-5;303;333],[-5-53;-503;333]
用卷积函数conv2处理的Matlab程序代码:
a=imread('lena','tif');
b=[-533;-503;-533]/1512;c=[333;-503;-5-53]/1512;
d=[333;303;-5-5-5]/1512;e=[333;30-5;3-5-5]/1512;
f=[33-5;30-5;33-5]/1512;g=[3-5-5;30-5;333]/1512;
h=[-5-5-5;303;333]/1512;i=[-5-53;-503;333]/1512;
b=conv2(a,b,'same');b=abs(b);c=conv2(a,c,'same');c=abs(c);
d=conv2(a,d,'same');d=abs(d);e=conv2(a,e,'same');e=abs(e);
f=conv2(a,f,'same');f=abs(f);g=conv2(a,g,'same');g=abs(g);
h=conv2(a,h,'same');h=abs(h);i=conv2(a,i,'same');i=abs(i);
p=max(b,c);p=max(d,p);p=max(e,p);p=max(f,p);p=max(g,p);p=max(h,p);p=max(i,p);
subplot(2,4,1),imshow(b),subplot(2,4,2),imshow(c),subplot(2,4,3),imshow(d),
subplot(2,4,4),imshow(e),subplot(2,4,5),imshow(f),subplot(2,4,6),imshow(g),
subplot(2,4,7),imshow(h),subplot(2,4,8),imshow(i)
figure,imshow(p)
由图可知,多个方向的算子得到的图像细节比较多。
四、基于二阶导数法的边缘检测:
拉氏算子,log算子
1.拉氏算子:
其模板为[010;1-41;010];对图像的噪声相当敏感,检测出的边缘常常是双像素宽、没有方向信息;因此很少直接用于图像检测;另一方面,一阶差分算子会在较宽范围形成较大的梯度值,因此不能精确定位,而利用二阶差分算子的过零点可以精确定位边缘。
用卷积函数conv2处理的Matlab程序代码:
a=imread('lena','tif');
b=[010;1-41;010]/56;
d=conv2(a,b,'same');d=abs(d);
imshow(d)
由图可知拉氏算子检测出的边缘常常是双像素宽,没有方向信息。
算子:
拉氏算子对噪声敏感,为减轻噪声的影响,可对需检测的图像先进行平滑,然后再运用拉氏算子检测边缘。
平滑时按照与给定像素点的远近给邻域中的点分配不同的权重,此权重大小应服从正态分布。
高斯函数是一种服从正态分布的平滑函数。
利用log算子进行边缘检测,即首先使图像与高斯函数卷积,然后再运用拉氏算子。
σ的选取:
过大,噪声滤除效果好,但是模糊严重、边缘检测不准确。
LOG算子先用高斯低通滤波器将图像进行预先平滑,然后用拉普拉斯算子找出图像中的陡峭边缘,然后用零灰度值进行二值化产生闭合的、连通的轮廓,消除了所有内部点。
Matlab程序代码:
a=imread('tuxing','tif');%读取图像
a=imnoise(a,'salt&pepper',;
b=edge(a,'log',,;%根据所指定的敏感度阈值thresh和标准偏差sigma(σ),用LOG算子进行边缘检测,默认时σ=2
c=edge(a,'log',,;%σ=3
d=edge(a,'log',,3);
subplot(2,2,1),imshow(a);
subplot(2,2,2),imshow(b);title('LOG阈值=σ=')
subplot(2,2,3),imshow(c);title('LOG阈值=σ=')
subplot(2,2,4),imshow(d);title('LOG阈值=σ=3')
实验结果:
由于log算子是一种二阶导数算子,因此对图像中的噪声相当敏感,如上图中的(2,2,2),增大log算子中的高斯-拉普拉斯滤波器的标准差σ可以有效的滤除噪声,如上图中的(2,2,4),但有些边缘也同样会被滤除掉,因此要适当的选择σ值。
同样阈值的大小决定了像素点赋值为‘1’的点的多少。