图像分割是指将图像分成若干互不重叠的子区域,使得同一个子区域内的特征具有一定相似性,不同子区域的特征呈现较为明显的差异。
1.基于阈值分割处理方法
基本思想:首先,确定一个合适的阈值T(阈值选定的好坏是此方法成败的关键);其次,将大于等于阈值的像素作为物体或背景,生成一个二值图像。(基于图的灰度直方图)
f = imread('下载.jpg');f=rgb2gray(f);
f =imnoise(f,'salt & pepper',0.05);
count = 0;
T = mean2(f);
done = false;
while ~done
count = count+1;
g = f>T;
Tnext = 0.5*(mean(f(g))+mean(f(~g)));
done = abs(T-Tnext)<0.5;
T =Tnext;
end
count
T
g = im2bw(f,T/255);
subplot(131),imshow(f),title('带噪声的图像');
subplot(132),imhist(f),title('图像的直方图');
subplot(133),imshow(g),title('全局阈值分割的结果')
2.基于边缘检测的分割方法
基本思路:先确定图像中的边缘像素,然后再把这些像素连接在一起就构成所需的区域边界。
图像边缘:即表示图像中一个区域的终结和另一个区域的开始,图像中相邻区域之间的像素集合构成了图像的边缘。所以,图像边缘可以理解为图像灰度发生空间突变的像素的集合。图像边缘有两个要素,即:方向和幅度。沿着边缘走向的像素值变化比较平缓;而沿着垂直于边缘的走向,像素值则变化得比较大。因此,根据这一变化特点,通常会采用一阶和二阶导数来描述和检测边缘。
图像中的边缘检测可以通过对灰度值求导数来确定,而导数可以通过微分算子计算来实现。在数字图像处理中,通常是利用差分计算来近似代替微分运算。
基本思想:计算局部微分算子
一阶导数:用梯度算子来计算
用途:用于检测图像中边的存在
二阶导数:通过拉普拉斯算子来计算
用途:
1)二阶导数的符号,用于确定边上的像素是在亮的一边,还是暗一的边。
2)二阶导数的零交叉点用于确定边缘的中心。
f = imread('下载.jpg'); f=rgb2gray(f);
subplot(231),imshow(f),title('原始图像');
[gv,t] = edge(f,'sobel','vertical');
subplot(232),imshow(gv),title('默认阈值垂直的sobel图像');
t
gv = edge(f,'sobel',0.15,'vertical');
subplot(233),imshow(gv),title('阈值0.15垂直的sobel图像')
gboth = edge(f,'sobel',0.15);
subplot(234),imshow(gboth),title('阈值为0.15垂直水平的sobel图像')
wneg45 = [-2 -1 0;-1 0 1;0 1 2];
gneg45 = imfilter(tofloat(f),wneg45,'replicate');
T =0.3*max(abs(gneg45(:)));
gneg45 = gneg45>=T;
subplot(235),imshow(gneg45),title('阈值45°边缘图像')
3.区域生长法
在种子点1的4邻域连通像素中,即2、3、4、5点,像素点5的灰度值与种子点的灰度值最接近,所以像素点5被加入到分割区域中,并且像素点5会作为新的种子点执行后面的过程。在第二次循环过程中,由于待分析图像中,即2、3、4、6、7、8,像素7的灰度值和已经分割的区域(由1和5组成)的灰度均值10.5最接近,所以像素点7被加入到分割区域中。最后一幅图,示意了区域生长的方向(由浅入深)。
从上面的分析中,我们可以看出,在区域生长过程中,需要知道待分析像素点的编号(通过像素点的x和y坐标值来表示),同时还要知道这些待分析点的像素的灰度值。
%regiongrow源程序
function [g,NR,SI,TI]=regiongrow(f,S,T)
%regiongrow执行区域生长
%[g,NR,SI,TI]=regiongrow(f,S,T).S可以是一个数组,它在每个种子点的坐标为1.
%S也可以是单个种子。
%相似地,T可以是一个数组,f中的每个位置都包含一个阈值。
%T也可以是一个标量,它定义一个全局阈值。
%
%在输出中,g是分割后的图像,每个区域的成员都用整数标出。
%参数NR是不同区域的数目。
%参数SI是一幅包含有种子点的图像。
%参数TI是一幅图像,该图像中包含在经过连通性处理前通过阈值测试的像素。
f=double(f);
%如果S是标量,则包含种子图像。
if numel(S)==1
SI=f==S;
S1=S;
else
%S是一个数组。排除重复,它包含在以下编码部分与种子位置联系去减少循环执行数量。
SI=bwmorph(3,'shrink',Inf);
J=find(J);
end
TI=false(size(f));
for K=1:length(S1)
seedvalue=S1(K);
S=abs(f-seedvalue)<=T;
TI=TI|S;
end
%使用SI的函数重构作为标记图像去获得区域与S中每个种子相符合。
%函数bwlabel分配不同的整数去每个区域。
[g,NR]=bwlabel(imreconstruct(SI,TI));
f = imread('下载.jpg'); f=rgb2gray(f);
subplot(221),imshow(f),title('原始图像');
[g,NR,SI,TI]=regiongrow(f,255,65);%种子的像素值为255,65为阈值
subplot(222),imshow(SI),title('种子点的图像');
subplot(223),imshow(TI),title('所有通过阈值测试的像素');
subplot(224),imshow(g),title('对种子点进行8连通分析后的结果');
4.区域分裂合并法
区域分裂合并法, 它与区域生长法略有相似之处,但无需预先指定种子点,而是按某种一致性准则分裂或者合并区域。
分裂合并法对分割复杂的场景图像比较有效。
分裂合并法算法实现:1)对图像中灰度级不同的区域,均分为四个子区域。2)如果相邻的子区域所有像素的灰度级相同,则将其合并。
3)反复进行上两步操作,直至不再有新的分裂与合并为止。
具体实现时,分裂合并算法是基于四叉树数据表示方式进行。