形态学分水岭直接分割梯度图像会产生过分割。本篇博文参考matlab中的示例以及冈萨雷斯版的《数字图像处理》总结了处理形态学分水岭分割的一般步骤。
主要步骤包括两部分:
1. 平滑预处理。
过分割的一部分原因是图像中有许多尺寸很小的局部最小值,平滑处理是消除很小细节的有效手段。本文利用的是基于重构的开闭操作来消除细节。
2. 应用标记
内部标记被定义为:(1)被更高“海拔”点包围起来的区域;(2)区域中的点组成连通分量;(3)多有属于这个连通分量的点具有相同的灰度值;
外部标记被定义为分水线,有效的将图像分割成不同的区域。沿着分水线的点是很好的背景候选点,因为他们经过相邻标记之间的最高点。可以形象的理解为聚水盆的脊。
matlab代码
% 读取图像
I = imread('cameraman.tif');
imshow(I)
text(732,501,'Image courtesy of Corel(R)',...
'FontSize',7,'HorizontalAlignment','right')
%步骤1:
Ie = imerode(I, se);
Iobr = imreconstruct(Ie, I);
figure, imshow(Iobr), title('Opening-by-reconstruction (Iobr)')
Ioc = imclose(Io, se);
figure, imshow(Ioc), title('Opening-closing (Ioc)')
Iobrd = imdilate(Iobr, se);
Iobrcbr = imreconstruct(imcomplement(Iobrd), imcomplement(Iobr));
Iobrcbr = imcomplement(Iobrcbr);
figure, imshow(Iobrcbr), title('Opening-closing by reconstruction (Iobrcbr)')
% 步骤2:
%imregionalmax计算平滑后的图像的局部最大值得到内部标记
fgm = imregionalmax(Iobrcbr);
figure, imshow(fgm), title('Regional maxima of opening-closing by reconstruction (fgm)')
%清理标记的边缘
se2 = strel(ones(5,5));
fgm2 = imclose(fgm, se2);
fgm3 = imerode(fgm2, se2);
%bwareaopen删除像素少的内部标记即消除一些局部最小值
fgm4 = bwareaopen(fgm3, 20);
I3 = I;
I3(fgm4) = 255;
figure, imshow(I3)
title('Modified regional maxima superimposed on original image (fgm4)')
% 利用阈值然后分水岭分割计算外部标记,即分水线
bw = im2bw(Iobrcbr, graythresh(Iobrcbr));
figure, imshow(bw), title('Thresholded opening-closing by reconstruction (bw)')
D = bwdist(bw);
DL = watershed(D);
bgm = DL == 0;
figure, imshow(bgm), title('Watershed ridge lines (bgm)')
% 使得局部最小值只出现在内部和外部标记点
gradmag2 = imimposemin(gradmag, bgm | fgm4);
%分水岭分割
L = watershed(gradmag2);
% 分割结果
Lrgb = label2rgb(L, 'jet', 'w', 'shuffle');
figure, imshow(Lrgb)
title('Colored watershed label matrix (Lrgb)')
figure, imshow(I), hold on
himage = imshow(Lrgb);
set(himage, 'AlphaData', 0.3);
title('Lrgb superimposed transparently on original image')
分割结果