I am trying to detect and determine the radius of circular beads (blobs) in an image using OpenCV in Python. I'm using the following code for this - it seems to work reasonably for non-overlapping circles.
I have the following issues:
- I'm not able to identify the overlapping sections at all.
- Some of the detected circles are larger than the actual size of the blobs. I've tried tweaking the HoughCircles parameters but it's more of a trial and error.
Any pointers on how to improve the circle detection and precision is greatly appreciated.
import numpy as np
import cv2
import sys
if len(sys.argv) < 2:
print ('Enter path to image file')
sys.exit()
img = cv2.imread(sys.argv[1])
output = img.copy()
#Convert image to Grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#Blur image
gray = cv2.GaussianBlur(gray, (3,3), 0)
#Canny edge detection
edges = cv2.Canny(gray, 50, 200)
cv2.imshow('edges', edges)
# # detect circles
circles = cv2.HoughCircles(image=gray,
method=cv2.HOUGH_GRADIENT,
dp=1.1,
param1=100,
param2=30,
minDist=30,
minRadius=10,
maxRadius=60)
rcircles = np.uint16(np.around(circles))
if circles is not None:
circles = np.round(circles[0, :]).astype("int")
print ("Number of circles:", len(circles))
# Count circles
count=1
for (x, y, r) in circles:
#Calculate radius in mm:
r_mm = round(r/53.3, 2)
# Create outer circle
cv2.circle(output, (x,y), r, (0, 0, 0), 1)
# Create center rectangle
cv2.rectangle(output, (x-2, y-2), (x+2, y+2), (0,255,0), -1)
# Add radius to center
cv2.putText(output, str(r_mm),
(x-15, y-5),
cv2.FONT_HERSHEY_COMPLEX_SMALL,
0.7, (0, 0, 0), 1)
# Print the radius of detected circles in pixels and mm
print ('c' + str(count) + ' ' + str(r_mm) + ' ' + str(r))
count += 1
cv2.imshow("output", np.hstack([img, output]))
cv2.waitKey(0)
Link to original image here.
Original image and image with detected circles and corresponding radii
