I have a picture of a lake as follows:


And I want to delineate the outline of the lake. I binarized the picture and obtained img:


tmp = img // ImageCrop[#, {900, 1200}, Bottom] & // DeleteBorderComponents // ComponentMeasurements[#, "ConvexVertices"] &
data = Range[913] /. tmp

With the coordinate data I can:

Flatten[#, 1] &[data] // Graphics[Point[#]] &

And it looks like this:


However, I don't know how to join them up to a closed shape, and there are too many points outside my assumed ``outline". Is there any way to solve my problem? Thank you!

Edit: To make it clearer, I draw this schematic diagram.


  • $\begingroup$ MinFilter[GradientFilter[image, 1], 8] // ImageAdjust $\endgroup$ Sep 28, 2015 at 18:27
  • 1
    $\begingroup$ Please draw a thick red line onto another image showing what do you understand by the "border" $\endgroup$ Sep 28, 2015 at 19:58
  • $\begingroup$ Since you obtain the map as satellite image from Google you can use Wikimapia API for obtaining the perimeter of the lake. Here I demonstrate how to do this on the example of highlighting the basement of the Eiffel Tower. $\endgroup$ Sep 29, 2015 at 9:57

4 Answers 4


Here is another method which utilizes the third argument of ComponentMeasurements.

At first we mark the key regions on the original image:

i = RemoveAlphaChannel@Import["https://i.stack.imgur.com/6RQTI.png"];
pointsOfInterest = {{516, 400}, {234, 231}, {426, 653}, {178, 489}};
Show[i, Epilog -> {Red, Disk[#, Offset[10]] & /@ pointsOfInterest}]

enter image description here

Then we select only components whose minimal bounding boxes include these points of interest:

m = MorphologicalComponents[
    Closing[EdgeDetect[ColorSeparate[ColorConvert[i, "LAB"]][[1]], 3, .010], 4]];
comps = ComponentMeasurements[m, "MinimalBoundingBox", 
   Or @@ RegionMember[Polygon[{#}]][pointsOfInterest] &];
iC = Colorize[m, ColorRules -> Append[Thread[comps[[;; , 1]] -> White], _ -> Black]];
Show[HighlightImage[i, MorphologicalPerimeter@iC], 
 Graphics[{Text[#1, Total[#2]/4, Background -> Yellow], FaceForm[], EdgeForm[LightYellow],
      Polygon[{#2}]} & @@@ comps], Graphics[{White, Line[{{180, 532}, {197, 541}}]}]]

enter image description here

Then we find the perimeter of the lake:

 MorphologicalPerimeter[FillingTransform@ColorNegate@Opening[ColorNegate@iC, 4]]]

enter image description here

The only problem with this solution is that the bridge is excluded from the perimeter. We can fix this manually:

        Epilog -> {White, Polygon[{{180, 532}, {195, 467}, {219, 473}, {201, 542}}]}], 
       "Image"], 4]]]

enter image description here

Now the result is almost perfect.

i = RemoveAlphaChannel@Import["https://i.stack.imgur.com/6RQTI.png"];
m = MorphologicalComponents[
   ColorNegate@Closing[EdgeDetect[ColorSeparate[ColorConvert[i, "LAB"]][[1]], 3], 4]];


Let us find 5 largest components:

Reverse[SortBy[ComponentMeasurements[m, "Count"], Last]][[;; 5]]
{3 -> 298285, 1 -> 34737, 7 -> 24297, 60 -> 7285, 32 -> 3610}

By trial an error we find that we need components 3 and 7:

iC = Colorize[m, ColorRules -> {3 -> Black, 7 -> Black, _ -> White}]


iF = FillingTransform@ColorNegate@Opening[iC, 4]


Finding the perimeter of the lake:

perimeter = MorphologicalPerimeter[iF]


Overlay on the original image:

ImageAdd[i, perimeter]


The result isn't perfect but can serve as a good start.


I'm not completely sure that this is what you're looking for, but Closing might be the function you're after. Example:

DeleteSmallComponents[ColorNegate[Closing[EdgeDetect[img], 3]]]

enter image description here


Just post a simple scheme:

img = Import["https://i.stack.imgur.com/6RQTI.png"]

Get the edge

enter image description here

Highlight it and finish this work.

HighlightImage[img, line]

enter image description here


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.