3

I am trying to find the differently shaped rocks in this image.

image
(source: nasa.gov)

I didn't get any satisfactory results from edge detection.

enter image description here

I did read about grabcut but again nothing satisfactory from that either. Any ideas on how I should proceed?

PS - My ultimate goal is to mark these rocks in the image with a different color.

UPDATE 1: Here is the code that I used for edge detection.

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('image1.JPG',0)
edges = cv2.Canny(img,255,255)

plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])

plt.show()

UPDATE 2: I have a couple of similar images like the one below in which the rocks (big in size) are clearly visible. Edge detection is again producing unsatisfactory results on the image. I am just looking for approaches which I can try. If you suggest an approach then please add the relevant links where I can read up more, I am new to opencv.


(source: nasa.gov)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
  • I suggest you post some sample code as to what you have done so far. That way people can suggest edits. – Nithish Jan 28 '16 at 06:34
  • I updated the question with the code. –  Jan 28 '16 at 06:39
  • Its pretty hard detect all the rocks from a background where the colour difference is not that much . and the lightning are totally different . But If you assume that the rocks will be bit darker than the background then you could threshold the image then apply contour detection and detect the contours in the threshold image – Arijit Jan 28 '16 at 08:22
  • that is a mess ... I would first detect/remove blackish areas looks like they all are rocks. then apply some [Enhancing dynamic range and normalizing illumination](http://stackoverflow.com/a/31558803/2521214) but use at least bi-cubic interpolation and made sure you are selecting backgroun pixels for it so you can eliminate the sunspots which are messing all up. then try edge detection or segmentation based on area homogenity. Both of these last two steps are a lot of work to code ... – Spektre Jan 28 '16 at 08:22
  • 2
    can you create another image with manually marked rocks? For me it isn't 100% which image parts are rocks and which aren't. Don't expect to achieve an algorithm being able to detect all rocks in such kind of images, I think it's nearly impossible. Maybe different kind of sensors would be better (maybe infrared cameras, stereo cameras, laser scanners, etc.) but not sure. – Micka Jan 28 '16 at 08:37
  • It seems too hard to detect rocks on these type of images . Its not even clear what are the original positives(rocks) in the image – Arijit Jan 28 '16 at 08:40
  • I have added another image as well as an update. Thank you guys for the inputs. –  Jan 28 '16 at 09:32
  • Do you have this image in color? – Øystein W. Jan 28 '16 at 09:51
  • 1
    No, I don't have the images in color. –  Jan 28 '16 at 11:06
  • Just expressing an idea... maybe it is easier to detect the sand (mostly regular areas)? And the result of the edge detection gives actually a good idea of where the rocks are (I mean, looking at the original picture doesn't make it a lot clearer for me). Personally, I would work on some pre-filtering before the edge detection and then close the paths (don't know how) to fill them with the different color. – Puck Jan 28 '16 at 11:28

2 Answers2

2

The rocks are segments of the image that are more plain than the sand pieces. You could try to get each line of the file, divide it in small segments, and compute the Kurtosis of the segment.

The Kurtosis is a measure of the "height" and "width" of the bell-curve of frequencies of values in the segment. Sand will have significantly lower Kurtosis than the Rocks, since it has a "broader" spectrum of frequencies. Segments with high Kurtosis will likely belong to rocks.

So it will be a matter of determining the ideal length of the segments that each line of the image will have to be divided into. Not a trivial task, but not a hard one either. Half the width of the smallest rock you want to identify (but at least 100 times the width of a grain of sand) should do the trick.

0

From a 2- d picture ... Really challenging. I bet using 2 pictures with an offset is how it can be done much easier processed as a stereoscopic image. Lagging that, I would suggest following strategies:

  1. Preprocessing to filter out noise outliers - median
  2. Maybe use a 2-d band pass filter to sort out rocks of a certain caliber.
  3. Use the edge detection you did - seems to have done an excellent job.
  4. Use algorithms that can identify clusters out of your vertices
  5. Combine points or vertices in your cluster using convex hull or voronoi.

That being said, I doubt that this forum is suitable to seek an answer to your question, as it is very hard to provide a straight forward answer using coding.

YoYo
  • 9,157
  • 8
  • 57
  • 74