标记分水岭Word格式.docx
《标记分水岭Word格式.docx》由会员分享,可在线阅读,更多相关《标记分水岭Word格式.docx(17页珍藏版)》请在冰豆网上搜索。
clc;
clearall;
closeall;
rgb=imread('
Sunset.jpg'
);
ifndims(rgb)==3
I=rgb2gray(rgb);
else
I=rgb;
end
figure('
units'
'
normalized'
position'
[0011]);
subplot(1,2,1);
imshow(rgb);
title('
原图'
subplot(1,2,2);
imshow(I);
灰度图'
第2步:
将梯度幅值作为分割函数
使用Sobel边缘算子对图像进行水平和垂直方向的滤波,然后求取模值,sobel
算子滤波后的图像在边界处会显示比较大的值,在没有边界处的值会很小。
hy=fspecial('
sobel'
hx=hy'
;
Iy=imfilter(double(I),hy,'
replicate'
Ix=imfilter(double(I),hx,'
gradmag=sqrt(Ix.^2+Iy.^2);
imshow(I,[]),title('
灰度图像'
)
imshow(gradmag,[]),title('
梯度幅值图像'
可否直接对梯度幅值图像使用分水岭算法?
L=watershed(gradmag);
Lrgb=label2rgb(L);
imshow(Lrgb);
梯度幅值做分水岭变换'
直接使用梯度模值图像进行分水岭算法得到的结果往往会存在过度分割的现象。
因此通常需要分别对前景对象和背景对象进行标记,以获得更好的分割效果。
第3步:
标记前景对象
有多种方法可以应用在这里来获得前景标记,这些标记必须是前景对象内部的连
接斑点像素。
这个例子中,将使用形态学技术“基于开的重建”和“基于闭的重
建”来清理图像。
这些操作将会在每个对象内部创建单位极大值,使得可以使用
imregionalmax来定位。
开运算和闭运算:
先腐蚀后膨胀称为开;
先膨胀后腐蚀称为闭。
开和闭这两种运
算可以除去比结构元素小的特定图像细节,同时保证不产生全局几何失真。
开运
算可以把比结构元素小的突刺滤掉,切断细长搭接而起到分离作用;
闭运算可以
把比结构元素小的缺口或孔填充上,搭接短的间隔而起到连接作用。
开操作是腐蚀后膨胀,基于开的重建(基于重建的开操作)是腐蚀后进行形态学
重建。
下面比较这两种方式。
首先,用imopen做开操作。
se=strel('
disk'
20);
Io=imopen(I,se);
imshow(I,[]);
imshow(Io),title('
图像开操作'
接下来,通过腐蚀后重建来做基于开的重建计算。
Ie=imerode(I,se);
Iobr=imreconstruct(Ie,I);
imshow(Iobr,[]),title('
基于开的重建图像'
开操作后,接着进行闭操作,可以移除较暗的斑点和枝干标记。
对比常规的形态
学闭操作和基于闭的重建操作。
首先,使用imclose:
Ioc=imclose(Io,se);
Ic=imclose(I,se);
subplot(2,2,1);
subplot(2,2,2);
imshow(Io,[]);
开操作图像'
subplot(2,2,3);
imshow(Ic,[]);
闭操作图像'
subplot(2,2,4);
imshow(Ioc,[]),title('
开闭操作'
现在使用imdilate,然后使用imreconstruct。
注意必须对输入图像求补,对
imreconstruct输出图像求补。
IM2=imcomplement(IM)计算图像IM的补集。
IM
可以是二值图像,或者RGB图像。
IM2与IM有着相同的数据类型和大小。
Iobrd=imdilate(Iobr,se);
Iobrcbr=imreconstruct(imcomplement(Iobrd),imcomplement(Iobr));
Iobrcbr=imcomplement(Iobrcbr);
imshow(Ioc,[]);
imshow(Iobr,[]);
imshow(Iobrcbr,[]),title('
基于闭的重建图像'
通过比较Iobrcbr和loc可以看到,在移除小污点同时不影响对象全局形状的应
用下,基于重建的开闭操作要比标准的开闭重建更加有效。
计算Iobrcbr的局部
极大来得到更好的前景标记。
fgm=imregionalmax(Iobrcbr);
subplot(1,3,1);
subplot(1,3,2);
imshow(Iobrcbr,[]);
基于重建的开闭操作'
subplot(1,3,3);
imshow(fgm,[]);
局部极大图像'
为了帮助理解这个结果,叠加前景标记到原图上。
It1=rgb(:
:
1);
It2=rgb(:
2);
It3=rgb(:
3);
It1(fgm)=255;
It2(fgm)=0;
It3(fgm)=0;
I2=cat(3,It1,It2,It3);
imshow(rgb,[]);
原图像'
imshow(I2);
局部极大叠加到原图像'
注意到大多闭塞处和阴影对象没有被标记,这就意味着这些对象在结果中将不会
得到合理的分割。
而且,一些对象的前景标记会一直到对象的边缘。
这就意味着
应该清理标记斑点的边缘,然后收缩它们。
可以通过闭操作和腐蚀操作来完成。
se2=strel(ones(5,5));
fgm2=imclose(fgm,se2);
fgm3=imerode(fgm2,se2);
imshow(fgm2,[]);
闭操作'
imshow(fgm3,[]);
腐蚀操作'
这个过程将会留下一些偏离的孤立像素,应该移除它们。
可以使用bwareaopen,
用来移除少于特定像素个数的斑点。
BW2=bwareaopen(BW,P)从二值图像中移除
所以少于P像素值的连通块,得到另外的二值图像BW2。
fgm4=bwareaopen(fgm3,20);
It1(fgm4)=255;
It2(fgm4)=0;
It3(fgm4)=0;
I3=cat(3,It1,It2,It3);
imshow(I2,[]);
闭腐蚀操作'
imshow(fgm4,[]);
去除小斑点操作'
imshow(I3,[]);
修改局部极大叠加到原图像'
第4步:
计算背景标记
现在,需要标记背景。
在清理后的图像Iobrcbr中,暗像素属于背景,所以可以
从阈值操作开始。
bw=im2bw(Iobrcbr,graythresh(Iobrcbr));
imshow(bw,[]);
阈值分割'
背景像素在黑色区域,但是理想情形下,不必要求背景标记太接近于要分割的对
象边缘。
通过计算“骨架影响范围”来“细化”背景,或者SKIZ,bw的前景。
这个可以通过计算bw的距离变换的分水岭变换来实现,然后寻找结果的分水岭
脊线(DL==0)。
D=bwdist(BW)计算二值图像BW的欧几里得矩阵。
对BW的
每一个像素,距离变换指定像素和最近的BW非零像素的距离。
bwdist默认使用
欧几里得距离公式。
BW可以由任意维数,D与BW有同样的大小。
D=bwdist(bw);
DL=watershed(D);
bgm=DL==0;
imshow(label2rgb(DL),[]);
分水岭变换示意图'
imshow(bgm,[]);
分水岭变换脊线图'
第5步:
计算分割函数的分水岭变换
函数imimposemin可以用来修改图像,使其只是在特定的要求位置有局部极小。
这里可以使用imimposemin来修改梯度幅值图像,使其只在前景和后景标记像素
有局部极小。
gradmag2=imimposemin(gradmag,bgm|fgm4);
前景标记'
imshow(gradmag,[]);
imshow(gradmag2,[]);
修改梯度幅值图像'
最后,可以做基于分水岭的图像分割计算。
一个可视化技术是叠加前景标记、背景标记、分割对象边界到初始图像。
可以使
用膨胀来实现某些要求,比如对象边界,更加清晰可见。
对象边界定位于L==0
的位置。
fgm5=imdilate(L==0,ones(3,3))|bgm|fgm4;
It1(fgm5)=255;
It2(fgm5)=0;
It3(fgm5)=0;
I4=cat(3,It1,It2,It3);
可视化说明了前景和后景标记如何影响结果。
在几个位置,部分的较暗对象与它
们相邻的较亮的邻接对象相融合,这是因为受遮挡的对象没有前景标记。
另外一个有用的可视化技术是将标记矩阵作为彩色图像进行显示。
标记矩阵,比
如通过watershed和bwlabel得到的,可以使用label2rgb转换到真彩图像来显示。
Lrgb=label2rgb(L,'
jet'
w'
shuffle'
彩色分水岭标记矩阵'
可以使用透明度来叠加这个伪彩色标记矩阵在原亮度图像上进行显示。
holdon;
himage=imshow(Lrgb);
set(himage,'
AlphaData'
0.3);
title('
标记矩阵叠加到原图像'
参考:
http:
//blueben‐
代码:
L=watershed(gradmag2);