You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()

Charuco板示例图


问题排查与修复

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 23:32:09