0

I have created a black and white mask using various OpenCV filters. There are four circles that are clearly visible black and white mask

I am trying to outline these circles using HoughCircles, but it gives many false positives and generally bad results:

circles = cv2.HoughCircles(combined, cv.CV_HOUGH_GRADIENT, 1, 300, np.array([]), 10, 30, 60, 300)

circle outlines

How can I properly detect the circular shapes in the black and white image?

Here is runnable code that can be used with the black and white image:

import numpy as np
import cv2
import cv

image = cv2.imread("image.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

circles = cv2.HoughCircles(gray, cv.CV_HOUGH_GRADIENT, 1, 300, np.array([]), 10, 30, 60, 300)
if circles is not None:
  circles = np.uint16(np.around(circles))
  for i in circles[0,:]:
      cv2.circle(image, (i[0], i[1]), i[2], (0, 255, 0), 1)
      cv2.circle(image, (i[0], i[1]), 2, (0, 0, 255), 3)

cv2.imshow("thing", image)

cv2.waitKey(0)
cv2.destroyAllWindows()
Jacob Brunson
  • 1,482
  • 4
  • 23
  • 37

1 Answers1

1

First of all, if I'm not mistaken, Hough Transform for circles expects a hollow circle, not a full one. This means you need to extract only the boundary/perimeter of the circles before applying the Hough Transform. OpenCV's findContours and arcLength functions will help you find the perimeters.

Second of all, unfortunately, in my experience Hough Transform is very sensitive to variations of the circle shape, meaning that if the shape you're trying to detect is "almost" a circle, it might not be able to detect it.

My advice is you should try to make your objects "rounder" by applying the Closing morphological operation on your binary image, with a disk-shaped structuring element. Then extract the perimeter of the objects in the image, and only then apply the Hough Transform. Hopefully, this will give you good enough results.


Alternatively, you can try to detect circles using the RANSAC algorithm. Here is an implementation for detecting lines, but you can adjust it for circles - just choose 3 points randomly (instead of 2), and define a circle that goes through them. Next, find all the points that lie near that circle (those are called the inlier points). These will be the points that satisfy the inequality: enter image description here

where (x,y) is the point, (x0,y0) is the center of the circle, r is its radius, and margin is a parameter you'll have to tune. The rest of the algorithm is the same.

Good luck!

Shaked
  • 475
  • 1
  • 3
  • 12