实验三 图像轮廓提取与边缘检测
一、实验目的:
理解并掌握对二值图像进行轮廓提取的相关算法(比如,掏空内部点法),以及用于图像边缘检测和提取的典型微分算子(梯度算子和拉普拉斯算子)。
二、实验环境:
计算机、Windows XP操作系统,Matlab7.0
二、实验内容:
1、根据掏空内部点算法,运用Matlab编程实现二值图像的轮廓提取。
%以下适用于黑色背景白色前景的二值图像轮廓提取(以二值图像circles为例)
BW=imread('circles.png'); %二值图像circles是uint8,0黑,255白
subplot(1,2,1); imshow(BW); title('二值图像');
[M, N]=size(BW); %M行,N列
BW_Buffer=BW;
for i=2: M-1
for j=2: N-1
if (BW(i, j)==255 & BW(i-1, j)==255 & BW(i+1, j)==255 & BW(i, j-1)==255 & BW(i, j+1)==255 & BW(i-1, j-1)==255 & BW(i-1, j+1)==255 & BW(i+1, j-1)==255 & BW(i+1, j+1)==255) %说明BW(i, j)是前景中的一个内部点
BW_Buffer(i, j)=0; %掏空该内部点,即将该内部点置成与背景相同灰度
end
end
end
subplot(1,2,2); imshow(BW_Buffer); title('提取轮廓');
%以下适用于白色背景黑色前景的二值图像轮廓提取(以二值图像source为例)
BW=imread('source.bmp'); %二值图像source是uint8,0黑,255白
subplot(1,2,1); imshow(BW); title('二值图像');
[M, N]=size(BW); %M行,N列
BW_Buffer=BW;
for i=2: M-1
for j=2: N-1
if (BW(i, j)==0 & BW(i-1, j)==0 & BW(i+1, j)==0 & BW(i, j-1)==0 & BW(i, j+1)==0 & BW(i-1, j-1)==0 & BW(i-1, j+1)==0 & BW(i+1, j-1)==0 & BW(i+1, j+1)==0) %说明BW(i, j)是前景中的一个内部点
BW_Buffer(i, j)=255; %掏空该内部点,即将该内部点置成与背景相同灰度
end
end
end
subplot(1,2,2); imshow(BW_Buffer); title('提取轮廓');
注意:使用掏空内部点的方法来提取二值图像的轮廓时,不能直接在原始二值图像矩阵上判断一个点掏空一个点,否则对前面像素的掏空操作会影响到对后面像素的判断结果。
解决方法:创建原始二值图像矩阵的副本(即图像矩阵BW_Buffer),在原始二值图像矩阵上执行判断操作,即依次判断每个像素点是否为前景中的内部点,如果是,则在图像矩阵BW_Buffer上执行掏空内部点的操作。
2、以灰度图像rice和cameraman为例,利用Matlab图像处理工具箱中的edge函数,分别使用Roberts 算子、Sobel算子、Prewitt 算子对其进行边缘检测。
(1)函数格式: BW = edge(I, 'method', thresh)
(2)格式说明:edge函数输入灰度图像矩阵I,输出二值图像矩阵BW;参数'method'用于指定所使用的边缘检测算子,可以是'roberts'、'sobel'、'prewitt'、'log'、'canny';参数thresh用于指定梯度门限值(也称梯度阈值),图像中梯度值大于等于门限值thresh的像素用白色(1)表示,说明这些地方对应边缘,梯度值小于门限值thresh的像素用黑色(0)表示(edge function will ignore all edges that are not stronger than thresh)。若不指定参数thresh,则edge函数会自动选择阈值。所以edge函数最终将原始灰度图像中的边缘和背景用二值图像的形式展现出来,以突出边缘的位置,达到边缘检测的目的。
(3)程序如下:
I=imread('rice.png');
subplot(2,2,1); imshow(I); title('原始图像');
[BW1,thresh1]=edge(I,'roberts'); %进行Roberts算子边缘检测并返回门限值
[BW2,thresh2]=edge(I,'sobel'); %进行Sobel算子边缘检测并返回门限值
[BW3,thresh3]=edge(I,'prewitt'); %进行Prewitt算子边缘检测并返回门限值
subplot(2,2,2); imshow(BW1); title('Roberts算子边缘检测结果');
subplot(2,2,3); imshow(BW2); title('Sobel算子边缘检测结果');
subplot(2,2,4); imshow(BW3); title('Prewitt算子边缘检测结果');
若向原始图像中加入随机噪声(比如高斯噪声),之后再对噪声图像分别运用Roberts 算子、Sobel算子、Prewitt 算子、Log算子(高斯-拉普拉斯算子)进行边缘检测,观察检测结果,试比较4种边缘检测算子的抗噪声干扰能力。
I=imread('rice.png');
subplot(2,3,1); imshow(I); title('原始图像');
G=imnoise(I, 'gaussian'); %向原始图像中加入高斯噪声
subplot(2,3,2); imshow(G); title('噪声图像');
BW1=edge(G, 'roberts'); %进行Roberts算子边缘检测
BW2=edge(G, 'sobel'); %进行Sobel算子边缘检测
BW3=edge(G, 'prewitt'); %进行Prewitt算子边缘检测
BW4=edge(G, 'log'); %进行Log算子边缘检测
subplot(2,3,3); imshow(BW1); title('Roberts算子边缘检测结果');
subplot(2,3,4); imshow(BW2); title('Sobel算子边缘检测结果');
subplot(2,3,5); imshow(BW3); title('Prewitt算子边缘检测结果');
subplot(2,3,6); imshow(BW4); title('Log算子边缘检测结果');