如何在G1单元树上校准摄像头
根据CharUco为Unitree G1头相机进行内在和外在摄像头校准.
根据G1的标准,G1头像摄像机的内在和外在校准,使用CharUco板和OpenCV进行了校准,并将结果保存到YAML,并通过重新投放错误智能检查验证.
人类 总时间:约90分钟 难度:中期 更新 2026 年 4 月
你将实现什么
在本教程结束时,您将为G1头相机每个相机内内内 (相机矩阵和扭曲系数),在头部设备中的相机之间内外,以及从头部相机框架到G1基链接的内外.所有这些都可以直接使用下游ROS 2 / LeRobot / OpenVLA堆
条件
- Unitree G1带着主摄像头阵列的电源和流 (EDU / 开发者变体将摄像头暴露在SDK上).
- ChArUco板. 打印A2 8x11板,用40mm方形和30mm的ArUco标记在
纸上,并将其安装在一个硬,平坦的,不 的表面 (泡 板或 烯基板). - 工作站与Ubuntu 22.04,Python 3.10,OpenCV 4.8+和安装的Unitree G1 SDK.
- 避免直接的阳光或镜像反射在板上.
步骤
打印和安装查鲁科板
生成板的PDF:
```
python -c "
import cv2
aruco = cv2.aruco
d = aruco.getPredefinedDictionary(aruco.DICT_5X5_100)
board = aruco.CharucoBoard((8, 11), 0.040, 0.030, d)
img = board.generateImage((1500, 2100), marginSize=40)
cv2.imwrite('charuco_a2.png', img)
"
```
印在A2
设置G1和流相机
启动G1在连接模式下,电池安装安全.通过Unitree SDK启动头部摄像头流. 精确的Python绑定在[unitreerobotics]
- 拍摄40-60个板框
移动G1头 (或板) 通过广泛的姿势:倾向左,倾向右,接近,远,离轴.OpenCV的校准度只能与你给它提供的多样性视角相等.对于立体外观,每一姿势都需要捕捉两个摄像头上的同步框架.
```
import cv2
for i in range(60):
frame_left, frame_right = camera.grab_sync()
cv2.imwrite(f'calib/left_{i:03d}.png', frame_left)
cv2.imwrite(f'calib/right_{i:03d}.png', frame_right)
input("move board, press enter")
```
**提示:**板应填满至少30%的框架,而最多的角落标记应跨越整个图像区域.仅在中心的板子拍摄产生了过度自信的内在.
- 计算每部相机的内在信息
运行每相机的查鲁科内定位:
```
import cv2, glob, numpy as np
aruco = cv2.aruco
d = aruco.getPredefinedDictionary(aruco.DICT_5X5_100)
board = aruco.CharucoBoard((8, 11), 0.040, 0.030, d)
detector = aruco.CharucoDetector(board)
all_corners, all_ids, img_size = [], [], None
for fn in sorted(glob.glob('calib/left_*.png')):
img = cv2.imread(fn, cv2.IMREAD_GRAYSCALE)
img_size = img.shape[::-1]
corners, ids, _, _ = detector.detectBoard(img)
if ids is not None and len(ids) > 6:
all_corners.append(corners)
all_ids.append(ids)
ret, K, dist, rvecs, tvecs = aruco.calibrateCameraCharuco(
all_corners, all_ids, board, img_size, None, None)
print('RMS reprojection error:', ret)
```
目标RMS低于0.5像素.超过1x表示板板平度不佳,姿势多样性不足或
- 计算立体音频外观
对于相机的对 (例如双向G1机上的左+右头相机),使用已经计算的内在和同步板观测运行
```
ret, K1, D1, K2, D2, R, T, E, F = cv2.stereoCalibrate(
object_points, left_img_points, right_img_points,
K_left, D_left, K_right, D_right, img_size,
flags=cv2.CALIB_FIX_INTRINSIC)
```
- ###计算头到底的外根 (可选)
如果您的下游政策需要摄像头在G1基链或世界框架中姿势,通过已知头部动态链接:从SDK读取头部关联状态,与相机到头链接外端 (从URDF或一次手眼校准) 编译,并发布ROS 2
- 为了
姆
保存在ROS兼容的YAML格式,以便标准的
```
import yaml
out = {
'image_width': 1280,
'image_height': 720,
'camera_name': 'g1_head_left',
'camera_matrix': {'rows': 3, 'cols': 3, 'data': K.flatten().tolist()},
'distortion_model': 'plumb_bob',
'distortion_coefficients': {'rows': 1, 'cols': 5, 'data': dist.flatten().tolist()},
}
with open('g1_head_left.yaml', 'w') as f:
yaml.safe_dump(out, f)
```
- 在测试场合验证
捕获一个新的 ChArUco 框架,它不在校准设置中.检测角落,重新设计使用您保存的内在,并覆盖图像.平均重新投放错误应该保持在0.5像素以下. 通过几种不同的头部姿势, 观看已知距离对象的立体差异, 如果它与磁带测量距离相符,
接下来要做什么?
输入您的校准内在任何下游政策堆
常见故障模式
**外观错误几厘米:**通常是单位虫
**不一致的运行:**检查每一个
**校准后政策仍然失败:**验证图像订单 (BGR与RGB) 和变量量订单 (收获然后变量,然后变量) 匹配政策的训练预处理.
深度潜水:为什么查鲁科不过是平板棋牌
简单的棋牌是教科书校准目标,但它有一个已知故障模式:如果任何棋牌板部分被遮蔽,整个检测都会失败. 查鲁科 (一个带有白色方形嵌入的阿鲁科信托人的棋牌板) 通过给每个角落一个独特的身份来解决这个问题. 校准器可以使用部分观测,因此您可以通过各种姿势积极地移动棋牌,而不会浪费捕获时间在不适用的框架上. 避免使用旧教程中的过时功能;在新的API中,子像素角的精炼要好得多.
对于人形头部摄像头来说,查鲁科还有助于一个细致的方法:头部在拍摄过程中倾斜,所以你的框架在"板拍摄整个图像"和"板移向一侧"之间交替.
潜水深度:有多好足够好?
错误排斥是标题号,但不是整个故事.
- RGB政策培训: 0.5到 1.0 px是可以的.政策对小内在错误有所容忍,特别是如果你训练和部署相同的校准.
- ** 静电深度或SLAM:** 0.3 px以下. 通过三角形的外部错误化合物.
- **手眼/操纵:**内在的0.5 px以下,相机到端的效应器外在的2 mm以下.考虑专用手眼校准程序 (例如Tsai-Lenz) 而不是通过URDF链.
深度潜水:重新校准触发器
一个G1不需要每周重新校准,但某些情况证明了这一点: (1) 对头部或相机安装的物理冲击, (2) 换相机, (3) 在新部署地点 (冷实验室到热生产床) 热漂移,以及 (4) 如果您看到在使用几周内出现的重新投放错误. 作为每周维护的一部分,自动化快速查查鲁科智能检查.
深入潜水:与政策培训的融合
一旦将校准YAML保存,将其将在三个地方将在下游堆
常见问题
如果我只是在进行电话测试,我可以跳过校准吗 是的,电话测试不需要校准.
** 校准有效时间为多久?** 假设没有对头部的物理影响.
G1 URDF校准是否足够准确? 通常在几毫米内
** 如何使用鱼眼相机?** 在OpenCV中使用







