1. 实验目的
①掌握图像分割的含义与目的;
②掌握迭代法、最大类间方差法、直方图法等阈值分割方法;
③掌握霍夫变换、区域生长法、区域分裂与合并法的原理,并能编程实现。
2. 实验内容
①调用Matlab / Python+OpenCV中的相关函数,分别通过实验法、直方图法、大津算法确定阈值,实现图像的全局阈值分割。
②调用Matlab / Python+OpenCV中的霍夫变换函数,检测图像中的直线和圆。
③自行编写代码,实现区域生长法及区域分裂与合并算法。
3. 实验过程
3.1 全局阈值分割
3.1.1迭代法
初始化一个阈值,通过迭代法求出最佳阈值,使用最佳阈值对图像进行分割,并显示原图和分割结果(参考图1)。
(1) 主要调用的函数、功能及参数说明
函数名 | 函数功能 | 参数说明 |
---|---|---|
imread(A) | 读取图片 | A:图片在文件夹的位置 |
rgb2gray(A) | 灰度转化 | A:图片 |
mean(A) | 求列或行的平均数 | A:矩阵 |
mean2(image) | 对整一个矩阵求像素平均值 | image:图片 |
find(A) | 查找非零元素的索引和值 | A:查找条件 |
abs(A) | 返回数组A中每个元素的绝对值和复数的模 | A:矩阵 |
A= imread('lena.png');
image=rgb2gray(A);%灰度转化
T=mean2(image);%取均值作为初始阈值
done=false;%定义跳出循环的量i=0;
%while循环进行迭代
while ~doner1=find(image<=T);%小于阈值的部分r2=find(image>T);%大于阈值的部分Tnew=(mean(image(r1))+mean(image(r2)))/2;%计算分割后两部分的阈值均值的均值done=abs(Tnew-T)<1;%判断迭代是否收敛T=Tnew;%如不收敛,则将分割后的均值的均值作为新的阈值进行循环计算i=i+1;
end
%这两步是将图像转换成二值图像
image(r1)=0;%将小于阈值的部分赋值为0
image(r2)=1;%将大于阈值的部分赋值为1 subplot(121);imshow(A);title('原图')
subplot(122);imshow(image,[]);title('迭代处理后')
(3) 总结(总结实验法步骤,对实验结果进行分析)
当目标与背景的面积相差较大时,更好地选择是将初始阈值T设置为最大灰度值和最小灰度值的中间值。
3.1.2最大类间方差法
使用最大类间方差法求出最佳阈值后,使用最佳阈值对图像进行分割,并显示原图和分割结果(参考图2)
(1) 主要调用的函数、功能及参数说明
函数名 | 函数功能 | 参数说明 |
---|---|---|
graythresh | 采用OTSU算法来获取全局阈值,自动选取阈 | ... |
(2) 源代码及实验结果(添加必要注释)
I = imread('lena.png');
T = graythresh(I); %采用OTSU算法来获取全局阈值,自动选取阈值
K = im2bw(I, T);%二值化
figure;
subplot(121), imshow(I);title('原图')
subplot(122), imshow(K);title('最大类间方差法')
(3) 总结(总结最大类间差分算法步骤,对实验结果进行分析)
最大类间差分算法是根据图像的灰度特性,将图像分为前景和背景两个部分。当取最佳阈值时,两部分之间的差别应该是最大的,前景和背景之间的类间方差如果越大,就说明构成图像的两个部分之间的差别越大。
3.1.3直方图法
首先得到图像的直方图,选出最佳阈值后,使用最佳阈值对图像进行分割,并显示原图和分割结果(参考下图)。
(1) 主要调用的函数、功能及参数说明
函数名 | 函数功能 | 参数说明 |
---|---|---|
imread(A) | 读取图片 | A:图片在文件夹的位置 |
rgb2gray(A) | 灰度转化 | A:图片 |
(2) 源代码及实验结果(添加必要注释)
A = imread('lena.png');
image=rgb2gray(A);%灰度转化[m,n]=size(image);%测量图像尺寸参数
GK=zeros(1,256); %预创建存放灰度出现概率的向量
for k=0:255GK(k+1)=length(find(image==k))/(m*n);%计算每级灰度出现的概率,将其存入GK中相应位置
endsubplot(2,2,1);imshow(image);title('灰度图像')
grid on;%显示网格线
axis on;%显示坐标系subplot(2,2,2),bar(0:255,GK,'g')%绘制直方图
title('灰度直方图')
xlabel('灰度值')
ylabel(' 出现概率')image2=im2bw(A,150/255);
subplot(2,2,3),imshow(image2);title('阈值150的分割图像')
grid on;
axis on;image3=im2bw(A,200/255);
subplot(2,2,4),imshow(image3);title('阈值200的分割图像')
grid on;
axis on;
(3) 总结(总结直方图法步骤,对实验结果进行分析)
图像分割是图像识别的基础,对图像进行图像分割,将目标从背景区域中分离出,可以避免图像识别时在图像上进行盲目的搜索,大大提高图像识别的效率以及识别准确率。基于灰度直方图的阈值分割计算简单,适用于目标与背景分布于不同灰度范围的灰度图像,特别是遥感图像。
3.2 霍夫变换
3.2.1 调用霍夫变换函数检测直线和圆
如下图所示,调用 Matlab/Python+OpenCV中的霍夫变换函数,检测图像中的直线和圆。
(1) 主要调用的函数、功能及参数说明
函数名 | 函数功能 | 参数说明 |
---|---|---|
imread(A) | 读取图片 | A:图片在文件夹的位置 |
(2) 源代码及实验结果(添加必要注释)
①直线检测代码及实验结果:
A= imread('lena.png');I=rgb2gray(A);%灰度转化BW = edge(I,'canny');%Canny方法提取图像边界,返回二值图像(边界1,否则0)
[H,T,R] = hough(BW);%计算二值图像的标准霍夫变换,H为霍夫变换矩阵,I,R为计算霍夫变换的角度和半径值
P = houghpeaks(H,3);%提取3个极值点
x = T(P(:,2));
y = R(P(:,1));
lines=houghlines(BW,T,R,P);%提取线段subplot(1,2,1);imshow(A);title('原图')
subplot(1,2,2);imshow(I);title('直线检测')
hold on;for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');%画出线段
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');%起点
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');%终点
end
②圆形检测代码及实验结果:
rgb= imread('lena.png');
image = rgb2gray(rgb);
imshow(image)d = imdistline(gca);
delete(d)
[centersBright,radiiBright,metricBright] = imfindcircles(rgb,[55 90],'ObjectPolarity','dark','Method','TwoStage','Sensitivity',0.94,'EdgeThreshold',0.1);
hBright = viscircles(centersBright, radiiBright,'Color','b');
b=length(radiiBright);
total_number=b;
③总结(总结霍夫变换检测步骤,并对实验结果进行分析)
霍夫变换的过程是在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果,该方法可以进行圆,直线,椭圆等形状的检测。
3.2.2 实现极坐标系下的霍夫变换(参考图5,6)
⑴ 源代码及实验结果(添加必要注释)
A= imread('lena.png');
I=rgb2gray(A);%灰度转化BW = edge(I,'canny');%Canny方法提取图像边界,返回二值图像(边界1,否则0)
[H,T,R] = hough(BW);%计算二值图像的标准霍夫变换,H为霍夫变换矩阵,I,R为计算霍夫变换的角度和半径值subplot(1,2,1);imshow(A);title('原图')
subplot(1,2,2);imshow(H,[],'XData',T,'YData',R,'InitialMagnification','fit');%hough变换的图像
title('霍夫变换结果')
xlabel('\theta'), ylabel('\rho');
axis on,axis square,hold on;
⑵ 总结(总结极坐标下霍夫变换步骤,对实验结果进行分析)
图像x−yx−y坐标空间中,经过点(xi,yi)(xi,yi)的直线表示为:yi=axi+b(1),yi=axi+b(1)。其中,参数a为斜率,b为截矩。其中,参数a为斜率,b为截矩。通过点(xi,yi)点(xi,yi)的直线有无数条。变换到了参数平面a−ba−b。这个变换就是直角坐标中对于(xi,yi)(xi,yi)点的Hough变换。
3.3 区域生长法
分别使用不同生长准则实现区域生长算法(参考图7)
⑴ 源代码及实验结果(添加必要注释及结果图)
I=imread('lena.png');if isinteger(I)I=im2double(I);
end
I = rgb2gray(I);figure
imshow(I)
[M,N]=size(I);
[y,x]=getpts; %单击取点后,按enter结束
x1=round(x);
y1=round(y);
seed=I(x1,y1); %获取中心像素灰度值J=zeros(M,N);
J(x1,y1)=1;count=1; %待处理点个数
threshold=0.15;
while count>0count=0;for i=1:M %遍历整幅图像for j=1:Nif J(i,j)==1 %点在“栈”内if (i-1)>1&(i+1)<M&(j-1)>1&(j+1)<N %3*3邻域在图像范围内for u=-1:1 %8-邻域生长for v=-1:1if J(i+u,j+v)==0&abs(I(i+u,j+v)-seed)<=thresholdJ(i+u,j+v)=1;count=count+1; %记录此次新生长的点个数endendendendendendend
endsubplot(1,2,1),imshow(I);title('原图')
subplot(1,2,2),imshow(J);title('区域生长实现')
4. 实验小结
①分析和总结全局阈值分割的几种实验结果,能够得到哪些启发或结论?
答:在上面的图像分割中,通过不同的阈值处理方法,得到良好的图像分割结果。不难发现, 对于不同的噪声环境和光照影响等等,一种单一的阈值分割方法往往无法出色的完成任务。
在今后的实验中,要合理的根据自己的图像样本来选择合理的算法。例如是否需要对图像进行平滑去噪,是否需要图像分区来使光照近似均匀。不仅要掌握上面的处理方法,也明白了为什么对上面的图像进行这样的处理和分析。
②当图片过曝或者过暗造成霍夫变换检测效果不理想时,可以采用哪些图像处理方法提升效果?
答:依赖直方图来调整图像强度值
③查阅相关资料,了解更多的图像分割方法,并从原理和结果等方面对比它们之间的异同。
答:
(1)基于阚值的分割方法是按照原图像的灰度特征划分出一个或者几个灰度阈值将原图像的每个像素的灰度值与灰度阈值进行比较,继而确定每个像素应该位于哪个区域。
(2)基于边缘的图像分割
边缘是指一个区域的结束与另一个区域的开始,也就是说图像边缘代表的是两个不同的区域边界线上的一些像素的集合,它一般代表着图像的灰度、纹路、颜色发生了一些突变,是图像局部特征不连续的体现。基于边缘的图像分割方法一般是基于图像灰度值检测的分割方法,即图像边缘是图像灰度值发生突变的一个转折,图像边缘有两个要素:幅度与方向。沿着边缘的方向,灰度值的变化比较小,垂直于边缘的方向,灰度值的变化比较大。因此我们可以对像素的灰度值进行求导来判断图像的边缘。
(3)基于区域的分割方法
区域生长指的是根据同一区域内像素具有一些相似的性质(灰度值、纹路、颜色)来聚集像素点的一种方法。我们可以从一个像素或者是一块很小的区域开始,将周围具有相同性质的像素或者区域划入到目前的区域当中,直到没有其他的像素或者是区域能够划入到当前区域为止,以此来实现区域不断增长的过程。