我正在使用OpenCV使用Charuco模式进行相机校准任务,这是我第一次处理这种板,但是插值步骤后的corners_ids导致整个角在我的情况下是70个角,但id(0,10,20,30,40,50,60)不准确,我不知道确切的失败,但我怀疑我使用cv2.aruco.CharucoBoard创建的板。create(squaresX, squaresY, squareLength, markerLength, dictionary)是不准确的,因此我需要熟悉它的人来理解我,特别是这些参数指的是(squareLength, markerLength)。
这个输入图像提供了插值后的图像id(0,10,20,30,40,50,60),每个图像都被定位在不准确位置的黑色圆圈包围
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)
我假设您使用的是最新版本的opencv(4.6.0.66),其中似乎interpolateCornersCharuco没有呈现正确的结果。卸载并恢复到4.1.2.30使它为我工作:
python3 -m pip install opencv-python==4.1.2.30
python3 -m pip install opencv-contrib-python==4.1.2.30
python3 -m pip install opencv-python-headless==4.1.2.30