Search code examples
pythonopencvhough-transform

How to find circle faster than by Hough Transform in python opencv


I’m trying to make Hough Transform find a circle faster or find another function that can do it faster.
(i do not need to stick to open cv, but it needs to be opensource)
I need to get centerpoint and radius.

My use case:
I have a square picture in grayscale, 4 aruco markers in the corners(detected earlier),
and a black circle approximately in the middle.
Rest of the picture is quite uniformly white-isch/gray.
Picture size is 1600x1600.
I know the approximate center position and radius of the circle

I use:

cv2.HoughCircles(image, cv2.HOUGH_GRADIENT, 1, 100, 100, 30, 200,250)

This takes about 35-40ms. I would love to get it down to about 15ms

I tried reducing resolution by half, but id does not give me very big benefit and makes result a bit "jittery".

Image i try to recognize: Image i try to recognize


Solution

  • I didn't have much success with the method I suggested in the comments so I tried a different approach:

    #!/usr/bin/env python3
    
    import cv2
    
    # Load image in greyscale
    im = cv2.imread('J65Xt.jpg', cv2.IMREAD_GRAYSCALE)
    
    # Define region of interest to exclude corner markers and reduce processing time
    ROI = im[400:-400,400:-400]
    
    # Threshold and invert
    _, thr = cv2.threshold(ROI, 80,255,type=cv2.THRESH_BINARY_INV)
    
    # Find contours
    contours, _ = cv2.findContours(thr, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    # Get centroid from moments - may not really need this - could get from bounding box
    M = cv2.moments(contours[0])
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])
    print(f'Centroid: cX={cX}, cY={cY} do not forget 400 offset of ROI')
    # Mark centre in black
    thr[cY-3:cY+3, cX-3:cX+3] = 0
    
    # Get bounding box and draw it on
    x, y, w, h = cv2.boundingRect(contours[0])
    print(f'x={x}, y={y}, w={w}, h={h}')
    print(f'cX={x+w/2}, cY={y+h/2}')
    cv2.rectangle(thr, (x, y), (x + w, y + h), 255, 1)
    cv2.imwrite('result.png', thr)
    

    enter image description here

    Output

    Centroid: cX=432, cY=394 do not forget 400 offset of ROI
    cX=432.5, cY=395.0
    

    It takes 127 microseconds on my Mac if you exclude loading the input image and saving the output image.