OpenCV 4.10.0下使用Charuco板进行相机标定的问题求助
适配OpenCV 4.10.0的Charuco板相机标定完整代码示例
以下是针对OpenCV 4.10.0 Python版本的可运行Charuco标定代码,同时解决你遇到的API调用问题:
完整代码实现
import cv2 as cv import numpy as np import glob # ---------------------- 1. 配置Charuco板参数 ---------------------- # 需与实际打印的Charuco板参数完全一致 CHARUCO_ROWS = 5 CHARUCO_COLS = 7 MARKER_SIZE = 0.03 # ArUco标记边长(单位:米) SQUARE_SIZE = 0.04 # Charuco棋盘格边长(单位:米) # 创建ArUco字典与Charuco板对象 aruco_dict = cv.aruco.getPredefinedDictionary(cv.aruco.DICT_4X4_50) charuco_board = cv.aruco.CharucoBoard( (CHARUCO_COLS, CHARUCO_ROWS), SQUARE_SIZE, MARKER_SIZE, aruco_dict ) # 初始化ArUco检测器(OpenCV 4.x标准用法) detector_params = cv.aruco.DetectorParameters() aruco_detector = cv.aruco.ArucoDetector(aruco_dict, detector_params) # ---------------------- 2. 加载标定图片 ---------------------- # 替换为你的图片路径,支持批量处理 image_paths = glob.glob("charuco_calib_imgs/*.jpg") # 存储标定所需数据 object_points = [] # 世界坐标系下的Charuco角点 image_points = [] # 图像坐标系下的Charuco角点 # ---------------------- 3. 逐图检测与数据收集 ---------------------- for img_path in image_paths: img = cv.imread(img_path) gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 检测ArUco标记 marker_corners, marker_ids, _ = aruco_detector.detectMarkers(gray) if marker_ids is not None and len(marker_ids) > 3: # 至少需要3个Marker匹配 # 匹配Charuco角点(解决你调用matchImagePoints失败的问题) match_ok, charuco_corners, charuco_ids = charuco_board.matchImagePoints( marker_corners, marker_ids ) if match_ok and len(charuco_ids) > 4: # 至少需要5个Charuco角点用于标定 # 插值优化Charuco角点(解决interpolateCornersCharuco调用问题) interp_ok, interp_corners, interp_ids = cv.aruco.interpolateCornersCharuco( marker_corners, marker_ids, gray, charuco_board ) # 优先使用插值后的角点(提升标定精度) if interp_ok: charuco_corners = interp_corners charuco_ids = interp_ids # 生成对应世界坐标点 obj_p, _ = charuco_board.generateImagePoints(charuco_ids) object_points.append(obj_p) image_points.append(charuco_corners) # 可视化检测结果(可选) cv.aruco.drawDetectedMarkers(img, marker_corners, marker_ids) cv.aruco.drawDetectedCornersCharuco(img, charuco_corners, charuco_ids) cv.imshow("Charuco Detection", img) cv.waitKey(100) cv.destroyAllWindows() # ---------------------- 4. 执行相机标定 ---------------------- if len(object_points) >= 10: # 推荐至少10张有效图片 # 初始化相机矩阵与畸变系数(可传入None让OpenCV自动计算) cam_mat = np.eye(3, dtype=np.float32) dist_coeffs = np.zeros((5, 1), dtype=np.float32) # 执行标定 retval, cam_mat, dist_coeffs, rvecs, tvecs = cv.calibrateCamera( object_points, image_points, gray.shape[::-1], cam_mat, dist_coeffs ) if retval: print("标定成功!") print("相机矩阵:\n", cam_mat) print("畸变系数:\n", dist_coeffs) # 保存标定结果 np.savez("charuco_calib_result.npz", camera_matrix=cam_mat, dist_coeffs=dist_coeffs) else: print("标定失败,请检查图片质量或参数配置") else: print("有效标定图片不足,请采集更多不同角度的Charuco板图片")
针对你遇到问题的修复说明
- 关于
cv.aruco.interpolateCornersCharuco缺失:该函数在OpenCV 4.10.0中仍存在,需确保通过cv2.aruco调用(注意导入时用import cv2 as cv),且传入参数格式正确(需传入灰度图、Charuco板对象等)。 - 关于Python版
ArucoDetector无detectBoard:Python版本确实没有该方法,需手动先检测Marker,再通过CharucoBoard.matchImagePoints匹配Charuco角点,这是当前版本的标准流程。 - 关于
matchImagePoints()调用失败:需满足两个核心条件:一是检测到的marker_ids不为空,且与marker_corners数量完全匹配;二是Charuco板的行列数、字典类型与实际打印的板完全一致。
关键注意事项
- 打印的Charuco板参数必须与代码中配置的完全一致,否则会导致匹配失败
- 标定图片需覆盖不同角度、距离和姿态,避免图片过于相似
- 确保图片中Marker清晰无严重遮挡,光照均匀
内容的提问来源于stack exchange,提问作者m.ariuz
相关产品推荐
相关产品推荐

