'Choosing parameters for HOUGH_GRADIENT_ALT

I am trying to solve this problems for hours already, and similar issues on StackOverflow did not help me.

Imagine I have this image (in reality it is a more complicated image but I'll stay with a simple example for now):

enter image description here

I do the following for the HOUGH_GRADIENT:

import cv2
import numpy as np
img = cv2.cvtColor(cv2.imread("example.png"), cv2.COLOR_BGR2GRAY)
img_blur = cv2.GaussianBlur(img, (9, 9), 1.5)
edges = cv2.Canny(img_blur, threshold1=50, threshold2=250)
circles = cv2.HoughCircles(
    edges, cv2.HOUGH_GRADIENT, 1.5, 20, 
    minRadius=10, maxRadius=100, param1=100, param2=100
)
img_cp = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
if circles is not None:
    circles = np.round(circles[0, :]).astype("int")
    for (x, y, r) in circles:
        cv2.circle(img_cp, (x, y), r, (0, 255, 0), 4)

This works without any problems and detects the inner circles just as I want:

enter image description here

I was trying to use HOUGH_GRADIENT_ALT instead as the OpenCV repo claims it to work better. From what I understand, most function call arguments should have the same meaning instead of param1 and param2.

So, I try:

circles = cv2.HoughCircles(
edges, cv2.HOUGH_GRADIENT_ALT, 1.5, 20, 
minRadius=10, maxRadius=100, param1=300, param2=0.9

)

And I get nothing. I have tried many different parameters but to no result. Not only I do not understand how to fix it but also I do not understand why it would not work. Any help would be very appreciated.

OpenCV version 4.5.5.



Solution 1:[1]

I solved problem. Try this: Edit: we cannot used this cv2.HOUGH_GRADIENT_ALT

#!/usr/bin/python39
#OpenCV 4.5.5 Raspberry Pi 3/B/4B-w/4/8GB RAM, Bullseye,v11.
#Date: 10th May, 2022

import numpy as np
import cv2

img = cv2.imread('circle.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
bilateral = cv2.bilateralFilter(gray,10,50,50)

minDist = 30
param1 = 30
param2 = 30
minRadius = 5
maxRadius = 100

circles = cv2.HoughCircles(bilateral, cv2.HOUGH_GRADIENT, 1, minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)

if circles is not None:
    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
        cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 4)

cv2.imwrite('inner_circle.png', img)
# Show result for testing:
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Output:

enter image description here

Edit: we can cv2.HOUGH_GRADINT_ALT And used snipped from @Valeria.

import numpy as np
import cv2


img = cv2.imread('circle.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
bilateral = cv2.bilateralFilter(gray,10,50,50)       

#circles = cv2.HoughCircles(bilateral, cv2.HOUGH_GRADIENT_ALT, 1, minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)
circles = cv2.HoughCircles(bilateral,
                           cv2.HOUGH_GRADIENT_ALT,
                           1.5, 20,
                           minRadius=10, maxRadius=100,
                           param1=300, param2=0.9)

if circles is not None:
    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
        cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 4)

cv2.imwrite('inner_circle1.png', img)
# Show result for testing:
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Output:

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1