Matlab中标记控制的分水岭算法中的过分割问题

8

我在使用Matlab实现标记控制的分水岭算法时遇到了问题。

输入图像是一个二进制掩模,其中包含两个聚类对象。另一张图像是另一个二进制图像,其中白色区域表示标记。

image marker

然后我尝试使用标记控制的分水岭算法来分割聚类对象。代码如下:

bw=imread('Im.jpg'); % read image
bwMarker=imread('Marker.jpg');% read marker
bw(bwMarker)=0; % impose the marker on the image
L=watershed(bw);% do the watershed
%% plot
rgb = label2rgb(L,'jet',[.5 .5 .5]);
figure(2), imshow(rgb,'InitialMagnification','fit')
title('Marker Controlled Watershed transform ')

结果显示在这个图表中。

enter image description here
它将对象分成两部分,但形状不完整。我想得到整个对象,但只是一条线将两个对象分开(如下所示)。有人能帮我吗?谢谢。

enter image description here

追加问题: 感谢yoda提供答案。然而,在这种情况下,使用“cityblock”进行距离变换是好的,但如果我们使用“euclidean”,它会导致过度分割。因为分水岭将取决于图像中的局部最小值,并且巧合的是,“cityblock”距离变换会产生正确数量的局部最小值。如果我们将“cityblock”应用于其他图像,则也会导致过度分割。 现在让我们看看yoda的代码:

img=im2bw(imread('http://i.stack.imgur.com/qrYCL.jpg'));

imgDist=-bwdist(~img,'cityblock');
imgDist(~img)=-inf; 

% check local minimums
BW = imregionalmin(imgDist);
figure(1), imshow(BW);  
title('Regional Minima in Original Image');

imgLabel=watershed(imgDist); 

以下是本地最小值和结果的展示:
请注意,在左侧图像中,局部最小值显示为白色区域。可以观察到聚类对象中仅有两个本地最小值。这导致了良好的结果。
现在,让我们通过使用“欧几里得距离”来查看距离变换。
imgDist=-bwdist(~img);
imgDist(~img)=-inf; 

% check local minimums    
BW = imregionalmin(imgDist);
figure(1), imshow(BW);  
title('Regional Minima in Original Image');

imgLabel=watershed(imgDist);    

imshow(imgLabel==0,'InitialMagnification','fit')

本地最小值和结果如下图所示:

enter image description hereenter image description here

请注意,在左侧的图中,局部最小值显示为白色区域。观察到在聚类对象区域中有许多局部最小值,这导致了过度分割的结果。

过度分割是因为分水岭将首先检查图像中的局部最小值,然后根据局部最小值执行分水岭操作。请注意,如果局部最小值太多,超过所需的分割对象,就会导致过度分割。提出了标记控制的分水岭来替换原始局部最小值并实现更好的结果(因为每个标记将表示一个所需的分割对象)。但是我不知道如何施加“标记”以抑制原始局部最小值,使图像仅具有由“标记”指定的局部最小值。谢谢。

2个回答

8

解决方案2:使用基于标记的分水岭算法:

您可以使用函数imimposemin强制使局部最小值处于标记位置。您需要稍微修改下面解决方案1中的代码,将第一个imDist ...行替换为

imgDist=-bwdist(~img);
imgDist=imimposemin(imgDist,marker);

其余代码相同。您应该得到以下分割:

enter image description here


解决方案1:使用曼哈顿距离:

这是MATLAB中的一种解决方案,可将您的两个集群分开:

img=im2bw(imread('http://i.stack.imgur.com/qrYCL.jpg'));

imgDist=-bwdist(~img,'cityblock');
imgDist(~img)=-inf;    
imgLabel=watershed(imgDist);    

imshow(imgLabel==0,'InitialMagnification','fit')

enter image description here


1
@belisarius:inf代表无穷大——或者说在实际应用中,表示一个非常大的数。 - Jonas
嗨Yoda,感谢您的回答。然而,在这种情况下,使用“cityblock”的距离变换是好的,但如果我们使用“euclidean”,它会导致过度分割。如果我们更改为其他示例,它也会失败。请查看我编辑后的问题以获取更多详细信息。谢谢。 - Cheung
@Cheung,请查看我的编辑,回答了您关于基于标记的分水岭的问题 :) - user616736

3
这是我在Mathematica中处理的方式。希望您可以理解。
i1 = Binarize@Import["http://i.stack.imgur.com/qrYCL.jpg"];
marker = Binarize@Import[  "http://i.stack.imgur.com/CMI6Z.jpg"]; 

ImageMultiply[i1, WatershedComponents[i1, marker] // Colorize]

enter image description here


1
不确定Mathematica的答案在这里是否适用。"希望你能翻译"并没有特别有帮助。 - Dang Khoa
4
许多 MATLAB 用户之前对我的 Mathematica 回答非常感激,因为图像处理很相似。例如,可以查看 https://dev59.com/dVXTa4cB1Zd3GeqPzjyk#6259407、https://dev59.com/I1vUa4cB1Zd3GeqPqy_2#7390040 和 https://dev59.com/F2025IYBdhLWcg3w1JmG#6240992。例如,在最后一个问题中,另一个用户(Amro)发布了翻译。因此,我想我的 MATLAB 标签下的回答还是有用的。 - Dr. belisarius
嗨,belisarius,我不懂Mathematica,但还是谢谢你的回答。 - Cheung

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接