OpenCV中interpolateCornersCharuco无法检测角点与ID问题求助
Charuco板相机标定:
interpolateCornersCharuco无法检测角点与ID 问题描述
我从别处获取了一段Charuco板相机标定代码,代码可正常检测并绘制ArUco标记,但cv2.aruco.interpolateCornersCharuco函数始终无法检测到角点与ID,更换多张图片后问题依旧。相关代码及示例图片如下:
ARUCO_DICT = cv2.aruco.DICT_4X4_50 SQUARES_VERTICALLY = 8 SQUARES_HORIZONTALLY = 11 SQUARE_LENGTH = 0.01 MARKER_LENGTH = 0.007 # ... PATH_TO_YOUR_IMAGES = 'path' # ------------------------------ def calibrate_and_save_parameters(): # Define the aruco dictionary and charuco board dictionary = cv2.aruco.getPredefinedDictionary(ARUCO_DICT) board = cv2.aruco.CharucoBoard((SQUARES_VERTICALLY, SQUARES_HORIZONTALLY), SQUARE_LENGTH, MARKER_LENGTH, dictionary) params = cv2.aruco.DetectorParameters() # Load PNG images from folder image_files = [os.path.join(PATH_TO_YOUR_IMAGES, f) for f in os.listdir(PATH_TO_YOUR_IMAGES) if f.endswith(".png")] image_files.sort() # Ensure files are in order all_charuco_corners = [] all_charuco_ids = [] for image_file in image_files: image = cv2.imread(image_file) image_copy = image.copy() marker_corners, marker_ids, _ = cv2.aruco.detectMarkers(image, dictionary, parameters=params) marker_corners = tuple(marker_corners,) cv2.aruco.drawDetectedMarkers(image_copy,marker_corners,marker_ids) # If at least one marker is detected if len(marker_ids) > 0: cv2.aruco.drawDetectedMarkers(image_copy, marker_corners, marker_ids) charuco_retval, charuco_corners, charuco_ids = cv2.aruco.interpolateCornersCharuco(marker_corners, marker_ids, image, board) if charuco_retval: all_charuco_corners.append(charuco_corners) all_charuco_ids.append(charuco_ids) # Calibrate camera retval, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.aruco.calibrateCameraCharuco(all_charuco_corners, all_charuco_ids, board, image.shape[:2], None, None) # Save calibration data np.save('camera_matrix.npy', camera_matrix) np.save('dist_coeffs.npy', dist_coeffs) # Iterate through displaying all the images for image_file in image_files: image = cv2.imread(image_file) undistorted_image = cv2.undistort(image, camera_matrix, dist_coeffs) cv2.imshow('Undistorted Image', undistorted_image) cv2.waitKey(0) cv2.destroyAllWindows() calibrate_and_save_parameters()

问题排查与修复
1. CharucoBoard尺寸参数顺序错误
OpenCV的CharucoBoard构造函数要求尺寸参数顺序为**(水平方向方格数, 垂直方向方格数)**,但代码里写反了,这是导致插值失败的核心原因。修正代码:
board = cv2.aruco.CharucoBoard((SQUARES_HORIZONTALLY, SQUARES_VERTICALLY), SQUARE_LENGTH, MARKER_LENGTH, dictionary)
2. 冗余的元组转换
代码中marker_corners = tuple(marker_corners,)属于多余操作,detectMarkers返回的格式已经符合interpolateCornersCharuco要求,直接删除该行即可。
3. 改用灰度图进行插值
interpolateCornersCharuco对灰度图的兼容性更好,避免彩色通道干扰,添加灰度转换步骤:
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) charuco_retval, charuco_corners, charuco_ids = cv2.aruco.interpolateCornersCharuco(marker_corners, marker_ids, gray, board)
4. 优化ArUco检测参数
开启亚像素角点细化,提升标记角点检测精度:
params = cv2.aruco.DetectorParameters() params.cornerRefinementMethod = cv2.aruco.CORNER_REFINE_SUBPIX
修复后的完整代码
ARUCO_DICT = cv2.aruco.DICT_4X4_50 SQUARES_VERTICALLY = 8 SQUARES_HORIZONTALLY = 11 SQUARE_LENGTH = 0.01 MARKER_LENGTH = 0.007 PATH_TO_YOUR_IMAGES = 'path' def calibrate_and_save_parameters(): # 定义ArUco字典与Charuco棋盘 dictionary = cv2.aruco.getPredefinedDictionary(ARUCO_DICT) # 修正棋盘尺寸参数顺序 board = cv2.aruco.CharucoBoard((SQUARES_HORIZONTALLY, SQUARES_VERTICALLY), SQUARE_LENGTH, MARKER_LENGTH, dictionary) # 优化检测参数 params = cv2.aruco.DetectorParameters() params.cornerRefinementMethod = cv2.aruco.CORNER_REFINE_SUBPIX # 加载文件夹内的PNG图片 image_files = [os.path.join(PATH_TO_YOUR_IMAGES, f) for f in os.listdir(PATH_TO_YOUR_IMAGES) if f.endswith(".png")] image_files.sort() all_charuco_corners = [] all_charuco_ids = [] for image_file in image_files: image = cv2.imread(image_file) image_copy = image.copy() gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) marker_corners, marker_ids, _ = cv2.aruco.detectMarkers(gray, dictionary, parameters=params) # 绘制检测到的ArUco标记 cv2.aruco.drawDetectedMarkers(image_copy, marker_corners, marker_ids) cv2.imshow("Detected Markers", image_copy) cv2.waitKey(100) if len(marker_ids) > 0: # 插值Charuco角点 charuco_retval, charuco_corners, charuco_ids = cv2.aruco.interpolateCornersCharuco(marker_corners, marker_ids, gray, board) if charuco_retval: all_charuco_corners.append(charuco_corners) all_charuco_ids.append(charuco_ids) # 绘制Charuco角点 cv2.aruco.drawDetectedCornersCharuco(image_copy, charuco_corners, charuco_ids) cv2.imshow("Charuco Corners", image_copy) cv2.waitKey(100) cv2.destroyAllWindows() # 仅当收集到有效数据时执行标定 if len(all_charuco_corners) > 0: retval, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.aruco.calibrateCameraCharuco(all_charuco_corners, all_charuco_ids, board, gray.shape[:2], None, None) # 保存标定参数 np.save('camera_matrix.npy', camera_matrix) np.save('dist_coeffs.npy', dist_coeffs) # 展示去畸变结果 for image_file in image_files: image = cv2.imread(image_file) undistorted_image = cv2.undistort(image, camera_matrix, dist_coeffs) cv2.imshow('Undistorted Image', undistorted_image) cv2.waitKey(0) cv2.destroyAllWindows() else: print("未检测到足够的Charuco角点,无法完成标定") calibrate_and_save_parameters()
内容的提问来源于stack exchange,提问作者Bene_Paul
相关产品推荐
相关产品推荐

