How to estimate the area and volume of the dam reservoir from the satellite image?

Hello all dear, I have the satellite image of Canton dam reservoir and I want to get its volume and area.

The actual specifications of the dam reservoir: volume=0.472km^3 & Surface area=32.01km^2

I did the following command to estimate the area, but the result was not acceptable and the unit is not clear. Please guide me to estimate the area and volume. Thank you

First, I manually obtained the shape below from the Mask Tool command.

imge =(image);

img = Binarize@imge~Erosion~1;
(m = MorphologicalComponents[img]) // Colorize

linecount = 
  3 /. (Binarize@imge // ColorNegate // Thinning // 
     ComponentMeasurements[#, "PerimeterCount"] &);
areacount = 
  2 /. ComponentMeasurements[MorphologicalComponents[img], "Count"];
areacount/linecount^2 // N

out put is : 0.111111

Your code amounts to this:

linecount = 3 /. {1 -> 587, 2 -> 76}
areacount = 2 /. {1 -> 11150, 2 -> 1, 3 -> 187734}

which does not make much sense to me.

There is no easy way to do this - especially if the dam is an obscure one, or one that Wolfram doesn’t have much data about. Why? Well we’d have to know a lot of entry points - such as, the outflow of the river, the height of the dam, the length of the dam etc. For much larger/well known dams, it is possible for us to get data relatively easily using the Dam Entity.

Here is what it might look like if you want to find the area and volume of dams on a particular (well-known) river.

DamsOn[River_] := 
 EntityClass["Dam", "River" -> SemanticInterpretation[River]] // EntityList
AssortDamsOn[River_] := 
ReverseSortBy[Table[{i, DamData[i, "Volume"]}, {i,DamsOn[River]}], Last]

Alternatively, if you want the volume of all of the tributaries as well

mississippiRiver = 
 EntityClass["River", 
   "Outflow" -> Entity["River", "MississippiRiver::mnr4z"]] // EntityList;
    
DamsMississippi = 
     FilteredEntityClass["Dam", 
       EntityFunction[
        y, ! MissingQ[y["Position"]] && 
         ContainsAny[y["River"], 
          Append[mississippiRiver, 
           Entity["River", "MississippiRiver::mnr4z"]]]]] // EntityList;

And we can create a beautiful graph of it using

GeoRegionValuePlot[EntityValue[DamsMississippi, "Volume", "EntityAssociation"], 
         AspectRatio -> 1, MissingStyle -> Transparent, 
         GeoBackground -> "Satellite"]

You also might want to look into CNNs for this sort of stuff. There are two excellent blog posts on predicting the scale of a satellite image - [WSC19] Fitting the World: Physical Scale from Satellite Images and https://community.wolfram.com/web/community/groups/-/m/t/1379645

Thank you, I think the area can be found by relating the pixels of the image and the scale, for the volume, the bathymetry image may be useful. But I’m not sure

If I had to do it, I would do this:

GeoGraphics[GeoRange -> {{36.05, 36.17}, {-98.7, -98.52}}, 
 GeoRangePadding -> Scaled[0.1], GeoBackground -> "Satellite"]

then, trace the contour of the dam with the “get coordinates” tool, and then use GeoArea:

damContour = {{36.14216500804076`, -98.66601000992658`},
   {36.15131161335255`, -98.6549477815357`},
   {36.1501032100147`, -98.62214348441108`},
   {36.15000037203102`, -98.60908533742007`},
   {36.13193732747872`, -98.58352140011719`},
   {36.10128112030604`, -98.57004960135653`},
   {36.08009879008038`, -98.6043835918035`},
   {36.1172565230945`, -98.61315564049649`},
   {36.12831708030723`, -98.62663775701455`},
   {36.13202116684048`, -98.64507269213401`},
   {36.13870030579935`, -98.6454368865287`},
   {36.13708633726377`, -98.6568745786338`}};
GeoGraphics[{White, Thick, Line[GeoPosition[damContour]]}, 
 GeoRange -> {{36.05, 36.17}, {-98.7, -98.52}}, 
 GeoRangePadding -> Scaled[0.1], GeoBackground -> "Satellite"]
GeoArea[Polygon[GeoPosition[damContour]]]

Great solution. I wonder if there’s any way to recognise the dam automatically without manually using track-coordinates

Thanks, this is better. Can I get information from Mathematica about bathymetry to find depth and look for volume?

I have found a solution

gcarc = GeoPath[Table[i, {i, damContour}], "Geodesic"]
gcarcDistance = 
 GeoDistance[Table[i, {i, damContour}], UnitSystem -> "Metric"]
   profile = 
    GeoElevationData[gcarc, Automatic, "GeoPosition", GeoZoomLevel -> 4]
       pts = profile[[1]][[1]]
        depths = #[[3]] & /@ pts
        distances = 
         QuantityMagnitude[
            GeoDistance[{pts[[1]][[1 ;; 2]], #[[1 ;; 2]]}, 
             UnitSystem -> "Metric"]] & /@ pts
                avg = Mean[depths]
            pts = Transpose[{distances, depths}]
            p1 = ListLinePlot[pts]

Modified from https://sites.psu.edu/charlesammon/2017/03/22/manipulating-elevationbathymetry-profiles-with-mathematica/

Thanks for your efforts Navvye, is it possible to combined with (Gianluca command) and get the volume?

Just multiply the area with the depth.

The entire code is uploaded as a nb

Thank you Navvye for share note book, but Volume of reservoir is 0.472km^3

I realised that! Well at least the area is somewhat accurate. I’ll try to improve the depth mechanism in sometime