1

I want to detect urban green areas in Google Earth imagery, using R. I've already downloaded contiguous images and assembled them into a larger image.

city map (satellite image) in Google Earth

The above PNG image has 800x769 pixels, but the original has 6400x6150. When I open it in R, using png library (and readPNG function), I get a matrix with three layers, containing the red, green and blue channels (same as with Gimp).

I want to know if it's feasible to extract only the green areas (areas with native vegetation) - so that later I can transform them into shapefile polygons or raster masks. Note that some areas with native vegetation are more brown than green (savanna type vegetation), and a big green area on the northern half of the map correspond to a lake.

I know that's usually done with non-visible bands of satellite spectrum, but I want to know if I can do this with vanilla Google Earth.

  • 1
    This sounds more like a job for Google Earth Engine (earthengine.google.com), a powerful platform for remote sensing analysis, which includes large public imagery datasets (not super high spatial resolution like Google Earth & Maps imagery, but better temporal & spectral resolution), a direct connection to computing capacity in the cloud, and a scripting language for developing your analysis. Similar tree detection and green-ness analysis have used it before. Also, be careful about systematically extracting imagery from Google Earth, be sure to read the terms of service. – Christiaan Adams Sep 19 '19 at 14:36
2

Read your image in using raster::stack and then you can access each of the red, green, and blue bands.

I'm using a JPEG version of the file which is what StackOverflow gives me when I download your image, but a PNG should work the same way:

library(raster)
map = stack("SzpGP.jpg")

I can plot a full-colour image with plotRGB:

plotRGB(map)

enter image description here

To plot the green areas you need to think of a method based on the three bands that identifies the colour you are looking for. You can't just look at the green band being high, because if red and blue are equally high you've got a light grey colour.

Just as an example, lets look at pixels where green is bigger than red or blue:

plot((map[[2]]>map[[1]]) & (map[[2]] > map[[3]]))

enter image description here

which seems to catch most of the broadly dark green areas. You might want to refine the condition expression a bit. Depends on your application.

Note how the image is very speckly, which makes converting to vector shapefiles tricky.

You might want to look into classification learning methods - for example I think there's a plugin for QGIS that lets you click on a few locations that you can see are forest, click on some that are urban, and so on, and then it builds a classification scheme and partitions your map into forest/urban/etc - usually better than a simple condition like I've done above. But that's beyond this question now....

| improve this answer | |
  • That seem to work very well, with a few exceptions, like the big lake, which is also green. I wonder if using the ruggedness (contrast between neighboring pixels) may solve this, even if I need a loop for that. Another solution I've found is to use a formula similar to NDVI, with green instead of near-infrared. The problem with Google Earth imagery are the shadows, though, they become almost black and fool the algorithm into thinking they're green. – Rodrigo Sep 17 '19 at 15:22
  • You'll have to figure out what differentiates the green of the lake from the green of vegetation and add that to the condition. If you want to go beyond simple band-based conditions into full-blown supervised learning then you should probably consult a reference book on remote sensing! – Spacedman Sep 17 '19 at 18:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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