Search code examples
c++opencvimage-processinghough-transform

How to calculate the distance of two circles in a image by opencv


image with two circles

enter image description here

I have an image that include two fibers (presenting as two circles in the image). How can I calculate the distance of two fibers?

I find it hard to detect the position of the fiber. I have tried to use the HoughCircles function, but the parameters are hard to optimize and it cannot locate the circle precisely in most times. Should I subtract the background first or is there any other methods? MANY Thanks!


Solution

  • It's possible using hough circle detection but you should provide more images if you want a more stable detection. I just do denoising and go straight to circle detection. Using a non-local means denoising is pretty good at preserving edges which is in turn good for the canny edge algorithm included in the hough circle algorithm.

    My code is written in Python but can easily be translated into C++.

    import cv2 
    from matplotlib import pyplot as plt
    
    IM_PATH = 'your image path'
    DS = 2 # downsample the image
    
    orig = cv2.imread(IM_PATH, cv2.IMREAD_GRAYSCALE)
    orig = cv2.resize(orig, (orig.shape[1] // DS, orig.shape[0] // DS))
    img = cv2.fastNlMeansDenoising(orig, h=3, templateWindowSize=20 // DS + 1, searchWindowSize=40 // DS + 1)
    
    plt.imshow(orig, cmap='gray')
    circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, dp=1, minDist=200 // DS, param1=40 // DS, param2=40 // DS, minRadius=210 // DS, maxRadius=270 // DS)
    
    if circles is not None:
        for x, y, r in circles[0]:
            c = plt.Circle((x, y), r, fill=False, lw=1, ec='C1')
            plt.gca().add_patch(c)
    plt.gcf().set_size_inches((12, 8))
    plt.show()
    

    Important

    Doing a bit of image processing is only the first step in a good (and stable!) object detection. You have to leverage every detail and property that you can get your hands on and apply some statistics to improve your results. For example:

    • Use Yves' approach as an addition and filter all detected circles that do not intersect the joints.
    • Is one circle always underneath the other? Filter out horizontally aligned pairs.
    • Can you reduce the ROI (are the circles always in a specific area in your image or can they be everywhere)?
    • Are both circles always the same size? Filter out pairs with different sizes.
    • ...

    If you can use multiple metrics you can apply a statistical model (ex. majority voting or knn) to find the best pair of circles.

    Again: always think of what you know about your object, the environment and its behavior and take advantage of that knowledge.