10
$\begingroup$

I have a picture of a lake as follows:

lake

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

bin

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:

fin

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.

schematic

$\endgroup$
3
  • $\begingroup$ MinFilter[GradientFilter[image, 1], 8] // ImageAdjust $\endgroup$ Commented 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$ Commented 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$ Commented Sep 29, 2015 at 9:57

4 Answers 4

6
$\begingroup$

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.sstatic.net/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[
   ColorNegate@
    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:

HighlightImage[i, 
 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:

HighlightImage[i, 
 MorphologicalPerimeter[
  FillingTransform@
   ColorNegate@
    Opening[ColorNegate@
      Rasterize[Show[iC, 
        Epilog -> {White, Polygon[{{180, 532}, {195, 467}, {219, 473}, {201, 542}}]}], 
       "Image"], 4]]]

enter image description here

Now the result is almost perfect.

$\endgroup$
8
$\begingroup$
i = RemoveAlphaChannel@Import["https://i.sstatic.net/6RQTI.png"];
m = MorphologicalComponents[
   ColorNegate@Closing[EdgeDetect[ColorSeparate[ColorConvert[i, "LAB"]][[1]], 3], 4]];
Colorize[m]

image

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}]

image

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

image

Finding the perimeter of the lake:

perimeter = MorphologicalPerimeter[iF]

image

Overlay on the original image:

ImageAdd[i, perimeter]

image

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

$\endgroup$
7
$\begingroup$

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

$\endgroup$
0
1
$\begingroup$

Just post a simple scheme:

img = Import["https://i.sstatic.net/6RQTI.png"]

Get the edge

enter image description here

Highlight it and finish this work.

HighlightImage[img, line]

enter image description here

$\endgroup$

Your Answer

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

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