图像边缘检测算法 代码程序
②Prewitt 算子 为了在边缘检测中减少噪声的影响, 1970 年 Prewitt 和 Sobel 分别提出 Prewitt 算子和 Sobel 算子。Prewitt 算子加大了边缘检测算子的模板,扩大到 3x3 来计算差分算子。Prewitt 边 缘检测算子使用两个有向算子(一个水平的,一个是垂直的,一般称为模板),每一个逼近一 个偏导数:
(1)用卷积函数 conv2 处理的 Matlab 程序代码: a=imread('lena','tif'); b=[0 1;-1 0]/126;c=[1 0;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 水平')
阶跃状边缘的位置在一阶导数的峰值点,在二阶导数的过零点;屋顶状边缘(有一定的宽度 范围)的位置在一阶导数的两峰值之间,在二阶导数的两个过零点之间。 三、基于一阶导数法的边缘检测 3.1 梯度算子 求梯度的运算可近似为微分模板与图像的卷积。常用一阶边缘检测算子有简单梯度算子、 Roberts 算子、priwitt 算子、sobel 算子。梯度算子包含着微分运算,对噪声比较敏感。 以上各算子都只包含 x,y 两个方向的模板,每种模板只对相应的方向敏感,而对其他方向 的变化响应不大。 ①Roberts 算子 Roberts 算子是一种利用局部差分算子寻找边缘的算子 ,它由下式给出:
实验结果: Canny 算子由于进行了高斯滤波,因此可以滤除噪声。而且 Canny 算子是双阈值检测,所以 图像连续性较好。 高斯滤波器标准差σ 的大小决定了滤除噪声的能力; 阈值的大小决定了像 素点赋值为‘1’的点的多少。 3.3 方向算子 Roberts 算子、priwitt 算子、sobel 算子都只包含两个方向的模板,每种模板只对相应的 方向敏感,对该方向上的变化有明显的输出,而对其他方向的变化响应不大。为了检测各个 方向的边缘,需要有各个方向的微分模板。8 个方向的 kirsch 模板较为常用,这 8 个方向 依次成 45°夹角,其 3*3 的模板为[-5 3 3;-5 0 3;-5 3 3], [3 3 3;-5 0 3;-5 -5 3], [3 3 3;3 0 3;-5 -5 -5], [3 3 3;3 0 -5; 3 -5 -5], [3 3 -5;3 0 -5;3 3 -5], [3 -5 -5;3 0 -5;3 3 3], [-5 -5 -5;3 0 3;3 3 3], [-5 -5 3;-5 0 3;3 3 3] 用卷积函数 conv2 处理的 Matlab 程序代码: a=imread('lena','tif'); b=[-5 3 3;-5 0 3;-5 3 3]/1512;c=[3 3 3;-5 0 3;-5 -5 3]/1512; d=[3 3 3;3 0 3;-5 -5 -5]/1512;e=[3 3 3;3 0 -5; 3 -5 -5]/1512; f=[3 3 -5;3 0 -5;3 3 -5]/1512;g=[3 -5 -5;3 0 -5;3 3 3]/1512; h=[-5 -5 -5;3 0 3;3 3 3]/1512;i=[-5 -5 3;-5 0 3;3 3 3]/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)
图像边缘检测算法研究
一、边缘检测:边缘是指图像局部亮度变化最显著的部分,边缘主要存在于目标与目标、目 标与背景、区域与区域(包括不同色彩)之间,是图像分割、纹理特征提取和形状特征提取 等图像分析的重要基础。边缘的检测正是利用物体和背景在某种图像特性上的差异来实现 的。这些差异包括灰度、颜色或纹理特征。边缘检测实际上就是检测图像特性发生变化的位 置。 二、图像的边缘大致可分为两种:阶跃状和屋顶状;阶跃状的边缘处于图像中两个不同灰度 的相邻区域之间,屋顶状的边缘上升和下降都比较缓慢。
1 1 1 PV 0 0 0 1 1 1
1 0 1 PH 1 0 1 1 0 1
如果我们用 Prewitt 算子检测图像 M 的边缘的话,我们可以先分别用水平算子和垂直算子 对图像进行卷积, 得到的是两个矩阵, 在不考虑边界的情形下也是和原图像同样大小的 M1, M2,他们分别表示图像 M 中相同位置处的两个偏导数。然后把 M1,M2 对应位置的两个数平 方后相加得到一个新的矩阵 G,G 表示 M 中各个像素的灰度的梯度值(一个逼近)。 然后就可以 通过阀值处理得到边缘图像。 (1)用卷积函数 conv2 处理的 Matlab 程序代码: a=imread('lena','tif'); b=[-1 -1 -1;0 0 0;1 1 1]/256;c=[-1 0 1; -1 0 1; -1 0 1]/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',0.005); b = edge(a,'prewitt',0.02); c = edge(a,'prewitt',0.07); [d,e] = edge(a,'prewitt'); %该处可得阈值的默认值 e subplot(2,2,1),imshow(a),axis on; title('原图') subplot(2,2,2),imshow(b) ,axis on; title('prewitt 阈值=0.02') subplot(2,2,3),imshow(c) ,axis on;title('prewitt 阈值=0.07') subplot(2,2,4),imshow(d) ,axis on; title('默认')
R (i, j ) ( f (i, j ) f (i 1, j 1)) 2 ( f (i, j 1) f (i 1, j )) 2
它是由两个 2 ×2 模板作用的结果(标注•的是当前像素的位置):
Hale Waihona Puke 1· 0 0 1 0· 1 1 0
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',0.005); %对图像加椒盐噪声 b = edge(a,'roberts',0.02); %以阈值为 0.02 进行 roberts 边缘检测 c = edge(a,'roberts',0.07); %阈值为 0.07 [d,e] = edge(a,'roberts'); %该处可得阈值的默认值 e subplot(2,2,1),imshow(a),axis on; title('原图') subplot(2,2,2),imshow(b) ,axis on; title('roberts 阈值=0.02') subplot(2,2,3),imshow(c) ,axis on;title('roberts 阈值=0.07') subplot(2,2,4),imshow(d) ,axis on; title('默认') 运行结果: