用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/MIUAV/vibe-coding-ros2 --skill camera-intrinsic-calibration命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | camera-intrinsic-calibration |
| description | 相机内参标定技能 - Kalibr、ROS2 标定工具、单目/双目标定 |
| argument-hint | 相机标定 OR intrinsic OR Kalibr OR 单目标定 OR 双目标定 |
| user-invocable | true |
相机内参标定理论与 ROS2 实现
当需要以下帮助时使用此技能:
# 安装标定工具
sudo apt install ros-humble-camera-calibration
# 标定单目相机
ros2 run camera_calibration cameracalibrator --size 9x6 --square 0.025 \
--ros-args -p image:=/camera/image_raw \
-p camera:=/camera
# 标定双目相机
ros2 run camera_calibration stereocalibrator --size 9x6 --square 0.025 \
--ros-args -p left:=/stereo/left/image_raw \
-p right:=/stereo/right/image_raw
# 创建标定板配置
cat > target.yaml << EOF
target_type: 'checkerboard'
targetCols: 6
targetRows: 4
targetSpacing: 0.03
EOF
# 录制数据
ros2 bag record /camera/image_raw /camera/camera_info -o calibration.bag
# 运行 Kalibr
kalibr_calibrate_cameras --target target.yaml \
--bag calibration.bag \
--topic /camera/image_raw \
--output-path kalibr_results/
import numpy as np
import cv2
import glob
class CameraCalibrator:
def __init__(self, board_size=(9, 6), square_size=0.025):
self.board_size = board_size
self.square_size = square_size
self.objp = self.create_object_points()
def create_object_points(self):
"""创建标定板三维坐标点"""
objp = np.zeros((self.board_size[0] * self.board_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:self.board_size[0], 0:self.board_size[1]].T.reshape(-1, 2)
objp *= self.square_size
return objp
def calibrate(self, image_paths):
"""标定相机"""
objpoints = [] # 3D points
imgpoints = [] # 2D points
for fname in image_paths:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 找角点
ret, corners = cv2.findChessboardCorners(gray, .board_size, )
ret:
objpoints.append(.objp)
corners2 = cv2.cornerSubPix(gray, corners, (, ), (-, -),
criteria=(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, , ))
imgpoints.append(corners2)
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
objpoints, imgpoints, gray.shape[::-], , )
{
: mtx,
: dist,
: rvecs,
: tvecs,
: ret
}
():
h, w = image.shape[:]
newK, roi = cv2.getOptimalNewCameraMatrix(K, dist, (w, h), , (w, h))
dst = cv2.undistort(image, K, dist, , newK)
x, y, w, h = roi
dst = dst[y:y+h, x:x+w]
dst
class StereoCalibrator:
def __init__(self, board_size=(9, 6), square_size=0.025):
self.board_size = board_size
self.square_size = square_size
self.objp = self.create_object_points()
def calibrate_stereo(self, left_images, right_images):
"""双目标定"""
# 分别标定两个相机
retL, mtxL, distL, _, _ = self.calibrate_single(left_images)
retR, mtxR, distR, _, _ = self.calibrate_single(right_images)
# 双目标定
objpoints = []
imgpointsL = []
imgpointsR = []
for lImg, rImg in zip(left_images, right_images):
grayL = cv2.cvtColor(lImg, cv2.COLOR_BGR2GRAY)
grayR = cv2.cvtColor(rImg, cv2.COLOR_BGR2GRAY)
retL, cornersL = cv2.findChessboardCorners(grayL, self.board_size, None)
retR, cornersR = cv2.findChessboardCorners(grayR, self.board_size, None)
if retL and retR:
objpoints.append(self.objp)
cornersL2 = cv2.cornerSubPix(grayL, cornersL, (11, 11), (-1, -1),
criteria=(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001))
cornersR2 = cv2.cornerSubPix(grayR, cornersR, (11, ), (-, -),
criteria=(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, , ))
imgpointsL.append(cornersL2)
imgpointsR.append(cornersR2)
ret, mtxL, distL, mtxR, distR, R, T, E, F = cv2.stereoCalibrate(
objpoints, imgpointsL, imgpointsR,
mtxL, distL, mtxR, distR, grayL.shape[::-])
baseline = np.linalg.norm(T)
fx = mtxL[, ]
{
: mtxL, : mtxR,
: distL, : distR,
: R, : T,
: E, : F,
: baseline,
: ret
}