I am working on camera calibration task using Charuco patterns using OpenCV, this is the first time i deals with this kind of boards but the problem that the corners_ids after interpolation step results the whole corners which is 70 corner in my case but the ids (0, 10, 20, 30, 40, 50, 60) aren't accurate, i don't know exactly the failure but i doubt that the board i have created using cv2.aruco.CharucoBoard.create(squaresX, squaresY, squareLength, markerLength, dictionary) is not acuurate, therefore i need someone familiar with it to understand me these parameters refer to especially (squareLength, markerLength).
this the input image provided images after interpolation id(0, 10, 20, 30, 40, 50, 60) each surrounded by black circle which positioned in an inaccurate location
def calibrate_charuco(dirpath, image_format, marker_length, square_length):
'''Apply camera calibration using aruco.
The dimensions are in cm.
'''
criteria = (cv2.TermCriteria_EPS + cv2.TermCriteria_MAX_ITER, 100, .001)
aruco_dict = aruco.Dictionary_get(aruco.DICT_4X4_1000)
board = aruco.CharucoBoard.create(11,8,square_length, marker_length, aruco_dict)
counter, corners_list, id_list = [], [], []
img_dir = pathlib.Path(dirpath)
first = 0
i = 0
# Find the ArUco markers inside each image
impaths = img_dir.glob(f'*{image_format}')
for img in impaths:
image = cv2.imread(str(img))
img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
corners, ids, rejected = aruco.detectMarkers(img_gray, aruco_dict)
for corner in corners:
cv2.cornerSubPix(img_gray, corner, (3, 3), (-1, -1), criteria)
resp, charuco_corners, charuco_ids = aruco.interpolateCornersCharuco(corners, ids, img_gray, board, minMarkers=0)
aruco.drawDetectedCornersCharuco(image, charuco_corners, charuco_ids, (255, 125, 125))
# If a Charuco board was found, let's collect image/corner points
# Requiring at least 20 squares
if resp > 20:
# Add these corners and ids to our calibration arrays
corners_list.append(charuco_corners)
id_list.append(charuco_ids)
# Actual calibration
ret, mtx, dist, rvecs, tvecs = aruco.calibrateCameraCharuco(
charucoCorners=corners_list,
charucoIds=id_list,
board=board,
imageSize=img_gray.shape,
cameraMatrix=None,
distCoeffs=None)
return [ret, mtx, dist, rvecs, tvecs]
# Parameters
IMAGES_DIR = 'Cam1'
IMAGES_FORMAT = 'jpg'
# Dimensions in cm
MARKER_LENGTH = 0.8
SQUARE_LENGTH = 1
ret, mtx, dist, rvecs, tvecs = calibrate_charuco(IMAGES_DIR, IMAGES_FORMAT, MARKER_LENGTH, SQUARE_LENGTH)
print(mtx)
original = cv2.imread('Cam1/G0011233.jpg')
dst = cv2.undistort(original, mtx, dist, None, mtx)
cv2.imwrite('undist_charuco.jpg', dst)