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

如何用Python为AprilTag位姿估计进行相机校准?

使用pupil_apriltags实现位姿估计:相机校准参数获取与传入指南

核心概念明确

pupil_apriltags的位姿估计依赖的camera_params参数,本质就是相机的内参参数,格式为[fx, fy, cx, cy]:

  • fx/fy:相机在x/y轴上的焦距(像素单位)
  • cx/cy:相机光心的x/y像素坐标

这和你之前用Aruco时用到的相机内参矩阵是同一组数据,只是提取方式不同。另外如果相机存在畸变,还需要传入distortion参数,格式为[k1, k2, p1, p2, k3](对应OpenCV校准输出的畸变系数)。

如何获取相机校准参数

用OpenCV完成相机校准即可得到所需参数,步骤如下:

1. 准备校准素材

  • 打印一张棋盘格(推荐9x6个内角点的规格,格子边长自己测量记录)
  • 用目标相机拍摄10-20张不同角度、不同距离的棋盘格照片(覆盖画面不同区域,尽量倾斜棋盘格)

2. 用OpenCV计算内参和畸变系数

运行以下代码(适配你的Windows环境和OpenCV 4.7.0):

import cv2
import numpy as np
import glob

# 棋盘格内角点数量(根据你打印的棋盘格调整)
chessboard_corners = (9, 6)
# 生成棋盘格的世界坐标(假设每个格子边长1单位,后续不影响内参计算)
obj_points = np.zeros((chessboard_corners[0]*chessboard_corners[1], 3), np.float32)
obj_points[:,:2] = np.mgrid[0:chessboard_corners[0], 0:chessboard_corners[1]].T.reshape(-1,2)

world_points = []  # 存储所有棋盘格的世界坐标
image_points = []  # 存储所有棋盘格的图像坐标

# 读取校准照片(替换为你的照片路径)
calib_images = glob.glob("calibration_photos/*.jpg")

for img_path in calib_images:
    img = cv2.imread(img_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 检测棋盘格角点
    ret, corners = cv2.findChessboardCorners(gray, chessboard_corners, None)
    if ret:
        world_points.append(obj_points)
        # 亚像素优化角点精度
        refined_corners = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), 
                                           (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001))
        image_points.append(refined_corners)

# 执行相机校准
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(
    world_points, image_points, gray.shape[::-1], None, None
)

# 提取pupil_apriltags需要的参数
fx = camera_matrix[0][0]
fy = camera_matrix[1][1]
cx = camera_matrix[0][2]
cy = camera_matrix[1][2]
camera_params = [fx, fy, cx, cy]
# 畸变系数转为列表格式
distortion = dist_coeffs[0].tolist()

# 可以把参数保存到文件,后续直接读取使用
np.savez("camera_calib_params.npz", camera_params=camera_params, distortion=distortion)

3. 保存复用参数

校准完成后,把camera_params和distortion保存到文件,后续不需要重复校准,直接读取即可。

传入参数实现位姿估计

用pupil_apriltags检测时,开启位姿估计并传入校准参数,示例代码:

from pupil_apriltags import Detector
import cv2
import numpy as np

# 读取保存的校准参数
calib_data = np.load("camera_calib_params.npz")
camera_params = calib_data["camera_params"]
distortion = calib_data["distortion"]

# 初始化AprilTag检测器(指定你使用的tag家族,比如tag36h11)
detector = Detector(families="tag36h11")

# 读取测试图像(或从摄像头实时获取帧)
img = cv2.imread("test_tag.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 检测并估计位姿
# tag_size为AprilTag的实际物理边长(单位:米,和后续平移向量单位一致)
detections = detector.detect(
    gray,
    estimate_tag_pose=True,
    camera_params=camera_params,
    distortion=distortion,
    tag_size=0.1  # 替换为你的tag实际尺寸
)

# 处理检测结果
for det in detections:
    print(f"检测到Tag ID: {det.tag_id}")
    print(f"旋转矩阵:\n{det.pose_R}")
    print(f"平移向量(米):\n{det.pose_t}")

注意事项

  • 校准照片质量直接影响参数精度:避免模糊、过曝/欠曝,尽量让棋盘格占画面不同区域
  • tag_size必须是实际物理尺寸,否则位姿结果的平移向量会有比例误差
  • 如果相机畸变很小,也可以不传distortion参数,或传入[0,0,0,0,0]跳过畸变校正

内容的提问来源于stack exchange,提问作者Maxime Dumonteil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 10:52:01