1

I have a problem. I have several pictures like this (.bmp files):

1:

one

2:

two

3:

three

4:

four

5:

enter image description here

And I would like to recognize how many circular shapes is on the picture. For example:

1st picture: program should return 1

2nd picture: program should return 2

3rd picture: program should return 5

4th picture: program should return 6

5th picture: program should return 8

Do you have any ideas? I would like to write my code in C# or Java (if you have any libraries).

I thought about looking for this tight areas between circular shapes, but I have no idea how to do this..,

Community
  • 1
  • 1
CookieMonssster
  • 658
  • 1
  • 6
  • 19
  • See my answer... look at the openCV example in their docs (linked in my answer). Circles.size() will give the number of circles. I don't imagine the overlaps will be a problem if you tweak the parameters. I might run a test on your images.. – foundry Jan 10 '13 at 01:34
  • 1
    Please edit your question's title to indicate that you want to count overlapping circles described in a binary image. For those that closed this question as "not real", be assured that is a very real question, it is not ambiguous, not overly board, etc. – mmgp Jan 16 '13 at 15:01

3 Answers3

3

So your question is not about actually recognizing circles, but about splitting overlapping circles. This is solved by using the distance transform followed by simple thresholding. Simple as that. The only step left is then counting the number of connected components.

For instance, here is the Matlab code:

f = yourimage;
dist = bwdist(f);
result = dist > (max(max(dist)))/1.5;

And here are the results for your images 1, 3, and 5:

enter image description here enter image description here enter image description here

mmgp
  • 18,901
  • 3
  • 53
  • 80
  • For C# in specific, Emgu (opencv wrapper) provides a distance transform function if you don't have one handy. First search engine hit: http://www.emgu.com/wiki/files/1.4.0.0/html/a2e0c025-f045-4f4f-ff6f-64dc12d229be.htm – mmgp Jan 10 '13 at 01:41
  • It looks nice and it is exackly what I need, but maybe do you know where I can find openSource code, because I would like to know how it works? – CookieMonssster Jan 10 '13 at 15:28
  • Searching for "Distance Transform" in any good search engine will provide a lot of such results. – mmgp Jan 10 '13 at 15:32
1

You could use the openCV library. The standard interface is C++ but a Java interface is available.

Here is a relevant openCV0-related SO answer, i am sure you can find many more...

houghcircles-parameters-to-recognise-balls

update

For some reason this answer has been downvoted, I have no idea why.

Here is a tutorial on the openCV site

Here is the openCV documentation

And here is a little video on YouTube

Community
  • 1
  • 1
foundry
  • 31,615
  • 9
  • 90
  • 125
  • But I dont need to find circle in whole picture. I need to share black object for several circural shapes and I think that is much harder ;/ – CookieMonssster Jan 10 '13 at 01:18
  • Then your question is not clear, my answer did not deserve a vote-down, it is correct as I read your question. I am really not clear now what you are asking, please revise the question. – foundry Jan 10 '13 at 01:21
  • It is not my vote-down. I'm sorry for that. – CookieMonssster Jan 10 '13 at 01:23
  • It seems to me that you want to count the number of circles ("how many circular shapes is on the picture"). To do that you need to recognise them first. OpenCV is a good tool to do that. Please explain if this is not the question – foundry Jan 10 '13 at 01:24
  • Or... do you want to recognise if you find the _same_ combination of circles in _different_ images...? Like that one in 4 and 5? – foundry Jan 10 '13 at 01:25
  • I gave you examples in my question. I hope that it is clear now. – CookieMonssster Jan 10 '13 at 01:29
1

The challenge of this problem is that the circular regions touch. However, an easy way to address this in your case would be to erode these images by a large number of single pixel steps. Check out this page on wikipedia:

http://en.wikipedia.org/wiki/Erosion_(morphology)

If you work with MATLAB, there is a function called bwmorph which will do this for you, and bwlabel to eventually find out how many objects you have here.

Perhaps you are able to erode these images with your own custom code. In this case, you can erode until you are left with a single pixel per object.

s.bandara
  • 5,636
  • 1
  • 21
  • 36
  • Erosion is not a good candidate per se here, except if you can estimate arbitrary angled lines to use as structuring element. This is much harder than using the correct approach: distance transform. – mmgp Jan 10 '13 at 01:35
  • Distance transform is also a great idea, but erosion would work as well here, with a single pixel per step (no particular structuring elements used). "correct" is funny anyways as there are many more ways to solve this particular problem. – s.bandara Jan 10 '13 at 01:37
  • Erosion requires a structuring element, so what do you mean more clearly ? It is getting closer to watershed and/or skeleton than erosion, I believe. – mmgp Jan 10 '13 at 01:39
  • What I'm talking about is plain erosion taking away pixels at the boundary (not using `imerode`, but `bwmorph` if you are a MATLAB person), It's like skeletonization in MATLAB but not leaving lines intact. – s.bandara Jan 10 '13 at 01:41
  • `bwmorph` with `erode` as parameter is simply an erosion with the elementary square SE. So it is using a SE, it doesn't work other way. I'm not a Matlab person in any way, by the way. The definition of erosion requires a SE, you can't change that. – mmgp Jan 10 '13 at 01:42
  • That's correct. Will do in this case. But distance transform is a neat idea as well. – s.bandara Jan 10 '13 at 01:43