Reputation: 347
I have a program that outputs an image (Bitmap) such as the one below, with some "filled" circles (left), some "unfilled" circles that will have "wings" (lower right), and some "incomplete and unfilled" circles with "wings" (upper right).
These circles are of varying size (though similar), and may have any number of wings. What I want to do is determine how many circles there are. So, for the example image, I need to the program to count 11 circles (the number of wings are irrelevant). I know the coordinates of all the black points (not to be confused with black circles, because a circle contains many black points). What I do not know is how to tell the computer to put the "close" ones together as just 1 circle.
A couple of notes : As mentioned, the circles will be very similar in size, but not the same, so I can't use diameter. Also, as you can see, some of the circles may be incomplete, so that might be an issue. The image will always be in black and white, and finally, there will always be white space between circles (I'm not sure if those 2 things can simplify the process)
I have seen a few brute force methods of looping through the bitmap and comparing how many black points there are within say 5 spaces of point (x,y), but that takes much too long, and doesn't always output correctly.
Is there any easy way to do this (in C#)?
Thanks in advance!!!
Upvotes: 1
Views: 630
Reputation: 1038
I'm not sure how to deal with the incomplete circles, but I do see a way to reduce the problem size.
The complete circles should be fairly easy to identify by taking each cluster of points, and starting in the center of the cluster and walking first left, then right, until an edge or wing is reached. Wings should be detectable by checking a few points in either direction for empty space.
Once you reach the edge, check the adjacent points, and follow the edge if necessary to find the vertical tangent on that side. You can then use the two opposing tangent points to define a circle and check the points in the cluster to see if they match.
Once identified, remove that cluster of points from the bitmap, increment the count, and move on. Once you've removed all easily identified clusters, crop the bitmap so the search space is smaller.
Upvotes: 1