Marker-Controlled Watershed Segmentation
第一步:读入图像并转为黑白图像
rgb = imread('pears.png'); I = rgb2gray(rgb); imshow(I) text(732,501,'Image courtesy of Corel(R)', 'FontSize',7,'HorizontalAlignment','right') |
第二步:使用梯度作为分割函数
hy = fspecial('sobel'); hx = hy'; Iy = imfilter(double(I), hy, 'replicate'); Ix = imfilter(double(I), hx, 'replicate'); gradmag = sqrt(Ix.^2 + Iy.^2); figure, imshow(gradmag,[]), title('Gradient magnitude (gradmag)') |
上图是在没有预处理就进行分割的结果。
在没有经过标记前景等预处理就进行分水岭分割,会导致过度分割
第三步:标记前景对象
有很多的方法可以在这里来获取前景标记,这些标记必须是前景对象内部的连接斑点像素。在这个例子中,你将使用形态学技术“开重建”和“闭重建”来处理(‘清理’)图像。这些操作将会在每个对象内部创建单位的极大值,以便于使用imregionalmax。
开运算是先腐蚀再膨胀,开运算在腐蚀后紧跟着生态重建。
首先用imopen进行开运算。
se = strel('disk', 20); Io = imopen(I, se); figure, imshow(Io), title('Opening (Io)') |
然后用imerode和imreconstruct计算开重建。
Ie = imerode(I, se); Iobr = imreconstruct(Ie, I); figure, imshow(Iobr), title('Opening-by-reconstruction (Iobr)') |
开运算之后使用闭运算能够去除图像中的暗点和比结构小的图像细节。下面对普通的生物闭运算和闭重建进行比较。首先用imclose进行闭运算
Ioc = imclose(Io, se); figure, imshow(Ioc), title('Opening-closing (Ioc)') |
现在用imdilate再用imreconstruct,切记必须已经有imreconstruct的输输入出结果。
Iobrd = imdilate(Iobr, se); Iobrcbr = imreconstruct(imcomplement(Iobrd), imcomplement(Iobr)); Iobrcbr = imcomplement(Iobrcbr); figure, imshow(Iobrcbr), title('Opening-closing by reconstruction (Iobrcbr)') |
从上面比较Iobrcbr和Ioc就能够看出,基于重建的开运算和比运算比基本的开闭运算更加邮箱,能够在保证不影响对象整体形状的同时去除细节。计算Iobrcbr的区域最大值就能够得到前景标记。
fgm = imregionalmax(Iobrcbr); figure, imshow(fgm), title('Regional maxima of opening-closing by reconstruction (fgm)') |
为了能够更好地展示结果,将上图的前景标记附到原始图像上
I2 = I; I2(fgm) = 255; figure, imshow(I2), title('Regional maxima superimposed on original image (I2)') |
我们注意到一些被遮挡和有阴影的对象并没有被标记出来,也就是说在最后的结果中这些对象并不能很好的被分割。此外,一些前景标记到了对象的边缘,这样我们必须要清除这些边界收缩一点范围。这些能够通过先闭运算再腐蚀的方式实现。
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)') |
第四步:计算背景的标记
现在我们需要标记出背景。在清理后的图像Iobrcbr中,暗点既是北京,因此我们首先进行一个阈值开运算。
bw = im2bw(Iobrcbr, graythresh(Iobrcbr)); figure, imshow(bw), title('Thresholded opening-closing by reconstruction (bw)') |
这样背景像素就用黑色来表示,但是我们并不希望背景标记和对象的边界离得太近。我们要通过计算骨骼影响区域或者bw的前景来对背景进行’瘦身‘。这一部能够通过计算bw的距离变换的分水岭变换来实现,之后遭到结果的分水岭界限。
D = bwdist(bw); DL = watershed(D); bgm = DL == 0; figure, imshow(bgm), title('Watershed ridge lines (bgm)') |
第五步:计算分割方程的分水岭变换
imimposemin函数能够用于规范图像,使得图像只在特定的位置存在区域最小值。这里我们使用imimposemin来规范梯度图像,使得区域最小值只落在前景和北京标记的像素上
gradmag2 = imimposemin(gradmag, bgm | fgm4); |
最后我们计算基于分水岭的分割
L = watershed(gradmag2); |
第六步:可视化结果
方法一: I4 = I; I4(imdilate(L == 0, ones(3, 3)) | bgm | fgm4) = 255; figure, imshow(I4) title('Markers and object boundaries superimposed on original image (I4)')
方法二: 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')
|