一、实验目的
1 理解阈值分割的依据及确定阈值的方法;
2 掌握常用的边缘检测算子的使用方法,加深对不同算子优缺点的理解;
3 能够自行评价各主要算子在无噪声条件下和噪声条件下的分割性能;
二、实验原理
(一) 阈值分割
1. 直方图法
测试图像:coins.png
原理:观察该图像的直方图,手动选取谷底点作为阈值对该图像进行分割。
2.OTSU法(最大类间方差法)确定阈值
此方法为选择阈值使目标和背景的类间方差最大或者目标(背景)内部方差最小。
相关函数: T=graythresh(f); %计算图像f的全局灰度阈值
3. 迭代阈值法
(1)选择一个初始阈值T0;
(2)根据阈值T0将图像分割为G1和G2两部分。G1包含所有小于等于T0的像素,G2包含所有大于T0的像素。分别求出G1和G2的平均灰度值m1和m2。
(3)得到新的阈值T1=(m1+m2)/2
(4)重复步骤(2)和(3),直到最新阈值和上一个阈值的差小于某个精度。
4. 点检测
用实验法确定阈值对图像中的孤立点进行检测,并总结阈值大小对检测结果的影响。
点检测模板w:
-1 -1 -1
-1 8 -1
-1 -1 -1
检测方法:
g=abs(imfilter(double(f), w))>=T
(二)边缘检测
利用边缘检测算子对图像进行操作,原理类似于图像增强中的模板和图像间的运算关系。
一阶导数可用于检测图像中的一个点是否在边缘上;
二阶导数可以判断一个边缘像素是在边缘亮的一边还是暗的一边;
一阶导数使用梯度算子,二阶导数使用拉普拉斯算子
各梯度算子模板如下:
各算子检测边缘的MATLAB程序语句如下:算子后面的参数可为默认,也可自行定义。
语法:[g,t]=edge(f, ‘method’, parameter)
说明:
g是一个逻辑数组,其值为:在f中检测到边缘的位置为1,其他位置为零;
method为边缘检测器方法,可选为: ‘sobel’, ‘prewit’, ‘roberts’, ‘log’(LoG), ‘zerocoss’, ‘canny’等;
parameter包含两部分:T为指定的阈值,第二部分为dir(检测边缘的首选方向: ‘horizontal’, ‘vertical’, ‘both’),或sigma(标准方差),或H(指定的滤波函数)。
例:
BW1=edge(I,‘roberts’,T, dir);
BW2=edge(I,‘prewitt’, T, dir);
BW3=edge(I,‘sobel’, T, dir);
BW4=edge(I,‘log’, T, dir);
BW5= edge(I,‘canny’, T, dir);
若不写次两个参数,则自动取默认值。
三、实验内容
(一)阈值分割
1. 直方图法
测试图像:coins.png
原理:观察该图像的直方图,手动选取谷底点作为阈值对该图像进行分割。
2. OTSU法
用OTSU法(最大类间方差法)确定阈值并对‘coins.png’或‘lena.jpg’进行分割。要求:分割用两种方法:(1)im2bw函数;(2)for循环。若用“coins.png”图像,则对该方法确定的阈值和上题中直方图确定的阈值进行比较,观察两值大小差别。
3.点检测
完成下面的练习,在实验报告中提交运行结果并回答问题。
练习:分别运行以下两段程序,并回答问题:
(1)
f=imread(‘saturn.png’); w=[-1 -1 -1; -1 8 -1; -1 -1 -1]; g=abs(imfilter(double(f), w)); T=max(g(😃); T=T*0.5; g=g>=T; imshow(f); figure, imshow(g);
问题:此段程序图像g能否正常显示,为什么?如何解决?(根据错误提示)
不能正常显示,因为对于rgb图像没法使用二维模板处理出正确的结果,从而不能显示出正确结果,加上f=rgb2gray(f);
(2)
f=imread(‘saturn.png’); f1=rgb2gray(f); f1=imresize(f1,[512 512]); w=[-1 -1 -1;-1 8 -1;-1 -1 -1]; g=abs(imfilter(double(f1),w)); a=1;T=a*max(g(😃); g=g>=T; imshow(f1); figure, imshow(g);
问题:
程序中的imresize函数的作用是什么?
对图像进行放缩到指定大小
对g=abs(imfilter(double(f1),w))中包含的三个函数的功能分别进行说明。
Double是为了将f1变成双精度浮点型(进行限定)、imfilter是通过w模板对图像进行卷积运算、abs是为了求取绝对值,因为有负数,给取正,便于进行比较
若要清晰显示原图像中的四个孤立点应对第二段程序中的哪部分进行调整。
a=1 的地方,对a进行下调
3. 迭代阈值法(选做)
要求:读懂程序,对3-13行给出注释
f=imread(‘rice.png’); imshow(f); count=0; T=mean2(f); done=false; while ~done count=count+1; g=f>T; T1=0.5*(mean(f(g))+mean(f(~g))); done=abs(T-T1)<0.05; T=T1; end f1=im2bw(f,T/255); imshow(f); figure,imshow(f1);
(二)边缘算子分割
1. 算子分割
(1)利用imfilter函数及Sobel模板(见实验原理部分)分别进行水平、垂直以及综合两方向的边缘检测。
步骤:
a. 读取‘cameraman.tif’图片并用im2double函数进行数据类型转换;
b. 分别生成水平和垂直两个方向的检测模板矩阵;
c. 用imfilter函数对图像分别进行两个方向的算子处理结果GX和GY;
d. 利用abs函数分别取两个方向各自的边缘图像的模值|GX|和|GY|;
e. 分别显示水平边缘、垂直边缘以及两个方向总边缘(|GX|+|GY|);
问题:观察运行后各模值的取值特点,总结本段程序的功能是什么?处理后的图像类型(是灰度图像还是二值图像)
特点是各个像素值是双精度形式,功能是图像锐化,增加边缘的锐利程度,灰度图像
(2)利用edge函数和Sobel算子分别检测水平、垂直及两个方向总边缘并进行显示。
问题:本段程序处理后的图像类型是灰度图像还是二值图像?通过(1)和(2)两段程序运行结果分析,说明两段程序功能上的区别。
二值图像。用算子进行计算时,运算出来的结果是灰度图像不是二值图,这是因为我们在进行算子处理时,是将其边缘锐化,使得边缘显示锐利,是图像增强。而利用edge算法时,处理出来的矩阵是二值图像而不是灰度图,这就是边缘检测,属于图像分割。
2. edge函数分割
用edge函数分别实现sobel算子、Prewitt算子、roberts算子、log算子、零交叉及canny算子的边缘提取,比较几种算子的分割效果,给出结论。
sobel算子、Prewitt算子、roberts算子是一阶算子,而log算子、零交叉及canny算子是二阶算子,并且对于canny算子是有方向梯度,所以效果最好
这里是引用
要求:图像采用‘lean’图像或‘cameraman’图像,所有图像显示在同一窗口。
四、撰写实验报告
程序、运行效果图、评价及总结(实验内容中的问题必须回答)
五、实验代码
%% 1 I = imread('C:\Users\DELL\Desktop\lena.jpg'); level = graythresh(I); BW = im2bw(I,level); imshow(BW); [M,N] = size(I); F = zeros(512); for i = 1:M for j = 1:N if im2double(I(i,j)) >= level F(i,j) = 1; elseif im2double(I(i,j)) < level F(i,j) = 0; end end end imshow(F); subplot(131);imshow(I);title('原图像') subplot(132);imshow(BW);title('im2bw图像') subplot(133);imshow(F);title('For图像') %% f=imread('saturn.png'); f=rgb2gray(f); w=[-1 -1 -1; -1 8 -1; -1 -1 -1]; g=abs(imfilter(double(f), w)); T=max(g(:)); T=T*0.5; g=g>=T; imshow(f); figure, imshow(g); f=imread('saturn.png'); f1=rgb2gray(f); f1=imresize(f1,[512 512]); w=[-1 -1 -1;-1 8 -1;-1 -1 -1]; g=abs(imfilter(double(f1),w)); a=0.4;T=a*max(g(:)); g=g>=T; imshow(f1); figure, imshow(g); %% f=imread('rice.png'); imshow(f); count=0; T=mean2(f); done=false; while ~done count=count+1; g=f>T; T1=0.5*(mean(f(g))+mean(f(~g))); done=abs(T-T1)<0.05; T=T1; end f1=im2bw(f,T/255); %因为阈值范围在【0,1】之间,而mean2得出的阈值只会在[0,255]所以进行归一化 imshow(f); figure,imshow(f1); %% 1 (1) I1 = imread('lena.jpg'); I = im2double(I1); BW1 = [-1 -2 -1;0 0 0;1 2 1]; BW2 = [-1 0 1;-2 0 2;-1 0 1]; g1 = imfilter(I,BW1); g2 = imfilter(I,BW2); % g3 = imfilter(I,BW3); a1 = abs(g1); a2 = abs(g2); a3 = a1+a2; figure subplot(221);imshow(I1);title('原图像'); subplot(222);imshow(a1);title('水平'); subplot(223);imshow(a2);title('垂直'); subplot(224);imshow(a3);title('总边缘'); %% 1 (2) I1 = imread('cameraman.tif'); I = im2double(I1); BW1 = edge(I,'sobel','horizontal'); %水平 BW2 = edge(I,'sobel','vertical'); %垂直 BW3 = edge(I,'sobel','both'); %两者 figure subplot(221);imshow(I1);title('原图像'); subplot(222);imshow(BW1);title('水平'); subplot(223);imshow(BW2);title('垂直'); subplot(224);imshow(BW3);title('总边缘'); %% 2 I1 = imread('cameraman.tif'); I = im2double(I1); BW1 = edge(I,'sobel'); BW2 = edge(I,'roberts'); BW3 = edge(I,'prewitt'); BW4 = edge(I,'log'); BW5 = edge(I,'zerocross'); BW6 = edge(I,'canny'); subplot(231);imshow(BW1);title('sobel'); subplot(232);imshow(BW2);title('roberts'); subplot(233);imshow(BW3);title('prewitt'); subplot(234);imshow(BW4);title('log'); subplot(235);imshow(BW5);title('zerocross'); subplot(236);imshow(BW6);title('canny');
六、实验
直方图
Otus
点检测
迭代阈值法
Imfilter加算子
Edge算子
各种edge