Jeanne Chaverot
Jeanne Chaverot

Reputation: 157

OpenCV Hough Circle Transform doesn't detect most circles

I am trying to detect as many circles in my images using the following code:


maxRadius = int(1.2*(width/16)/2)
minRadius = int(0.9*(width/16)/2)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
circles = cv.HoughCircles(image=gray, 
                               method=cv.HOUGH_GRADIENT, 
                               dp=1.2, 
                               minDist=2*minRadius,
                               param1=70,
                               param2=0.9,
                               minRadius=minRadius,
                               maxRadius=maxRadius                           
                          )

Although it does work for some of the images there are a few exceptions for which it doesn't.

Below we can see that for two different images that represent the same kind of experiment, my algorithm yields very different results.

How can I fix this? Should I apply some sort of filter on the images first to enhance the contrast?

enter image description here

enter image description here

EDIT: added original image:

enter image description here

Upvotes: 1

Views: 1026

Answers (1)

Knight Forked
Knight Forked

Reputation: 1619

This solution may or may not work on other images but it does work on the one you posted. You might want to work on that "sweet spot" apropos the adaptiveThreshold and HoughCricles parameters so that it works with other images as well.

import numpy as np
import cv2
import matplotlib.pyplot as plt

rgb = cv2.imread('/path/to/your/image/cells_0001.jpeg')
gray = cv2.cvtColor(rgb, cv2.COLOR_BGR2GRAY)
imh, imw = gray.shape

th = cv2.adaptiveThreshold(gray,255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY_INV,11,2)

maxRadius = int(1.2*(imw/16)/2)
minRadius = int(0.9*(imw/16)/2)
circles = cv2.HoughCircles(image=th, 
                               method=cv2.HOUGH_GRADIENT, 
                               dp=1.2, 
                               minDist=2*minRadius,
                               param1=70,
                               param2=25,
                               minRadius=minRadius,
                               maxRadius=maxRadius                           
                          )

out_img = rgb.copy()
for (x, y, r) in circles[0]:
    # draw the circle in the output image
    cv2.circle(out_img, (x, y), int(r), (0, 255, 0), 1)

plt.imshow(out_img)

Upvotes: 2

Related Questions