Search code examples
pythonopencvgeometrydetectionhough-transform

Python OpenCV: Getting Stats out of Hough Circle Detection


A fellow student and I are working on a coin counter via image processing. We used two methods to recognize the coins as circles. On the one hand Connected Components with Stats and on the other Hough Transformation. The advantage of CC w/ Stats is the direct output of all important parameters (e.g. pixel area). However, CC has w/stats weaken with touching coins in the image (center of the coin is not recognized correctly). Hough Transformation doesn't have this problem and easily detects every circle correctly. However, we have no idea how to use the data of the detected objects here. So is there a way to get the data out with another function or is there even a way to generate a hybrid code from CC w/ Stats and Hough Transformation?

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

image='17.png'
img=cv2.imread(image,1)
img_orig=img.copy()
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

img=cv2.GaussianBlur(img,(21,21),cv2.BORDER_DEFAULT)


all_circs=cv2.HoughCircles(img, cv2.HOUGH_GRADIENT,1,500,param1=110,param2=35,minRadius=200,maxRadius=600)
all_circs_rounded=np.uint32(np.around(all_circs))


count = 1
for i in all_circs_rounded[0, :]:
    cv2.circle(img_orig,(i[0],i[1],),i[2],(255,0,0),3)
    cv2.circle(img_orig,(i[0],i[1],),2,(255,0,0),3)
    cv2.putText(img_orig,"Coin"+str(count),(i[0]-70,i[1]+30),cv2.FONT_HERSHEY_SIMPLEX,1.1,(255,0,0),2)
    count+=1

print (all_circs_rounded)
print (all_circs_rounded.shape)
print ('I have found ' + str(all_circs_rounded.shape[1]) + ' coins')

plt.rcParams["figure.figsize"]=(16,9)
plt.imshow(img_orig)


Solution

  • There are several potential solutions for this problem

    1. You could use image segmentation with watershed. This method has the advantage of being able to locate touching coins in the image as you can easily segment coins from one another. In addition, watershed allows you to obtain the center of the coin where you can do additional processing.

    2. Continue to use Hough Circle Transform. The function returns various parameters such as the radius which you can use to find the circle's area. Here's a quick example to obtain the radius which you can use the find the area using the classic formula. This method also allows you to easily obtain the center of the circle.

    # detect circles in the image
    circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.2, 100)
    
    # ensure at least some circles were found
    if circles is not None:
        # convert the (x, y) coordinates and radius of the circles to integers
        circles = np.round(circles[0, :]).astype("int")
    
        # loop over the (x, y) coordinates and radius of the circles
        for (x, y, r) in circles:
            # draw the circle in the output image, then draw a rectangle
            # corresponding to the center of the circle
            cv2.circle(output, (x, y), r, (0, 255, 0), 4)
            cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
    
            # calculate area here
            ...
    
    1. Pivot completely and use contour detection with filtering. Potential steps would be