在分割任务中,如果您同时拥有以下两点:
1. 良好的标记;
2. 对感兴趣对象周围的边缘强度;
那么它可以直接通过 Watershed Transform 来解决。问题是当然要获得这些标记,并根据需要增强相关边缘。获得这些可能涉及特定于问题的知识,而我没有针对您的问题的这些知识。
尽管如此,还是有一些通用方法可能会有用。例如,数学形态学中的连接算子可用作合并和扩展平坦区域的方法。因此,它可能会为我们提供相对良好的标记。在下面的图像中,在原始图像的灰度版本(左图)上执行了开放式形态重建(一种连接算子),并且右边显示了剩余的区域最大值。
现在,我们可以获得上述左图像的形态梯度。我们还可以在上述右图像中进行孔填充和小圆盘膨胀,以获得更平滑的轮廓 - 这定义了我们的标记图像。然后,在使用我们的标记图像对渐变图像应用 Watershed Transform,然后扩展(依赖于您如何看待它,即腐蚀或膨胀)分水岭线之后,我们得到了以下图像:
我怀疑您可以轻松丢弃过大和过小的区域。然后,如果您对爪子和手掌有一些粗略的预期尺寸,您可以丢弃不相关的区域。此时,只需要扩大区域以形成单个组件,并在原始图像中显示结果轮廓即可。
每个步骤的执行示例代码(Matlab 代码的相关步骤也在注释中显示):
f = Import["http://imageshack.us/a/img407/4636/p1060993g.jpg"]
g = ColorConvert[f, "Grayscale"] (* g = rgb2gray(f); *)
(* First image shown: *)
geo = GeodesicOpening[g, DiskMatrix[5]] (* geo = imreconstruct(imerode(g, ... *)
(* strel('disk', 6)), g); *)
(* Second image shown: *)
marker = MaxDetect[geo] (* marker = imregionalmax(geo); *)
(* Watershed on gradient with markers. *)
mgrad = ImageSubtract[Dilation[geo, 1], Erosion[geo, 1]]; (* mgrad = ... *)
(* imdilate(geo,strel('square',3)) - imerode(geo,strel('square',3)); *)
ws = Image[ (* ws = watershed(imimposemin(mgrad, bwmorph(imfill(... *)
WatershedComponents[mgrad, (* imregionalmax(geo),'holes'),'dilate')))); *)
Dilation[FillingTransform[marker], DiskMatrix[1]]]]
(* Third image shown: *)
wsthick = Erosion[ws // ImageAdjust, DiskMatrix[5]]
(* Connected component selection based on some supposed sizes. *)
ccs = SelectComponents[wsthick, "Count", 1000 <
(* Final image (thick border on binarized filled dilated ccs) *)
res = ImageAdd[f, Dilation[MorphologicalPerimeter[FillingTransform[
MorphologicalPerimeter[Dilation[ccs, DiskMatrix[9]]]]], 2]]