Advice on techniques for recognising land/sea mass in google maps
I am looking to develop some code that will be able to by looking at images downloaded from google maps, categorize which part of the image depicts the land and which part depicts the sea.
I am a bit of a newbie 开发者_StackOverflow社区to computer vision and machine learning so I am looking for a few pointers on specific techniques or API's that may be useful (I am not looking for the code to this solution).
What I have some up with so far:
- Edge detection may not be much help (on its own). Although it gives quite a nice outline of the coast, artefacts on the surface/above the sea may give false positives for land mass (stuff like clouds, ships, etc).
- Extracting the blue colour element of an image may give a very good indication of which is sea or not (as obviously, the sea has a much higher level of blue saturation than the land)
Any help is of course, greatly appreciated.
EDIT (for anyone who may want to do something similar):
- Use the static google maps API to fetch map images (not satellite photos, these have too much noise/artefacts to be precise). Example url- http://maps.google.com/maps/api/staticmap?sensor=false&size=1000x1000¢er=dover&zoom=12&style=feature:all|element:labels|visibility:off&style=feature:road|element:all|visibility:off
- To generate my threshold images I used the Image processing lab. I would apply the normalized RGB -> extract blue channel filter and then apply Binarization -> otsu threshold. This has produced extremley useful images without the need to fiddle with thresholds values (the algorithm is very clever so I won't muddy the waters and attempt to explain it)
I assume you are using the satellite view images from Google Maps otherwise you wouldn't have written about ships or other artefacts.
As you already said it might be a good idea to simply try to extract the blue image part. Just having a look at the blue channel of an RGB image isn't going to work (I just tried), since the woods and so on will not give a good threshold value on the water.
So you can try converting the image to YCbCr color space and have a look at the chrominance channels there.
This an example I just made with a screenshot from google maps. I converted it to YCbCr in Matlab and just took the Cb channel.
You can then binarize this image by a well set threshold, which shouldnt be too hard to find. You probably will still have small artefacts for which you could use morphological operators (Opening the image several times). This should remove small artefacts and leave the parts that are land and the parts that are water.
Hope it helps... if not, please keep asking...
EDIT
I've just tried again with another screenshot in matlab:
- Convert Image to YCbCr colorspace
- Just have a look at Cb channel
- find threshold on Cb image either fixed or by i.e. Otsu's method which finds an appropriate thresholdl in a bipartite histogram
- perform opening or other filters to eliminate small noises
The original image I made:
After applying a threshold on the Cb image:
After applying an opening (5) on the image
I just picked a threshold manually... You might get better results by having a look which threshold would work better... But as you see this should also work on the different colors of water from rivers and ocean.
You are looking for a segmentation algorithm, that assigns each pixel to one of two classes (land, sea). One of the simplest approaches is to use thresholding.
- define a threshold
t
- if
pixel value
> t -> assign pixel to land - else assign pixel to sea (usually you will have a bitmap, where you keep track of the pixel class)
Since this approach works best if you can distinguish land and sea masses easily, I would suggest that you compare the hue value of the pixels (i. e. find a threshold between blue and green).
精彩评论