Home > OS >  Use OpenCV to identiy hollow and filled circles
Use OpenCV to identiy hollow and filled circles

Time:03-03

I'm using OpenCV houghcircles to identify all the circles (both hollow and filled). Follow is my code:

import numpy as np
import cv2

img = cv2.imread('images/32x32.png')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

bilateral = cv2.bilateralFilter(gray,10,50,50)

minDist = 30
param1 = 30
param2 = 50
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, 0, 255), 2)

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

Test input image 1: enter image description here

Test output image1: enter image description here

As you can see I'm able identity most of the circles except for few. What am I missing here? I've tried varying the parameters but this is the best i could get.

Also, if I use even more compact circles the script does not identify any circles whatsoever.

enter image description here

CodePudding user response:

An alternative idea is to use find contour method and chek whether the contour is a circle using appox as below.

import cv2

img = cv2.imread('32x32.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

inputImageCopy = img.copy()

# Find the circle blobs on the binary mask:
contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Use a list to store the center and radius of the target circles:
detectedCircles = []

# Look for the outer contours:
for i, c in enumerate(contours):

    # Approximate the contour to a circle:
    (x, y), radius = cv2.minEnclosingCircle(c)

    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02 * peri, True)
    
    if len(approx)>5: # check if the contour is circle
        
        # Compute the center and radius:
        center = (int(x), int(y))
        radius = int(radius)

        # Draw the circles:
        cv2.circle(inputImageCopy, center, radius, (0, 0, 255), 2)

        # Store the center and radius:
        detectedCircles.append([center, radius])

cv2.imshow("Circles", inputImageCopy)
cv2.waitKey(0)
cv2.destroyAllWindows()

enter image description here

enter image description here

  • Related