rgb = imread('pears.png'); I = rgb2gray(rgb); imshow(I) text(732,501,'Image courtesy of Corel',... 'FontSize',7,'HorizontalAlignment','right')2 利用梯度图像来作为分割函数
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('gradmag')
L = watershed(gradmag); Lrgb = label2rgb(L); figure, imshow(Lrgb), title('Lrgb')
由于没有其他的预处理,则很容易得到一个过分割的结果。
3 标注前景目标
一系列的步骤能够用于得到前景标注,在这个例子当中主要运用形态学处理中的开操作和闭操作来得到前景标注。而开操作和闭操作的实现由两种方式,一种是直接调用imopen和imclose函数,另一种是调用重构函数来实现开操作和闭操作。
首先看开操作的实现:
se = strel('disk', 20); Io = imopen(I, se); figure, imshow(Io), title('Io')另外一个开操作的实现如下所示:
Ie = imerode(I, se); Iobr = imreconstruct(Ie, I); figure, imshow(Iobr), title('Iobr')在开操作之后进行闭操作:
Ioc = imclose(Io, se); figure, imshow(Ioc), title('Ioc')利用重构实现闭操作
Iobrd = imdilate(Iobr, se); Iobrcbr = imreconstruct(imcomplement(Iobrd), imcomplement(Iobr)); Iobrcbr = imcomplement(Iobrcbr); figure, imshow(Iobrcbr), title('Iobrcbr')需要注意的是,在这膨胀之后需要对图像进行求反之后才能进行重构操作。
在开操作和闭操作之后,将区域内的最大值置为1,这样就得到了前景。
fgm = imregionalmax(Iobrcbr); figure, imshow(fgm), title('fgm')
当然,你也可以将这些数据给加到源图像上使得结果更利于理解:
I2 = I; I2(fgm) = 255; figure, imshow(I2), title('fgm superimposed on original image')注意到,许多遮挡以及处于阴影下的目标还没有被分割出来,这意味着这些目标不能很好的在结果中分割出来。同样,前景标注刚好在一些目标的边缘上,这意味着你需要清除这些边缘并将这些边缘进行收缩。这些操作能够由腐蚀和闭操作进行处理。
se2 = strel(ones(5,5)); fgm2 = imclose(fgm, se2); fgm3 = imerode(fgm2, se2);然而这样的处理之后会得到一些独立的像素点,为了消除这些像素点就需要进行消除操作。
fgm4 = bwareaopen(fgm3, 20); I3 = I; I3(fgm4) = 255; figure, imshow(I3) title('fgm4 superimposed on original image')4 计算背景标注
背景的计算是除掉前景之外的部分,这一步的实现是利用最有阈值实现的。
bw = im2bw(Iobrcbr, graythresh(Iobrcbr)); figure, imshow(bw), title('bw')经过上面的操作之后,bw的imcomplement就可以的到图像的背景标注:
由于不希望背景标注离希望分割的目标太近,我们将这个背景进行瘦身操作。这个操作可以利用分水岭变换得到。
D = bwdist(bw); DL = watershed(D); bgm = DL == 0; figure, imshow(bgm), title('bgm')5 计算修改后的分割函数的分水岭变换
imimposemin函数修改分割函数,使得这个分割函数在前景和背景为1的位置有区域内的较小值。因此这个函数可以用于修改最初得到的梯度图像。使得梯度图像在前景和背景处取值是区域内的较小值,对修改后的函数进行分水岭变换。
gradmag2 = imimposemin(gradmag, bgm | fgm4);
<pre name="code" class="cpp">L = watershed(gradmag2);6 将上诉分割结果展示出来第一种方式是利用分割出来的前景和背景对原来的图像进行重新赋值:
I4 = I; I4(imdilate(L == 0, ones(3, 3)) | bgm | fgm4) = 255; figure, imshow(I4) title('Markers and object boundaries superimposed on original image')第二种方式是将分割得到的标记矩阵显示出来:
Lrgb = label2rgb(L, 'jet', 'w', 'shuffle'); figure, imshow(Lrgb) title('Lrgb')第三种方式是利用透明叠加伪彩色来显示结果图像
figure, imshow(I), hold on himage = imshow(Lrgb); set(himage, 'AlphaData', 0.3); title('Lrgb superimposed transparently on original image')