Search code examples
pythonopencvcomputer-visioncamera

cv2.findCirclesGrid in python not working


I want to calculate a calibration for my camera and I have this pattern but it for some reason doesnt recognise it.

calibration_pattern = cv2.imread('circles/IMG_9341.JPG')
gray_pattern = cv2.cvtColor(calibration_pattern, cv2.COLOR_BGR2GRAY)

# Define chessboard size and criteria
pattern_size = (4, 11)  # Change accordingly based on your calibration pattern

# Find circle centers on the calibration pattern
ret, corners = cv2.findCirclesGrid(gray_pattern, pattern_size, flags = cv2.CALIB_CB_ASYMMETRIC_GRID + cv2.CALIB_CB_CLUSTERING)

ret is always False

example image

I tried changing up the patterns, flags even other images but it is always False.


Solution

  • Your fix would be to edit the blobDetector params. The default blobDetector does not suit your image

    Your circles are quite big, and hence if you set the minimum and maximum area of the blob detector, everything should work fine. Here's how to do it:

    im = cv2.cvtColor(cv2.imread("circles.jpg"), cv2.COLOR_BGR2RGB) # read im
    im_chess = im.copy()
    gray = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY) # convert to gray
    blobParams = cv2.SimpleBlobDetector_Params() # create a default blob detector param
    blobParams.filterByArea = True # enable filtering by area
    blobParams.minArea = 10000   # minimum area
    blobParams.maxArea = 40000   # maximum area
    blobDetector = cv2.SimpleBlobDetector_create(blobParams) # create the blob detector
    ret, corners = cv2.findCirclesGrid(im, (4,11),
                                       flags = (cv2.CALIB_CB_ASYMMETRIC_GRID+cv2.CALIB_CB_CLUSTERING),
                                       blobDetector = blobDetector) # pass the blobDetector to the function
    if ret == True: # if detected...
        corners2 = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), 
                                    (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)) # refine corner location
        cv2.drawChessboardCorners(im_chess, (4,11), corners2, ret) # draw the chessboard
    

    This is the end result:

    Results

    Try to play around with other parameters if you want. This is a nice tutorial.