Determining the radius of all circular (overlapping) blobs in image using OpenCV in Python

Viewed 1090

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:

  1. I'm not able to identify the overlapping sections at all.
  2. 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

m

0 Answers
Related