Search code examples
pythonopencvimage-processinghough-transform

How to manipulate hough circles to detect all circles in the given image using python?


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

import copy

image = cv2.imread('C:/Users/Deepak Padhi/Desktop/download.png')

#cv2.imshow('Filtered_original',image)

image = cv2.GaussianBlur(image,(5,5),0)

orig_image = np.copy(image)
gray= image[:,:,1]
output=gray.copy()
##cv2.imshow("gray", gray)
##cv2.waitKey(0)

circles=cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 3, 4.0)

circles = np.uint16(np.around(circles))
for i in circles[0,:]:
    # draw the outer circle
    cv2.circle(output,(i[0],i[1]),i[2],(0,255,0),2)
    # draw the center of the circle
    cv2.circle(output,(i[0],i[1]),2,(0,0,255),3)
cv2.imshow('detected circles',output)

This is the code I used to try and detect all circles in the given image: Image of circles

Which parameter and how should I manipulate to detect the smaller as well as the larger circles? I had tried minRadius and maxRadius to possible values as per both circles, but it didn't work, so I let it reset to default.

It feels like the canny edge detector is actually detecting the smaller circles with the default arguments(100,100), as attached canny detection

I took the Green plane of the given image:Original Image


Solution

  • I would recommend you to first read the docs.

    If you just change the param1 and param2 which are thresholds for the Canny edge detector, the cv2.HoughCircles works fine.

    Here the code:

    import cv2
    import numpy as np
    
    image = cv2.imread('circles.png')
    
    image = cv2.GaussianBlur(image, (5, 5), 0)
    
    orig_image = np.copy(image)
    gray = image[:, :, 1]
    output = gray.copy()
    
    circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=20, 
                               minRadius=0, maxRadius=0)
    
    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
        # draw the outer circle
        cv2.circle(output, (i[0], i[1]), i[2], (0, 255, 0), 2)
        # draw the center of the circle
        cv2.circle(output, (i[0], i[1]), 2, (0, 0, 255), 3)
    cv2.imwrite('detected circles.png', output)
    

    Result