I have image of Tiger\'s Pugmark (footprint impression) in mud. I want to detect the boundary of the pugmark but the image is uniform in intensity that is foreground and bac
The approach in the @mmpg’s answer may be unstable, since the used algorithms require setting of parameters, which may be specific for each image. This problem seems to be better approached with parametric models that have prior knowledge about the shape.
Active Shape Models framework iteratively approximates the boundary of the shape. First, you initialize it with some average shape (images are just illustrations, not the actual output of the algorithm):
The contour is defined by the anchor points (shown by blue ticks, only for the palm to avoid clutter). In each iteration the algorithm considers orthogonal directions in each anchor point and estimates the probability of the boundary at each distance (usually using the image gradient, but in your case it should be more complicated — may be the difference in texture, e.g. distance between histograms of textons). Here red points highlight arg-maximums of that distributions:
Then the new contour is fit to the data to maximize those distributions multiplied by the prior distribution of the shape. Assuming the uniform prior, the new contour would look like this:
In practice you would like to have a non-trivial shape distribution. To estimate that, you will need a training set of images where the pugmark masks are manually labelled.
You may want to try this MATLAB implementation.
In segmentation tasks if you have both
then it is directly solved by a Watershed Transform. The problem, of course, is obtaining these markers, as well enhancing relevant edges as needed. Obtaining these might involve problem-specific knowledge, which I don't have for your problem.
Nevertheless, there are some general methods that might be useful. For instance, connected operators from Mathematical Morphology serve as a way to merge and extend flat zones. Thus, maybe it can give us relatively good markers for the problem. In the following image a morphological reconstruction by opening (a kind of connected operator) was performed in the grayscale version of the original image (left image), and the remaining regional maximum is shown at right.
Now, we can obtain the morphological gradient of the left image above. We can also do hole filling and a dilation with a small disk in the right image above to obtain more smooth contours -- this defines our marker image. Then, applying a Watershed Transform in the gradient image using our marker image, and then expanding (erode or dilate, depends on how you see it) the watershed lines, we get the following image:
I suspect that you can discard too large and too small regions easily. Then, if you have some rough expected sizes for the claws, as well for the palm, you can discard the irrelevant regions. At this point it is only a matter of dilating the areas to form a single component and show the resulting contour in the original image:
Sample code for performing each step (the relevant steps are also shown in commented Matlab code):
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 < # < 3000 || 6000 < # < 10000 &]
(* Final image (thick border on binarized filled dilated ccs) *)
res = ImageAdd[f, Dilation[MorphologicalPerimeter[FillingTransform[
MorphologicalPerimeter[Dilation[ccs, DiskMatrix[9]]]]], 2]]