I am trying to detect full circles and semicircles in an image.
I am following the below mentioned procedure : Process image (including Canny edge detection) Find contours and draw them on an empty image, so that I can eliminate unwanted components. (The processed image is exactly what I want.) Detect circles using HoughCircles. And this is what I get.
I tried varying the parameters in HoughCircles but the results are not consistent as it varies based on lighting and the position of circles in image. I accept or reject a circle based on it's size. So the result is not acceptable. Also I have a long list of "acceptable" circles so I need some allowance in the HoughCircle params. As for the full circles, it's easy - I can simply find the "roundness" of the contour. The problem is semi-circles!
Please find the edited image before hough transform
I know that it's little bit late, but I used different approach which is much easier. From the
cv2.HoughCircles(...)
you get centre of the circle and the diameter (x,y,r). So I simply go through all centre points of the circles and I check if they are further away from the edge of the image than their diameter.Here is my code:
The semicircle detected by the hough algorithm is most probably correct. The issue here might be that unless you strictly control the geometry of the scene, i.e. exact position of the camera relative to the target, so that the image axis is normal to the target plane, you will get ellipsis rather than circles projected on the image plane. Not to mention the distortions caused by the optical system, which further degenerate the geometric figure. If you rely on precision here, I would recommend camera calibration.
Here is another way to do it, a simple RANSAC version (much optimization to be done to improve speed), that works on the Edge Image.
the method loops these steps until it is cancelled
if a circle is verified, remove the circle from input/egdes
input:
output:
console output:
optimization should include:
use all inlier to fit a better circle
dont compute distance transform after each detected circles (it's quite expensive). compute inlier from point/edge set directly and remove the inlier edges from that list.
if there are many small circles in the image (and/or a lot of noise), it's unlikely to hit randomly 3 edge pixels or a circle. => try contour detection first and detect circles for each contour. after that try to detect all "other" circles left in the image.
a lot of other stuff
You better try with different kernel for gaussian blur.That will help you
so change
size(i,i),j,j)
Use
houghCircle
directly on your image, don't extract edges first. Then test for each detected circle, how much percentage is really present in the image:For this input:
It gives this output:
The red circles are Hough results.
The green sampled dots on the circle are inliers.
The blue dots are outliers.
Console output:
If you want to test RANSAC instead of Hough, have a look at this.