图像的边缘检测和分割
一、实验目的
1.学会使用编程实现不同算法的边缘检测。
2.学会使用编程实现不同算法的图像分割。
3.能够根据实验结果分析各种算法的特点及其应用场合,培养处理实际图像的能力。
二、实验要求
1.实验课前需要写预习实验报告,内容为本次实验要求中的所有程序清单。
2.实验课对预习报告中的编程代码进行上机调试,完成实验指导书中全部实验要求内容。
3.实验课后写出实验报告。报告要求有实验目的,实验内容与步骤,调试完成的准确编程代码,实验小结,回答问题。
三、实验内容(每一个内容编写一个*.m文件)
1.边缘检测:
(1)利用边缘检测函数edge ()对灰度图像(house.tif)进行边缘检测,检测算子分别选择'roberts'、'sobel'、'prewitt'、LOG、'Canny'(其他参数选择:default),比较不同检测算子对边缘检测的效果;
实验代码:
I=imread('E:\实验五\house.tif');
I1=edge(I,'sobel');
I2=edge(I,'roberts');
I3=edge(I,'prewitt');
I4=edge(I,'log');
I5=edge(I,'canny');
figure;
subplot(2,3,1),imshow(I),title('原图');
subplot(2,3,2),imshow(I1),title('sobel算子边缘检测图');
subplot(2,3,3),imshow(I2),title('roberts算子边缘检测图');
subplot(2,3,4),imshow(I3),title('prewitt算子边缘检测图');
subplot(2,3,5),imshow(I4),title('log算子边缘检测图');
subplot(2,3,6),imshow(I5),title('canny算子边缘检测图')
实验结果:
比较:
Robert算子只能检测出大体的边缘,sobel算子和prewitt算子则能较为完全的检测出边缘,log算子不仅能检测边缘还能显示许多的细节,canny算子检测的边缘细节最接近原图。
(2)利用工具箱函数imfilter()和如图1所示四种不同方向的线检测模板w1/w2/w3/w4对图像(Fig0908(a).tif)进行边缘检测,比较不同方向的检测算子对边缘检测的效果;
-1 |
-2 |
-1 |
|
-1 |
0 |
1 |
|
0 |
1 |
2 |
|
-2 |
-1 |
0 |
0 |
0 |
0 |
|
-2 |
0 |
2 |
|
-1 |
0 |
1 |
|
-1 |
0 |
1 |
1 |
2 |
1 |
|
-1 |
0 |
1 |
|
-2 |
-1 |
0 |
|
0 |
1 |
2 |
图1 w1(水平) w2(垂直) w3 (+45°) w4(-45°)
实验代码:
I=imread('E:\实验五\Fig0908(a).tif');
w1 = [-1 -2 -1;0 0 0;1 2 1];
w2 = [-1 0 1;-2 0 2;-1 0 1];
w3 = [0 1 2;-1 0 1;-2 -1 0];
w4 = [-2 -1 0;-1 0 1;0 1 2];
I1 = imfilter(tofloat(I),w1);
I2 = imfilter(tofloat(I),w2);
I3 = imfilter(tofloat(I),w3);
I4 = imfilter(tofloat(I),w4);
subplot(2,3,1), imshow(I), title('原图');
subplot(2,3,2), imshow(I1), title('w1过滤器过滤后');
subplot(2,3,3), imshow(I2), title('w2过滤器过滤后');
subplot(2,3,4), imshow(I3), title('w3过滤器过滤后');
subplot(2,3,5), imshow(I4), title('w4过滤器过滤后');
实验结果:
比较:
不同方向的检测算子对边缘检测对其方向上的噪声有很好的过滤作用。
2.对灰度图像(rice.tif)编程实现图像锐化增强(算子如图2所示):
(1)利用robert算子检测图像边缘,并采用门限法得到锐化增强图像(T=10,T=50);
实验代码:
I=imread('E:\实验五\rice.tif');
r1=[-1 0;0 1];
r2=[0 -1;1 0];
I1=imfilter(I,r1);
I2=imfilter(I,r2);
I3=(abs(I1)+abs(I2))>10;
I4=(abs(I1)+abs(I2))>50;
subplot(1,2,1),imshow(I3),title('阈值10');
subplot(1,2,2),imshow(I4),title('阈值50');
实验结果:
(2)利用sobel算子检测图像边缘并得到锐化增强图像;
实验代码:
I=imread('E:\实验五\rice.tif');
r1=[ -1 0 1;-2 0 2;-1 0 1];
r2=[ -1 -2 -1;0 0 0;1 2 1];
I1=imfilter(I,r1);
I2=imfilter(I,r2);
I3=abs(I1)+abs(I2);
subplot(1,2,1),imshow(I),title('原图');
subplot(1,2,2),imshow(I3),title('Sobel算子图');
实验结果:
(3)利用Laplacian算子检测图像边缘,分H1和H2两种情况,并得到锐化增强图像;
实验代码:
I=imread('E:\实验五\rice.tif');
r1 = [0 1 0;1 -4 1;0 1 0];
r2 = [1 1 1;1 -8 1;1 1 1];
I1 = imfilter(I,r1);
I2 = imfilter(I,r2);
subplot(1,3,1), imshow(I), title('原图');
subplot(1,3,2), imshow(I1), title('H1锐化增强图像');
subplot(1,3,3), imshow(I2), title('H2锐化增强图像');
实验结果:
(4)比较采用不同边缘检测算子锐化增强图像的不同效果。
Roberts算子图像边缘接近于正45度或负45度时,该算法处理效果更理想。soberts算子的边缘检测结果在水平方向和垂直方向均比Robert算子更加明显,laplacian算法边缘检测对孤立象素的响应要比对边缘或线的响应要更强烈,对不存在噪声的图像更友好。
H1 H2
-1 |
0 |
|
0 |
-1 |
|
-1 |
0 |
1 |
|
-1 |
-2 |
-1 |
|
0 |
1 |
0 |
|
1 |
1 |
1 |
0 |
1 |
|
1 |
0 |
|
-2 |
0 |
2 |
|
0 |
0 |
0 |
|
1 |
-4 |
1 |
|
1 |
-8 |
1 |
|
|
|
|
|
|
-1 |
0 |
1 |
|
1 |
2 |
1 |
|
0 |
1 |
0 |
|
1 |
1 |
1 |
图2 robert算子 sobel算子 Laplacian算子
3. 对灰度图像(Fig1018(a).tif)实现基于阈值处理的图像分割(1为必做内容,2-4为选做内容):
(1)利用函数graythresh ()和otsuthresh()找到全局阈值,对图像进行分割;
实验代码:
I=imread('E:\实验五\rice.tif');
x=graythresh(I);%获取otsu算得的阈值
I1=im2bw(I,x);
[counts,x]=imhist(I);
y=otsuthresh(counts);
I2=im2bw(I,y);
subplot(2,2,1),imshow(I),title('原图');
subplot(2,2,2),imhist(I);
subplot(2,2,3),imshow(I1),title('graythresh分割');
subplot(2,2,4),imshow(I2),title('otsuthresh分割');
实验结果:
(2)采用迭代阈值选取方法,编程实现基于图像数据自动地选择阈值,对图像进行全局阈值分割;
实验代码:
f=imread('E:\实验五\rice.tif');
[m,n]=size(f);
Pn=zeros(m,n);
G1=zeros(m,n);
G2=zeros(m,n);
%%迭代法%%%%%
T=mean(mean(f)); %初始阈值
T1=0;
while(abs(T-T1)>0.3)
R1=find(f>=T);
R2=find(f<T);
T1=T;
T=(mean(mean(f(R1)))+mean(mean(f(R2))))/2;
Pn(R1)=1;
Pn(R2)=0;
end
Pn=uint8(Pn*255);
imhist(f),title('Original hist'),ylabel('pixel num'),axis tight; %原图直方图
hold on;
plot([T, T], [0,5000],'r'); %标注阈值
yu = sprintf('T=%d ', T);
text(T+20,4000,yu);
figure;
subplot(1,2,1); %原始图像
imshow(f),title('原始图像');
subplot(1,2,2); %分割后二值图
imshow(Pn),title('分割图像');
实验截图:
(3)使用Otsu阈值选取方法,编程实现对图像进行最佳全局阈值分割;
实验代码:
a=imread('E:\实验五\rice.tif');
subplot(1,2,1),imshow(a),title('原图');
count=imhist(a) ;
[m,n]=size(a) ;
N=m*n;
L=256;
count=count/N;
for i=1:L
if count (i)~=0
st=i-1;
break;
end
end
for i=L:-1:1
if count (i) ~=0.
nd=i-1;
break;
end
end
f=count(st+1:nd+1);
p=st;
q=nd-st;
u=0;
for i=1:q
u=u+f(i)*(p+i-1);
ua(i)=u;
end;
for i=1:q
w(i)=sum(f(1:i));
end;
d=(u*w-ua).^2./(w.*(1-w));
[y,tp]=max(d);
th=tp+p;
for i=1:m
for j=1:n
if a(i,j)>th
a(i,j)=255;
else
a(i,j)=0;
end
end
end
subplot(1,2,2),imshow(a),title('分割图');
实验截图:
(4)比较迭代法和Otsu法两种不同的阈值处理方法对图像进行分割的效果。
但从上面的图像处理效果来看,这两种方式对rice.tif图像分割处理的效果是一样的,并没有太大的区别。
四、问题与讨论
1.比较不同检测算子对灰度图像('house.tif')边缘检测的效果有什么不同?
答:Roberts算子图像边缘接近于正45度或负45度时,该算法处理效果更理想。soberts算子的边缘检测结果在水平方向和垂直方向均比Robert算子更加明显,laplacian算法边缘检测对孤立象素的响应要比对边缘或线的响应要更强烈,对不存在噪声的图像更友好。
- 比较不同方向的检测算子对边缘检测的效果有什么不同?
答:不同方向的检测算子对边缘检测对其方向上的噪声有很好的过滤作用。
3.迭代法和Otsu法两种不同的阈值处理方法对图像进行分割的效果有什么不同?
答:迭代法:当直方图存在比较明显的波谷时,这种方法是比较好的。
基于Ostu最佳全局阈值方法:如果这两个类中像素点的灰度的方差越大,说明获取到的阈值就是最佳的阈值,利用该阈值可以将图像分为前景和背景两个部分。
五、总结
1.实验收获
通过实验我了解了不同算法的边缘检测,学会使用编程实现不同算法的图像分割,也能够根据不同场合选择最适合的方法。
2.实验不足
通过实验我发现自己对迭代法对不同阈值处理还有点不太理解,对不同检测算子记忆也有点混乱,还需要多看看。