Reputation: 455
I am using OpenCV to detect ellipses in a binary image as shown below. In the image, there are eight ellipses to be detected. I can use findContours to obtain a lot of contours including the eight ellipses. The problem is: how can I judge and which one is ellipse which one is not? How to remove all the other false detections?
Upvotes: 7
Views: 4353
Reputation: 6005
Although another answer has been previously accepted, there are several options to be explored, so I'll add another answer. Assuming that a Hough method is fast enough for your application, here are some interesting alternatives:
I might also add that Hough is likely to be the "right" way to proceed in reliably detecting ellipses, but you may run into additional challenges. You indicate that Hough circles is fast enough on your desktop, but how well does the performance of the desktop match that embedded system? Does the embedded system have a floating point unit? If not, don't be too alarmed by the performance exhibited by software-emulated floating point. You may still be able to implement the Hough algorithm satisfactorily using fixed-point math, lookup-tables, etc.
Upvotes: 1
Reputation: 455
Now I think I have successfully solve the problem using my own algo. Just post it for future reference.
As shown below, all the ellipses can be accurately located. And false detections are successfully removed. On the other hand, the algo is very time efficient: 0.03s for all image processing on my normal desktop. Image size: 448x336 pixel
Procedure of the algo:
EDIT: Comments on George Profenza and karlphillip's answers. Thank George Profenza and karlphillip for their answers. However, their answers can not solve the problem well. The first idea given by George Profenza is to set threshold for the size of the contours. In fact, I have used that in my algo. But obviously that is an preliminary step of the algo. There are many false detections of "good" size. The second idea of George Profenza is to use HoughCircles, which is also proposed by karlphillip. The problem of HoughCircles is: (a) it is slow, while I need to implement the algo in real time in embedded systems. (b) it can only detect circles but not ellipses. Of course, when the ellipse is close to a circle, it also works. But for general cases, it doesn't. Moreover, my method above cannot detect the "figure 8". It is a big problem and I am still working on it.
Upvotes: 1
Reputation: 93468
In this specific case, the Hough Circle Transform is probably the easiest solution.
Copy the code from the tutorial and change the parameters of cv::HoughCircles()
to:
/// Apply the Hough Transform to find the circles
HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 1, 10, 40, 30, 0, 0 );
Output:
But I loved @George's idea, go with it, it's more robust than specifying hardcoded constants. My approach works great for this image, but if you have images with different sizes of circles and stuff, you want to use cv::minEnclosingCircle()
.
Upvotes: 8
Reputation: 51867
One option is a bit hacky: On top of findContours use minEnclosingCircle and filter contours by min. enclosing radius based on a threshold value (remove smaller than radius A (remove tiny blobs) and greater than radius B( remove huge blobs)). You can also try minAreaRect and check width/height ratio to look for uniform blobs rather than tall/wide ones.
The less hacky solution is to use Hough transforms. Have a look at the hough circle and the tutorial
Upvotes: 7