close all; 



 %% 

 %Step 1: 彩色图像->灰度图像 

 rgb = imread('pears.png'); 

 I = rgb2gray(rgb); 

 figure;subplot(121) 

 imshow(I) 

 %Step 2: 利用梯度实现图像的分割 

 %使用sobel算子进行边缘检测, 

 text(732,501,'Image courtesy of Corel','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);%求模 

 subplot(122), imshow(gradmag,[]), title('gradmag') 

 %直接用分水岭 

 %L=watershed(gradmag); 

 %Lrgb=label2rgb(L); 

 %figure;imshow(Lrgb), 

 %title('Lrgb') 

 %No. 如果没有额外的预处理,如下面的标记计算,使用分水岭变换直接结果往往是“过度分割。”  

 % 以下是标记前景和背景物体 

 %各种程序可以在这里应用到找到前景标记,它必须连接内的每个前景对象的像素的斑点。在这个例子中,你将使用名为“开放由重建”及以上的图像“闭合由重建”为“干净”的形态学技术。这些操作将创建一个可以使用imregionalmax位于每个对象内部平最大值。 

 %Step 3:形态学开操作 

 se = strel('disk', 20);%圆形结构元素 

 Io = imopen(I, se);%形态学开操作 

 figure;subplot(121) 

 imshow(Io), title('Io')%显示执行后的图 

 %Step 4:腐蚀与重建 

 Ie = imerode(I, se);%对图像进行腐蚀 

 Iobr = imreconstruct(Ie, I);%对图像进行重建 

 subplot(122);imshow(Iobr), %显示重建后的图像 

 title('Iobr') 

 %Step 5:形态学关操作 

 Ioc = imclose(Io, se);%形态学关操作 

 figure;subplot(121) 

 imshow(Ioc),  

 title('Ioc') 

 %Step 6:图像膨胀与求反 

 Iobrd = imdilate(Iobr, se);%对图像进行膨胀 

 Iobrcbr = imreconstruct(imcomplement(Iobrd), imcomplement(Iobr)); 

 Iobrcbr = imcomplement(Iobrcbr);%对图像求反 

 subplot(122);imshow(Iobrcbr),  

 title('Iobrcbr') 

 %%Step 7:获得局部最大值 

 fgm = imregionalmax(Iobrcbr);%获得局部最大值 

 figure;imshow(fgm),  

 title('fgm') 

 %Step 8:在原图上显示极大值区域 

 I2 = I; 

 I2(fgm) = 255;%局部极大值处像素值设为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);%开操作 

 %Step 9:显示修改后的极大区域 

 I3 = I; 

 I3(fgm4) = 255;%前景设置为255 

 figure;subplot(121), 

 imshow(I3)%显示修改后的极大区域 

 title('fgm4 superimposed on original image') 

 %现在标记背景, 在清理后的图像,Iobrcbr,暗像素属于背景,所以你可以从一个阈值操作。 

 %Step 10:转化为二值图像 

 bw = im2bw(Iobrcbr, graythresh(Iobrcbr)); 

 subplot(122);imshow(bw), 

 title('bw') 

 %背景像素是黑色的,但理想地,我们不希望的背景标记是太靠近我们目标对象的边缘。我们通过'骨骼化'进行细分,对二值图像的距离进行分水岭变换,然后寻找分水岭的界线。 

 %Step 11: 

 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);%分水岭变换 

 I4 = I; 

 I4(imdilate(L == 0, ones(3, 3)) | bgm | fgm4) = 255;%前景及边界处置255 

 figure; subplot(121) 

 imshow(I4)%突出前景及边界 

 title('Markers and object boundaries') 

 Lrgb = label2rgb(L, 'jet', 'w', 'shuffle');%转化为伪彩色图像 

 subplot(122); imshow(Lrgb)%显示伪彩色图像 

 title('Colored watershed label matrix') 

 figure; imshow(I),  

 hold on 

 himage = imshow(Lrgb);%在原图上显示伪彩色图像 

 set(himage, 'AlphaData', 0.3); 

 title('Lrgb superimposed transparently on original image')