相机:132GS MIPI双目相机
平台:RDK X5
问题:请问如何获取原始图像并自行标定相机,然后在run_stereo的时候载入本地标定参数
相机:132GS MIPI双目相机
平台:RDK X5
问题:请问如何获取原始图像并自行标定相机,然后在run_stereo的时候载入本地标定参数
可以尝试使用 ROS2 官方工具 camera_calibration 包,采集棋盘格数据并生成 .yaml 标定文件。
然后修改相机驱动节点的启动配置文件(通常是 .launch.py 或 .yaml 参数文件),将标定文件路径指向你生成的本地文件。
但是执行run_camera.sh发布的图像topic都是nv12的,不被标定工具支持
针对 NV12 格式不被 ROS2 camera_calibration 支持的问题,核心思路是:在标定前将图像从 NV12 转换为 RGB8/mono8。
RDK X5 上 MIPI 相机默认输出 NV12 是为了节省带宽和方便硬件编解码,但标定工具需要未压缩的像素格式。以下是三种解决方案,按推荐程度排序:
image_proc 或自定义节点做格式转换(推荐)在相机驱动和标定工具之间加一个图像格式转换节点,将 NV12 转为 RGB8 或 mono8。
确认当前图像 topic 和格式
ros2 topic echo /camera/image_raw --field encoding
# 应输出: nv12
创建格式转换节点(Python 示例):
# nv12_to_rgb.py
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
import numpy as np
class Nv12ToRgb(Node):
def __init__(self):
super().__init__('nv12_to_rgb')
self.sub = self.create_subscription(Image, '/camera/image_raw', self.callback, 10)
self.pub = self.create_publisher(Image, '/camera/image_rgb', 10)
self.bridge = CvBridge()
def callback(self, msg):
# NV12 数据解析
h, w = msg.height, msg.width
nv12_data = np.frombuffer(msg.data, dtype=np.uint8)
nv12_data = nv12_data.reshape((h * 3 // 2, w))
bgr = cv2.cvtColor(nv12_data, cv2.COLOR_YUV420sp2BGR)
rgb_msg = self.bridge.cv2_to_imgmsg(bgr, encoding='rgb8')
rgb_msg.header = msg.header
self.pub.publish(rgb_msg)
if __name__ == '__main__':
rclpy.init()
rclpy.spin(Nv12ToRgb())
运行转换节点:
source /opt/tros/setup.bash
ros2 run your_package nv12_to_rgb
使用转换后的 topic 进行标定:
ros2 run camera_calibration cameracalibrator.py \
--size 8x6 \
--square 0.025 \
image:=/camera/image_rgb \
camera:=/camera
部分 MIPI 相机驱动支持配置输出格式。检查相机驱动的 .yaml 或 .launch.py 文件:
查找相机参数文件(通常在 /opt/tros/share/hobot_mipi_cam/ 或类似路径):
find /opt/tros -name "*.yaml" | xargs grep -l "format\|encoding"
修改输出格式(如果驱动支持):
# 示例:hobot_mipi_cam 参数
pixel_format: rgb8 # 或 mono8
# 原值可能是: nv12
重启相机节点:
ros2 launch hobot_mipi_cam hobot_mipi_cam.launch.py
注意:不是所有相机驱动都支持直接输出 RGB8,NV12 是 MIPI CSI-2 的标准格式,强制转 RGB8 可能增加 CPU 负载或降低帧率。
如果相机驱动支持 GStreamer,可以用管道直接转换:
gst-launch-1.0 v4l2src device=/dev/video0 ! \
video/x-raw,format=NV12 ! \
videoconvert ! \
video/x-raw,format=RGB ! \
ros2_image_publisher
标定完成后会生成 .yaml 文件(如 ost.yaml),修改相机驱动的启动配置:
# 在 .launch.py 文件中
Node(
package='hobot_mipi_cam',
executable='hobot_mipi_cam_node',
parameters=[{
'camera_info_url': 'file:///home/your_user/calibration/ost.yaml',
# 或
'calibration_file': '/home/your_user/calibration/ost.yaml'
}]
)
如果上述方案都不可行,请提供:
ros2 topic list 输出ros2 topic echo /camera/image_raw --field encoding,width,heightros2 pkg list | grep cam)这样可以进一步定位驱动是否支持格式切换。
总结:优先用方案一(加转换节点),简单可靠;如果驱动支持,方案二更直接。标定完成后记得修改驱动配置载入本地 .yaml 文件。
run_camera.sh里的out_format改成bgr8即可解决
太好了!
你找到了最直接的解决方案。
修改 run_camera.sh 中的 out_format 确实是最简单的办法,比加转换节点更省事。
# 编辑 run_camera.sh 或相关配置文件
# 找到类似这样的行:
out_format=nv12 # 改为
out_format=bgr8 # 或 rgb8
这样相机驱动直接输出 BGR8/RGB8,camera_calibration 就能直接用了。
采集标定数据
source /opt/tros/setup.bash
ros2 run camera_calibration cameracalibrator.py \
--size 8x6 \
--square 0.025 \
image:=/camera/image_raw \
camera:=/camera
保存标定文件
ost.yaml载入标定参数到 run_stereo
# 修改 stereo 节点的启动配置,添加参数:
camera_info_url: "file:///path/to/your/ost.yaml"
| 项目 | 说明 |
|---|---|
| 带宽 | BGR8 比 NV12 数据量大 1.5 倍,确认 MIPI 带宽足够 |
| 帧率 | 格式转换可能影响帧率,观察是否降帧 |
| CPU | 驱动内转换比后处理节点更高效 |
建议在原帖子中把你的解决方案更新一下,帮助其他遇到同样问题的开发者:
更新:直接修改
run_camera.sh中的out_format=bgr8即可输出标定工具支持的格式,无需额外转换节点。
这样社区其他人搜索时就能快速找到答案了 ![]()
标定过程中有任何问题随时问!
请问需要的标定结果.yaml文件的格式是什么,外参和内参都支持本地导入吗
针对你的问题,RDK X5 的 run_stereo.sh (StereoNet) 支持的标定文件格式主要有两种,取决于你使用的 标定模式 (calib_method)。
calib_method=ros 或默认)这是最通用的格式,由 ROS2 camera_calibration 包直接生成(即 ost.yaml)。StereoNet 节点会通过订阅 /camera_info Topic 自动获取内参。
文件结构示例 (ost.yaml):
image_width: 1280
image_height: 720
camera_name: "left_camera"
camera_matrix:
rows: 3
cols: 3
data: [fx, 0, cx, 0, fy, cy, 0, 0, 1] # 内参矩阵
distortion_model: "plumb_bob"
distortion_coefficients:
rows: 1
cols: 5
data: [k1, k2, p1, p2, k3] # 畸变系数
rectification_matrix:
rows: 3
cols: 3
data: [1, 0, 0, 0, 1, 0, 0, 0, 1] # 矫正矩阵(单目标定为单位阵)
projection_matrix:
rows: 3
cols: 4
data: [fx, 0, cx, Tx, 0, fy, cy, Ty, 0, 0, 1, 0] # 投影矩阵
projection_matrix 的 Tx/Ty 或通过其他机制注入。calib_method=custom)如果你需要直接加载包含双目外参的完整文件,需使用 StereoNet 特定的 JSON/YAML 格式。这是 run_stereo.sh 中 stereo_calib_file_path 参数指向的文件。
文件结构示例 (custom_calib.yaml 或 .json):
根据社区案例和报错信息,该格式通常需要包含左右目的完整参数及相互关系:
# 这是一个概念结构,具体字段名需参考 hobot_stereonet 源码或最新文档
left_camera:
intrinsics: [fx, fy, cx, cy]
distortion: [k1, k2, p1, p2, k3]
right_camera:
intrinsics: [fx, fy, cx, cy]
distortion: [k1, k2, p1, p2, k3]
stereo_params:
baseline: 0.12 # 基线距离 (米)
rotation: [r1, r2, ...] # 旋转矩阵 (9个元素)
translation: [tx, ty, tz] # 平移向量
topic:34849) 直接使用 custom 模式加载外部 YAML 可能存在稳定性问题(段错误),建议优先尝试通过 ROS Topic 注入参数。| 参数类型 | 是否支持本地导入 | 推荐导入方式 | 说明 |
|---|---|---|---|
| 内参 (Intrinsic) | ROS Topic 注入 | 标定生成的 ost.yaml 通过 camera_info_publisher 发布到 /camera_info Topic,StereoNet 自动订阅使用。这是最稳妥的方式。 |
|
| 畸变 (Distortion) | ROS Topic 注入 | 同上,包含在 ost.yaml 中。若开启 GDC 硬件去畸变 (mipi_gdc_enable=True),则需将参数填入驱动层的 YAML。 |
|
| 外参 (Extrinsic) | 手动指定参数 | run_stereo.sh 脚本提供了显式参数来覆盖外参,推荐直接使用脚本参数而不是依赖文件解析:--baseline 0.12 (基线)--camera_cx, --camera_cy 等 |
为了避免文件格式解析错误(如段错误)并灵活使用自标定参数,建议采用 “ROS Topic 内参 + 脚本参数外参” 的组合方式:
使用 camera_calibration 生成 left_ost.yaml 和 right_ost.yaml,然后启动发布节点:
# 启动相机内参发布器
ros2 run camera_calibration camera_info_publisher \
--ros-args -p url:=file:///path/to/your/left_ost.yaml \
-p frame_id:=camera_link \
-p camera_name:=left_camera
# 对右目重复操作,确保 topic 名称匹配 stereo 节点订阅
修改 run_stereo.sh 或在命令行直接传递外参参数,不依赖 stereo_calib_file_path (或设为空):
bash run_stereo.sh \
--calib_method ros \
--stereo_calib_file_path "" \
--baseline 0.120 \ # 你的双目基线 (米)
--camera_fx 900.0 \ # 可选:覆盖内参
--camera_fy 900.0 \
--camera_cx 640.0 \
--camera_cy 360.0
camera_calibration 生成的 ost.yaml (标准格式)。/camera_info) 自动加载,支持。run_stereo.sh 的 命令行参数 (--baseline 等) 直接传入,支持且更稳定。calib_method=custom 直接加载复杂的自定义 YAML 文件,目前社区反馈该方式可能存在解析 Bug。请问如何可视化校正后的图像(即运行run_stereo.sh后的/rectify_left_image话题),直接使用rviz或者rqt_image_view会提示不支持nv12格式
针对 run_stereo.sh 输出的校正图像(如 /rectify_left_image)是 NV12 格式,而 rviz2 或 rqt_image_view 默认不支持直接显示 NV12 的问题,这里有三种解决方案,按推荐程度排序:
run_stereo.sh 脚本支持配置输出图像的编码格式。你只需要在启动时添加或修改 codec_in_format 参数。
编辑 run_stereo.sh 脚本,找到 codec_in_format 参数行:
# 原值可能是:
codec_in_format=bgr8 # 或者 nv12
确保它被设置为 bgr8 或 rgb8。
或者在命令行启动时直接覆盖参数:
bash run_stereo.sh \
--codec_in_format bgr8 \
--publish_rectify_bgr True
注意:
publish_rectify_bgr=True确保发布的是 BGR 格式的校正图。
验证 Topic 格式:
ros2 topic echo /rectify_left_image --field encoding
# 应输出: bgr8 或 rgb8
现在可以直接用 RViz2 查看:
rviz2
# 添加 Image 显示,Topic 选择 /rectify_left_image
image_transport 或转换节点(如果方案一无效)如果 StereoNet 节点强制输出 NV12,可以在中间加一个格式转换节点。
# nv12_to_rgb_display.py
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
import numpy as np
class Nv12ToRgb(Node):
def __init__(self):
super().__init__('nv12_to_rgb_display')
# 订阅 NV12 的校正图
self.sub = self.create_subscription(Image, '/rectify_left_image', self.callback, 10)
# 发布 RGB8 的校正图
self.pub = self.create_publisher(Image, '/rectify_left_image_rgb', 10)
self.bridge = CvBridge()
def callback(self, msg):
if msg.encoding != 'nv12':
self.pub.publish(msg) # 已经是 RGB,直接转发
return
h, w = msg.height, msg.width
# NV12 数据解析:Y 平面 + UV 平面
nv12_data = np.frombuffer(msg.data, dtype=np.uint8)
nv12_data = nv12_data.reshape((h * 3 // 2, w))
# 转换为 BGR
bgr = cv2.cvtColor(nv12_data, cv2.COLOR_YUV420sp2BGR)
# 转为 ROS Image 消息
rgb_msg = self.bridge.cv2_to_imgmsg(bgr, encoding='bgr8')
rgb_msg.header = msg.header
self.pub.publish(rgb_msg)
if __name__ == '__main__':
rclpy.init()
rclpy.spin(Nv12ToRgb())
运行转换节点:
source /opt/tros/setup.bash
python3 nv12_to_rgb_display.py
在 RViz2 中订阅新 Topic:
/rectify_left_image_rgbrqt_image_view 的插件(如果支持)部分 rqt_image_view 版本支持通过插件解码 NV12,但 RDK 的 TROS 环境可能未默认安装。
尝试安装:
sudo apt install ros-humble-rqt-image-view
如果仍不支持,请优先使用方案一。
确认当前 Topic 格式:
ros2 topic info /rectify_left_image -v
# 查看 Published message type 和 encoding 字段
如果格式是 nv12:
在 RViz2 中显示:
/rectify_left_image(如果已转为 BGR8)或 /rectify_left_image_rgb| 项目 | 说明 |
|---|---|
| 性能 | 直接修改 codec_in_format 比后处理转换节点更高效 |
| 带宽 | BGR8 数据量比 NV12 大 1.5 倍,确认网络/显示带宽足够 |
| 兼容性 | RViz2 在 ARM 平台上对 NV12 支持有限,建议统一转 BGR8 |
建议优先尝试 方案一,直接在 run_stereo.sh 中设置 --codec_in_format bgr8,这是最干净的解决方案。如果遇到问题,再考虑方案二的转换节点。
转换成功后,欢迎在原帖子更新解决方案,帮助其他开发者!
我仔细对比了一下/rectify_left_image和/origin_left_image,感觉除了被resize以外,似乎没有看到畸变校正的效果?是不是run_stereo.sh里有参数没设置正确导致实际没有进行校正
你的观察非常敏锐!如果 /rectify_left_image 和 /origin_left_image 看起来除了分辨率不同外,畸变效果没有明显区别,说明畸变校正(Undistortion)实际上并没有生效。
这通常是因为 run_stereo.sh 的标定模式配置不正确,导致节点没有加载你的标定参数,而是使用了默认的空参数(相当于无校正)。
以下是排查和解决步骤:
在 RDK X5 的 StereoNet 流程中,畸变校正通常由两个环节之一完成:
hobot_mipi_cam)完成,输出已经是无畸变图像。如果你的标定文件没有正确加载,节点会 fallback 到“无畸变”模式,导致输出的 rectify 图像和原图看起来一样(仅做了 Resize)。
请重点检查 run_stereo.sh 中的以下几个关键参数:
calib_method)这是最关键的一步。如果你使用的是 ROS camera_calibration 生成的 ost.yaml,不能直接用 calib_method=custom 加载文件路径,而应该使用 calib_method=ros 并通过 Topic 注入。
修改建议:
# 错误用法(容易崩溃或无效):
# calib_method=custom
# stereo_calib_file_path=/path/to/ost.yaml
# ✅ 正确用法(推荐):
calib_method=ros
stereo_calib_file_path="" # 留空,不直接加载文件
如果你希望 StereoNet 处理畸变,必须确保相机驱动没有预先做一遍 GDC 校正,或者 StereoNet 知道原始畸变参数。
检查 mipi_gdc_enable 参数:
情况 A:mipi_gdc_enable=True (默认)
rectify 操作主要是做极线对齐 (Rectification),而不是去畸变。rectify 图看起来确实和原图很像。/origin_left_image 里的直线已经是直的,说明驱动层已经处理了。情况 B:mipi_gdc_enable=False
/camera_info 中发布了正确的畸变系数 (distortion_coefficients)。在运行 run_stereo.sh 的同时,在另一个终端检查相机内参 Topic:
# 查看左目内参
ros2 topic echo /image_combine_raw/left/camera_info
# 或者根据你的脚本配置,可能是 /left_camera/camera_info
# 重点检查以下字段是否为 0 或默认值:
# distortion_coefficients: [0.0, 0.0, 0.0, 0.0, 0.0] <-- 如果全为 0,说明没加载成功!
# camera_matrix: [fx, 0, cx, ...] <-- 检查 fx, fy, cx, cy 是否是你标定的值
如果 distortion_coefficients 全为 0,说明 StereoNet 没有读到你的标定文件。
为了确保标定生效,请按以下标准流程操作:
不要依赖 run_stereo.sh 直接读文件,而是启动一个独立的节点发布标定参数。
# 终端 1: 发布左目内参
ros2 run camera_calibration camera_info_publisher \
--ros-args \
-p url:=file:///home/your_user/calibration/left_ost.yaml \
-p frame_id:=camera_link \
-p camera_name:=left_camera \
--remap camera_info:=/image_combine_raw/left/camera_info
# 终端 2: 发布右目内参 (如果有单独的右目标定文件)
ros2 run camera_calibration camera_info_publisher \
--ros-args \
-p url:=file:///home/your_user/calibration/right_ost.yaml \
-p frame_id:=camera_link \
-p camera_name:=right_camera \
--remap camera_info:=/image_combine_raw/right/camera_info
(注意:--remap 后的 topic 名称必须与 run_stereo.sh 中订阅的 left_camera_info_topic 和 camera_info_topic 一致)
编辑脚本,确保以下参数设置正确:
# 关键参数设置
calib_method=ros # 使用 ROS Topic 获取内参
stereo_calib_file_path="" # 不要指定文件路径,避免解析错误
mipi_gdc_enable=False # 【重要】如果想让 StereoNet 做去畸变,建议关闭驱动层 GDC
# 如果保持 True,则 StereoNet 只做极线校正
# 外参参数(如果是双目,必须手动指定基线,因为 ROS 单目标定文件不含基线)
baseline=0.120 # 填入你实测的双目基线距离 (米)
camera_cx=640.0 # 可选:如果 Topic 里没覆盖,可在这里强制指定
camera_cy=360.0
camera_fx=900.0
camera_fy=900.0
运行脚本:
bash run_stereo.sh
ros2 topic echo /image_combine_raw/left/camera_info
# 确认 distortion_coefficients 不为 0
/origin_left_image 和 /rectify_left_image。/origin_left_image:直线弯曲(如果 mipi_gdc_enable=False)。/rectify_left_image:直线变直,且左右目同一水平线上的像素对齐。| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| rectify 和 origin 看起来一样 | 1. distortion_coefficients 为 02. 驱动层已去畸变 ( mipi_gdc_enable=True) |
1. 检查 camera_info Topic 是否有数据2. 尝试关闭 mipi_gdc_enable 测试 |
| 节点崩溃 (exit code -11) | calib_method=custom 解析文件失败 |
改用 calib_method=ros + camera_info_publisher |
| 深度图全黑或测距为 0 | 基线 (baseline) 为 0 或外参错误 |
在启动脚本中手动传入 --baseline 0.12 |
| 直线不直 | 标定数据未生效 | 确认 camera_info_publisher 已启动且 Topic 名称匹配 |
建议先执行“第三步”中的 ros2 topic echo 命令,这是判断标定参数是否加载成功的最直接证据。如果 distortion_coefficients 全是 0,那无论怎么跑,图像都不会有去畸变效果。
run_cam.sh怎么设置才能直接输出去畸变后的图
要在 run_cam.sh (或 hobot_mipi_cam 启动配置) 中直接输出已去畸变的图像,核心是启用 GDC (Geometry Distortion Correction) 硬件模块并加载正确的标定文件。
RDK X5 的去畸变通常在相机驱动层完成,而不是在 StereoNet 层。
你需要修改相机驱动节点的启动参数,启用 GDC 并指向你的标定文件。
.yaml 或 .bin)GDC 模块需要特定的标定文件格式。
.yaml (ROS 标准格式):通常可以直接使用,但需确认字段匹配。.bin:需使用地平线提供的 GDC Tool (Windows) 将内参转换为映射表。
.yaml 也能被驱动加载,具体取决于 SDK 版本。将你的标定文件重命名或放置在驱动默认读取的路径,例如:
/opt/tros/share/hobot_mipi_cam/config/132GS_calibration.yaml (文件名需与驱动配置匹配)。
run_cam.sh 或 .launch.py找到启动相机节点的脚本(通常是 run_cam.sh 或其调用的 hobot_mipi_cam.launch.py),修改以下参数:
关键参数设置:
| 参数名 | 推荐值 | 说明 |
|---|---|---|
mipi_gdc_enable |
True |
核心开关:启用硬件去畸变 |
camera_calibration_file |
/path/to/your/calib.yaml |
指向你的标定文件路径 |
out_format |
bgr8 |
建议输出 BGR8 以便直接查看 (之前已解决) |
修改示例 (run_cam.sh 或启动命令):
# 方式 A: 如果脚本支持直接传参
bash run_cam.sh \
--mipi_gdc_enable True \
--camera_calibration_file /home/your_user/calibration/132GS_calibration.yaml \
--out_format bgr8
# 方式 B: 如果是修改 .launch.py 文件 (查找 hobot_mipi_cam 节点)
# 在 Python 文件中修改参数声明:
Node(
package='hobot_mipi_cam',
executable='hobot_mipi_cam_node',
parameters=[{
'mipi_gdc_enable': True, # 开启 GDC
'camera_calibration_file': '/home/your_user/calibration/132GS_calibration.yaml', # 标定文件路径
'pixel_format': 'bgr8', # 输出格式
# 其他参数...
}]
)
启动相机后,订阅图像话题并观察:
# 1. 确认话题图像格式
ros2 topic echo /camera/image_raw --field encoding
# 应输出: bgr8
# 2. 使用 rqt_image_view 或 rviz2 查看
rqt_image_view /camera/image_raw
# 或使用之前设置的 /rectify_left_image (如果 stereo 节点也订阅了驱动输出的话)
观察标准:
| 问题 | 原因 | 解决方法 |
|---|---|---|
| GDC 开启后黑屏/报错 | 标定文件路径错误或格式不匹配 | 检查日志 ros2 launch ... 输出,确认 camera_calibration_file 路径正确且文件存在 |
| 图像依然有畸变 | 标定文件内参不准或未生效 | 检查日志中是否有 GDC init success 字样;确认 distortion_coefficients 不为 0 |
| 帧率下降 | GDC 占用硬件资源 | X5 的 GDC 是硬件加速,通常不影响帧率,检查是否同时进行了其他重负载操作 |
| 找不到标定文件 | 默认路径不对 | 显式在 launch 文件中指定绝对路径,不要依赖相对路径 |
camera_calibration 生成 ost.yaml。ost.yaml,使用 GDC Tool 转为 .bin (咨询官方文档确认是否必须)。run_cam.sh,设置 mipi_gdc_enable=True 和 camera_calibration_file 路径。提示:如果你之前修改过 out_format=bgr8 解决了标定问题,那么现在只需在此基础上增加 mipi_gdc_enable=True 和标定文件路径即可直接获得去畸变图像,无需再经过 StereoNet 处理。
执行run_cam.sh,gdc_enable=True,log也打印了加载成功自己的calib.yaml文件,也打印了执行gdc,但是echo camera_info发现distortion里都是0,并且打印的内参数值也不是我calib.yaml里的值
你遇到的现象非常典型:GDC 硬件去畸变已生效(日志打印成功),但 ROS camera_info Topic 里的参数却是默认的(畸变系数为 0,内参不匹配)。
这是 RDK X5 相机驱动的一个设计特性(或者说是“行为不一致”):
.yaml 文件,并成功应用了去畸变算法(所以图像直了)。hobot_mipi_cam):并没有自动将你加载的 .yaml 文件里的参数填充到发布的 camera_info Topic 中。
既然驱动不自动发布,你需要手动发布正确的 camera_info,或者修改驱动配置让它发布。
camera_info_publisher 手动注入(最推荐,最稳定)不要依赖相机驱动发布内参,而是启动一个独立的节点,把你标定好的 ost.yaml 发布出去。这样无论驱动内部怎么变,下游拿到的参数永远是你标定的。
步骤:
ost.yaml(由 camera_calibration 生成)。mipi_gdc_enable=True):bash run_cam.sh --mipi_gdc_enable True --out_format bgr8
source /opt/tros/setup.bash
# 发布左目内参 (注意 remap 到相机驱动实际发布的 topic 名称)
ros2 run camera_calibration camera_info_publisher \
--ros-args \
-p url:=file:///home/你的用户/标定目录/left_ost.yaml \
-p frame_id:=camera_link \
-p camera_name:=left_camera \
--remap camera_info:=/camera/left/camera_info # 关键:需匹配 run_cam.sh 发布的 topic
(注:如果是双目,需要分别发布左右目,topic 名称通常是 /camera/left/camera_info 和 /camera/right/camera_info,请用 ros2 topic list 确认)效果:
重要提示:如果你开启 GDC 后图像已经无畸变,但
camera_info里还有畸变系数,某些算法(如 StereoNet)可能会二次去畸变导致图像错误。
最佳实践:如果 GDC 已去畸变,建议在发布的ost.yaml中将distortion_coefficients全改为0.0,但保留正确的camera_matrix(内参)。
如果你希望相机驱动自动发布正确的参数,需要修改 .launch.py 文件。
/opt/tros/share/hobot_mipi_cam/launch/hobot_mipi_cam.launch.py 或类似路径。Node 定义中,添加 camera_info_url 参数:Node(
package='hobot_mipi_cam',
executable='hobot_mipi_cam_node',
parameters=[{
'mipi_gdc_enable': True,
'camera_calibration_file': '/home/你的用户/标定目录/132GS_calibration.yaml',
'camera_info_url': 'file:///home/你的用户/标定目录/ost.yaml', # 新增这行
# 其他参数...
}]
)
注意:部分旧版本驱动可能不支持 camera_info_url 参数,如果无效请回退到方案一。
如果驱动确实尝试读取但读错了,可能是 YAML 格式问题。
lens_distortion 等)。camera_matrix, distortion_coefficients 等)。确认你的 calib.yaml 包含以下标准字段:
image_width: 1280
image_height: 720
camera_name: "camera"
camera_matrix:
rows: 3
cols: 3
data: [fx, 0, cx, 0, fy, cy, 0, 0, 1]
distortion_model: "plumb_bob"
distortion_coefficients:
rows: 1
cols: 5
data: [k1, k2, p1, p2, k3]
如果字段名不对,驱动会静默失败并使用默认值。
camera_info_publisher 节点,强行覆盖 Topic 数据。distortion_coefficients 设为 [0, 0, 0, 0, 0](因为图像已经由 GDC 去畸变了),但保留正确的 camera_matrix (fx, fy, cx, cy)。run_stereo.sh 时,设置 mipi_gdc_enable=True(告诉它图像已经处理过)。calib_method=ros,让它订阅你手动发布的那个正确的 camera_info。这样就能保证:图像是直的,参数是对的,深度计算也是准的。
echo camera_info怎么突然没任何输出了
camera_info 突然没输出,说明相机节点可能没有正常发布该 Topic。按以下步骤快速排查:
# 1. 列出所有包含 camera_info 的 topic
ros2 topic list | grep camera_info
# 2. 列出所有包含 camera 的 topic
ros2 topic list | grep camera
常见 Topic 名称(根据你的启动方式可能不同):
| 启动方式 | 可能的 camera_info topic |
|---|---|
run_cam.sh (单目) |
/camera/camera_info 或 /camera_info |
run_cam.sh (双目) |
/camera/left/camera_info + /camera/right/camera_info |
run_stereo.sh |
/image_combine_raw/left/camera_info + /image_combine_raw/right/camera_info |
# 1. 查看节点列表
ros2 node list | grep cam
# 2. 查看节点状态
ros2 node info /mipi_cam # 或你的节点名称
# 3. 查看图像 topic 是否有数据
ros2 topic hz /camera/image_raw # 替换为你实际的图像 topic
如果图像 topic 也没有数据 → 相机节点启动失败,检查日志。
重新运行 run_cam.sh,观察日志中是否有以下关键信息:
bash run_cam.sh --mipi_gdc_enable True --out_format bgr8
关键日志检查:
| 日志内容 | 含义 |
|---|---|
GDC init success |
GDC 硬件初始化成功 |
camera_calibration_file loaded |
标定文件加载成功 |
publish camera_info |
正在发布 camera_info |
ERROR / Failed |
有错误,需要关注具体信息 |
如果之前能输出现在不能,可能是配置被修改了。检查 run_cam.sh 或 .launch.py 中是否有以下参数:
# 在 .launch.py 中确认是否有 camera_info 相关配置
parameters=[{
'mipi_gdc_enable': True,
'camera_calibration_file': '/path/to/calib.yaml',
'publish_camera_info': True, # 确认这个参数是否存在且为 True
}]
不依赖相机驱动发布,自己启动一个发布节点:
# 终端 1: 启动相机
bash run_cam.sh --mipi_gdc_enable True --out_format bgr8
# 终端 2: 发布标定参数
ros2 run camera_calibration camera_info_publisher \
--ros-args \
-p url:=file:///home/你的用户/标定目录/ost.yaml \
-p frame_id:=camera_link \
--remap camera_info:=/camera/camera_info # 替换为实际 topic 名称
# 查看是否有残留的相机进程
ps aux | grep mipi_cam
# 如果有,杀掉后重启
killall -9 mipi_cam_node
# 然后重新运行 run_cam.sh
如果上述步骤无法解决,请提供:
# 1. topic 列表
ros2 topic list | grep -E "camera|image"
# 2. 节点列表
ros2 node list | grep cam
# 3. run_cam.sh 启动时的完整日志(最后 20 行)
# 4. 你 echo 的具体命令
echo /xxx/camera_info # 你用的是哪个 topic 名称?
这样我可以帮你精确定位问题所在。
[WARN] [1779270905.584900072] [mipi_node]:
node params:
config_path: /opt/tros/humble/lib/mipi_cam/config/
video_device_name:
channel: 2
channel2: 0
camera_info_url:
camera_calibration_file_path: /userdata/rdk_cam/SC132gs_dual_calibration.yaml
out_format_name: bgr8
gdc_bin_file:
image_width: 1280
image_height: 1088
sub_image_width: 960
sub_image_height: 540
framerate: 10
rotation: 90.000000
device_mode: dual
dual_combine: 1
lpwm_enable: true
gdc_enable: true
frame_ts_type: realtime
frame_id: default_cam
link_type: 0
link_port: 0
io_method_name: ros
cal_alpha: 0.000
[WARN] [1779270905.585438113] [mipi_factory]: This is’t support device type(), start defaule capture.
[INFO] [1779270905.586788236] [mipi_cap]: this board support mipi:
[INFO] [1779270905.586837486] [mipi_cap]: host 0
[INFO] [1779270905.586865736] [mipi_cap]: host 2
[INFO] [1779270905.587111611] [mipi_cam]: cal_file:/userdata/rdk_cam/SC132gs_dual_calibration.yaml
[INFO] [1779270905.587924652] [mipi_cam]: Camera calibration file did not specify distortion model, assuming plumb bob
index: 0 sensor_name: sc230ai-30fps config_file:linear_1920x1080_raw10_30fps_1lane.c
index: 1 sensor_name: sc132gs-1280p config_file:linear_1088x1280_raw10_30fps_1lane.c
index: 2 sensor_name: ov5647 config_file:linear_1920x1080_raw10_30fps_2lane.c
index: 3 sensor_name: imx219-30fps config_file:linear_1920x1080_raw10_30fps_2lane.c
index: 4 sensor_name: imx477-1920x1080-50fps config_file:linear_1920x1080_raw12_50fps_2lane.c
index: 5 sensor_name: imx415-20fps-2lane config_file:linear_3840x2160_raw10_30fps_2lane.c
Searching camera sensor on device: /proc/device-tree/soc/cam/vcon@0 i2c bus: 6 mipi rx phy: 0
WARN: Sensor Name: sc230ai-30fps, Expected Chip ID: 0xCB34, Actual Chip ID Read: 0x00
WARN: Sensor Name: sc230ai-30fps, Expected Chip ID: 0xCB34, Actual Chip ID Read: 0x132
WARN: Sensor Name: sc132gs-1280p, Expected Chip ID: 0x132, Actual Chip ID Read: 0x00
INFO: vp_sensor_detect_2 Support sensor index:0, sensor_name:sc132gs-1280p on mipi rx csi 0, i2c addr 0x32, config_file:linear_1088x1280_raw10_30fps_1lane.c
Searching camera sensor on device: /proc/device-tree/soc/cam/vcon@2 i2c bus: 4 mipi rx phy: 2
WARN: Sensor Name: sc230ai-30fps, Expected Chip ID: 0xCB34, Actual Chip ID Read: 0x00
WARN: Sensor Name: sc230ai-30fps, Expected Chip ID: 0xCB34, Actual Chip ID Read: 0x00
WARN: Sensor Name: sc132gs-1280p, Expected Chip ID: 0x132, Actual Chip ID Read: 0x00
WARN: Sensor Name: sc132gs-1280p, Expected Chip ID: 0x132, Actual Chip ID Read: 0x00
INFO: vp_sensor_detect_2 Support sensor index:2, sensor_name:sc132gs-1280p on mipi rx csi 2, i2c addr 0x33, config_file:linear_1088x1280_raw10_30fps_1lane.c
Searching camera sensor on device: /proc/device-tree/soc/cam/vcon@0 i2c bus: 6 mipi rx phy: 0
WARN: Sensor Name: sc132gs-1280p, Expected Chip ID: 0x132, Actual Chip ID Read: 0x00
INFO: vp_sensor_fixed_mipi_host_1 Found sensor_name:sc132gs-1280p on mipi rx csi 0, i2c addr 0x32, config_file:linear_1088x1280_raw10_30fps_1lane.c
[WARN] [1779270906.475218220] [mipi_cap]: i2c bus: 4, EEPROM FLAG: SZYGSJKJ
[INFO] [1779270906.477199885] [mipi_cap]: ====EepromDrobotHead======
bus: 4
flag: SZYGSJKJ
camType: 1
cal_tpye: 0
ver_main: 1
ver_min: 1
angle: 1
d_num: 8
[INFO] [1779270906.506208768] [mipi_cap]: ====m_d_info_l======
width: 1280
height: 1088
fx: 668.227722
fx: 668.227722
fy: 668.109619
cy: 541.561401
[INFO] [1779270906.506423393] [mipi_cap]: ====m_d_info_r======
width: 1280
height: 1088
fx: 658.154358
fx: 658.154358
fy: 658.159058
cy: 541.673401
[INFO] [1779270906.506489851] [mipi_cap]: ====r_t_info======
r11: 0.999988
r12: 0.004470
r13: 0.001999
r21: -0.004469
r22: 0.999990
r23: -0.000624
r31: -0.002002
r32: 0.000615
r33: 0.999998
tx: -79.939400
ty: 0.461299
tz: 0.277197
[WARN] [1779270906.506907517] [mipi_cap]: => ================== left awb otp data ==================
[WARN] [1779270906.506947226] [mipi_cap]: left_awb_otp_data_.awb_golden_data[0].rg_ratio: 1401
[WARN] [1779270906.506979142] [mipi_cap]: left_awb_otp_data_.awb_golden_data[0].bg_ratio: 340
[WARN] [1779270906.507008226] [mipi_cap]: left_awb_otp_data_.awb_golden_data[1].rg_ratio: 1094
[WARN] [1779270906.507035892] [mipi_cap]: left_awb_otp_data_.awb_golden_data[1].bg_ratio: 403
[WARN] [1779270906.507063934] [mipi_cap]: left_awb_otp_data_.awb_golden_data[2].rg_ratio: 880
[WARN] [1779270906.507091309] [mipi_cap]: left_awb_otp_data_.awb_golden_data[2].bg_ratio: 548
[WARN] [1779270906.507120267] [mipi_cap]: left_awb_otp_data_.awb_data[0].rg_ratio: 1416
[WARN] [1779270906.507147559] [mipi_cap]: left_awb_otp_data_.awb_data[0].bg_ratio: 334
[WARN] [1779270906.507175309] [mipi_cap]: left_awb_otp_data_.awb_data[1].rg_ratio: 1106
[WARN] [1779270906.507203059] [mipi_cap]: left_awb_otp_data_.awb_data[1].bg_ratio: 395
[WARN] [1779270906.507232392] [mipi_cap]: left_awb_otp_data_.awb_data[2].rg_ratio: 889
[WARN] [1779270906.507259934] [mipi_cap]: left_awb_otp_data_.awb_data[2].bg_ratio: 535
[WARN] [1779270906.507346975] [mipi_cap]: => ================== right awb otp data ==================
[WARN] [1779270906.507377517] [mipi_cap]: right_awb_otp_data_.awb_golden_data[0].rg_ratio: 1401
[WARN] [1779270906.507405767] [mipi_cap]: right_awb_otp_data_.awb_golden_data[0].bg_ratio: 340
[WARN] [1779270906.507433308] [mipi_cap]: right_awb_otp_data_.awb_golden_data[1].rg_ratio: 1094
[WARN] [1779270906.507460475] [mipi_cap]: right_awb_otp_data_.awb_golden_data[1].bg_ratio: 403
[WARN] [1779270906.507488183] [mipi_cap]: right_awb_otp_data_.awb_golden_data[2].rg_ratio: 880
[WARN] [1779270906.507514933] [mipi_cap]: right_awb_otp_data_.awb_golden_data[2].bg_ratio: 548
[WARN] [1779270906.507806058] [mipi_cap]: right_awb_otp_data_.awb_data[0].rg_ratio: 1432
[WARN] [1779270906.507840350] [mipi_cap]: right_awb_otp_data_.awb_data[0].bg_ratio: 348
[WARN] [1779270906.507869475] [mipi_cap]: right_awb_otp_data_.awb_data[1].rg_ratio: 1120
[WARN] [1779270906.507897558] [mipi_cap]: right_awb_otp_data_.awb_data[1].bg_ratio: 410
[WARN] [1779270906.507925100] [mipi_cap]: right_awb_otp_data_.awb_data[2].rg_ratio: 900
[WARN] [1779270906.507953391] [mipi_cap]: right_awb_otp_data_.awb_data[2].bg_ratio: 559
[WARN] [1779270906.507980183] [mipi_cap]: => ========================================================
[INFO] [1779270906.522123333] [mipi_cap]: ===stetreo calibration===
gdc_width_scale : 1
gdc_height_scale : 1
Kl :
[656.7575224009456, 0, 636.3995967335052;
0, 656.3766938297126, 540.4756754786636;
0, 0, 1]
Dl :
[-0.3299087609588053, 0.1366269992103298, -0.000135318131175941, -9.84710031787936e-05, -0.02937890519777009, 0.0001405065239949476, 4.560677311111928e-05, 4.667085000242849e-05]
Kr :
[659.0957261498398, 0, 632.5403313828651;
0, 658.9494113212542, 539.3174440945205;
0, 0, 1]
Dr :
[-0.3364821198808888, 0.1464031938938395, -9.945169177922777e-06, -0.0002291888331273915, -0.03406702140405501, -4.29001168046378e-05, -0.0002310372582815102, 0.0001254511419107697]
R_rl :
[0.9999953142616191, -0.002907409016669017, 0.0009583462919259559;
0.002906859188535815, 0.9999956099808883, 0.0005746204042934068;
-0.0009600127413120272, -0.0005718319340480337, 0.9999993756916929]
t_rl :
[-0.079168011922606;
0.0002710668686210687;
0.00333092179027396]
[WARN] [1779270906.523189749] [mipi_cap]: Target FOV 0.00° out of valid range [85.79°, 132.42°]
[WARN] [1779270906.523366749] [mipi_cap]: Use default alpha=0.0 (target FOV invalid)
[INFO] [1779270906.557143502] [mipi_cap]: ===Corrected parameters===
Rl :
[0.999135942994594, -0.006301666912573564, -0.04108109553585833;
0.006314730227134835, 0.9999800441762919, 0.0001882321424095503;
0.04107908955249437, -0.0004474855348523314, 0.9991557977403895]
Rr :
[0.9991102129125855, -0.003420897787433496, -0.04203664962976757;
0.003407530032672816, 0.9999941184384002, -0.0003896507192395557;
0.04203773534390663, 0.0002460628669746228, 0.9991159933962729]
Pl :
[688.8245310324257, 0, 687.7464141845703, 0;
0, 688.8245310324257, 540.0140228271484, 0;
0, 0, 1, 0]
Pr :
[688.8245310324257, 0, 687.7464141845703, -54.58143454102571;
0, 688.8245310324257, 540.0140228271484, 0;
0, 0, 1, 0]
[INFO] [1779270906.684268690] [mipi_cap]: left_camera_gdc bin_buf_size = 9220
[INFO] [1779270906.785651282] [mipi_cap]: right_camera_gdc bin_buf_size = 9364
[INFO] [1779270906.786256365] [mipi_cap]: ===Corrected stetreo calibration ===
Kl :
[656.7575224009456, 0, 636.3995967335052;
0, 656.3766938297126, 540.4756754786636;
0, 0, 1]
Dl :
[-0.3299087609588053, 0.1366269992103298, -0.000135318131175941, -9.84710031787936e-05, -0.02937890519777009, 0.0001405065239949476, 4.560677311111928e-05, 4.667085000242849e-05]
Kr :
[659.0957261498398, 0, 632.5403313828651;
0, 658.9494113212542, 539.3174440945205;
0, 0, 1]
Dr :
[-0.3364821198808888, 0.1464031938938395, -9.945169177922777e-06, -0.0002291888331273915, -0.03406702140405501, -4.29001168046378e-05, -0.0002310372582815102, 0.0001254511419107697]
R_rl :
[0.9999953142616191, -0.002907409016669017, 0.0009583462919259559;
0.002906859188535815, 0.9999956099808883, 0.0005746204042934068;
-0.0009600127413120272, -0.0005718319340480337, 0.9999993756916929]
t_rl :
[-0.079168011922606;
0.0002710668686210687;
0.00333092179027396]
calib file width, height : 1280,1088
gdc_width_scale, gdc_height_scale : 1, 1
rectify [f, cx, cy, baseline]: [688.825, 687.746, 540.014, 0.0792385]
[INFO] [1779270906.802108013] [mipi_cap]: csi0 ignore mclk ex attr, because not config mclk.
[INFO] [1779270906.802816471] [mipi_cap]: lpwm_enable: 1
[INFO] [1779270906.802889179] [mipi_cap]: lpwm_index: 0, trigger_source: 0, trigger_mode: 0, period: 100000, offset: 10, duty_time: 100, threshold: 0, adjust_step: 0
[INFO] [1779270906.803017345] [mipi_cap]: lpwm_index: 1, trigger_source: 0, trigger_mode: 0, period: 100000, offset: 10, duty_time: 100, threshold: 0, adjust_step: 0
[INFO] [1779270906.803059345] [mipi_cap]: lpwm_index: 2, trigger_source: 0, trigger_mode: 0, period: 100000, offset: 10, duty_time: 100, threshold: 0, adjust_step: 0
[INFO] [1779270906.803094262] [mipi_cap]: lpwm_index: 3, trigger_source: 0, trigger_mode: 0, period: 100000, offset: 10, duty_time: 100, threshold: 0, adjust_step: 0
[WARN] [1779270906.813351417] [mipi_cap]: X5 start gdc rotation and cal.
Searching camera sensor on device: /proc/device-tree/soc/cam/vcon@2 i2c bus: 4 mipi rx phy: 2
WARN: Sensor Name: sc132gs-1280p, Expected Chip ID: 0x132, Actual Chip ID Read: 0x00
WARN: Sensor Name: sc132gs-1280p, Expected Chip ID: 0x132, Actual Chip ID Read: 0x00
INFO: vp_sensor_fixed_mipi_host_1 Found sensor_name:sc132gs-1280p on mipi rx csi 2, i2c addr 0x33, config_file:linear_1088x1280_raw10_30fps_1lane.c
[INFO] [1779270907.624063948] [mipi_cap]: csi2 ignore mclk ex attr, because not config mclk.
[INFO] [1779270907.624591155] [mipi_cap]: lpwm_enable: 1
[INFO] [1779270907.624632822] [mipi_cap]: lpwm_index: 0, trigger_source: 0, trigger_mode: 0, period: 100000, offset: 10, duty_time: 100, threshold: 0, adjust_step: 0
[INFO] [1779270907.624668364] [mipi_cap]: lpwm_index: 1, trigger_source: 0, trigger_mode: 0, period: 100000, offset: 10, duty_time: 100, threshold: 0, adjust_step: 0
[INFO] [1779270907.624701322] [mipi_cap]: lpwm_index: 2, trigger_source: 0, trigger_mode: 0, period: 100000, offset: 10, duty_time: 100, threshold: 0, adjust_step: 0
[INFO] [1779270907.624734322] [mipi_cap]: lpwm_index: 3, trigger_source: 0, trigger_mode: 0, period: 100000, offset: 10, duty_time: 100, threshold: 0, adjust_step: 0
[WARN] [1779270907.632198855] [mipi_cap]: X5 start gdc rotation and cal.
[WARN] [1779270908.283946067] [mipi_cam]: [init]->cap sc132gs-1280p init success.
[INFO] [1779270908.284144317] [mipi_node]: [MipiCamNode::init]->Initing ‘/opt/tros/humble/lib/mipi_cam/config/’ at 1280x1088 via ros at 10 FPS
[INFO] [1779270908.284239150] [mipi_cap]: get calibration camera info
[INFO] [1779270908.291772767] [mipi_cap]: get calibration camera info
[INFO] [1779270908.305515709] [mipi_cam]: [start]->w:h=1280:1088.
[INFO] [1779270908.306426208] [mipi_node]: starting timer 100
=== Detected IIO Devices ===
Device: iio:device0 | Name: 34190000.adc
[INFO] [1779270908.337337798] [mipi_cap]: capture a frame, handle: 493413, id: 0, timestamps: 24193.896891, current uptime: 24193.810954, sys_timestamps: 1779270908.304047, HW timestamp: 24198.947293, trig timestamp: 24198.937433,current timestamp: 1779270908.337277, laps ms: 33.229589ms, exposure_time: 9.860000ms.
[INFO] [1779270908.355352611] [mipi_cam]: publish laps ms= 51
[INFO] [1779270908.355678944] [mipi_cam]: getImage channel=left, enc=bgr8, width=1280, height=1088, step=3840, ts=1779270908.304047, laps ms=49
[INFO] [1779270908.437987266] [mipi_cap]: capture a frame, handle: 493413, id: 1, timestamps: 24193.995593, current uptime: 24193.911632, sys_timestamps: 1779270908.402750, HW timestamp: 24199.047293, trig timestamp: 24199.037434,current timestamp: 1779270908.437954, laps ms: 35.204172ms, exposure_time: 9.859000ms.
[INFO] [1779270908.443616135] [mipi_cap]: capture a frame, handle: 231269, id: 0, timestamps: 24193.996905, current uptime: 24193.917271, sys_timestamps: 1779270908.404061, HW timestamp: 24199.047294, trig timestamp: 24199.037434,current timestamp: 1779270908.443594, laps ms: 39.532423ms, exposure_time: 9.860000ms.
[INFO] [1779270908.452195417] [mipi_cam]: publish laps ms= 50
[INFO] [1779270908.452433833] [mipi_cam]: getImage channel=left, enc=bgr8, width=1280, height=1088, step=3840, ts=1779270908.402750, laps ms=86
[INFO] [1779270908.537599319] [mipi_cap]: capture a frame, handle: 231269, id: 1, timestamps: 24194.095594, current uptime: 24194.011254, sys_timestamps: 1779270908.502750, HW timestamp: 24199.147294, trig timestamp: 24199.137435,current timestamp: 1779270908.537577, laps ms: 34.826517ms, exposure_time: 9.859000ms.
[INFO] [1779270908.541372356] [mipi_cap]: capture a frame, handle: 493413, id: 2, timestamps: 24194.095948, current uptime: 24194.015030, sys_timestamps: 1779270908.502747, HW timestamp: 24199.147651, trig timestamp: 24199.137435,current timestamp: 1779270908.541352, laps ms: 38.604975ms, exposure_time: 10.216000ms.
[INFO] [1779270908.553143093] [mipi_cam]: publish laps ms= 51
[INFO] [1779270908.553516967] [mipi_cam]: getImage channel=left, enc=bgr8, width=1280, height=1088, step=3840, ts=1779270908.502747, laps ms=96
[INFO] [1779270908.637684538] [mipi_cap]: capture a frame, handle: 231269, id: 2, timestamps: 24194.195952, current uptime: 24194.111339, sys_timestamps: 1779270908.602751, HW timestamp: 24199.247652, trig timestamp: 24199.237436,current timestamp: 1779270908.637662, laps ms: 34.910440ms, exposure_time: 10.216000ms.
[INFO] [1779270908.641388367] [mipi_cap]: capture a frame, handle: 493413, id: 3, timestamps: 24194.195995, current uptime: 24194.115049, sys_timestamps: 1779270908.602794, HW timestamp: 24199.247652, trig timestamp: 24199.237436,current timestamp: 1779270908.641371, laps ms: 38.577318ms, exposure_time: 10.216000ms.
这是我的log信息,请帮我分析为什么/image_combine_raw的图像还是没去畸变的
根据你提供的日志,我发现了关键问题:
从日志可以看到:
[INFO] [mipi_cap]: left_camera_gdc bin_buf_size = 9220
[INFO] [mipi_cap]: right_camera_gdc bin_buf_size = 9364
[WARN] [mipi_cap]: X5 start gdc rotation and cal.
GDC 确实初始化成功了,标定参数也从 EEPROM 读取了。
camera_info_url 是空的 node params:
config_path: /opt/tros/humble/lib/mipi_cam/config/
camera_info_url: # ← 这里是空的!
camera_calibration_file_path: /userdata/rdk_cam/SC132gs_dual_calibration.yaml
这就是 camera_info topic 没有输出的原因 —— 驱动没有配置发布标定参数的路径。
日志显示你运行的是 run_cam.sh(相机驱动),但你说检查的是 /image_combine_raw —— 这个 topic 是 run_stereo.sh (StereoNet) 发布的,不是相机驱动直接发布的。
# 列出所有相机相关的 topic
ros2 topic list | grep -E "camera|image"
# 确认 run_cam.sh 实际发布的 topic 名称
ros2 topic list | grep image_raw
run_cam.sh 通常发布的 topic:
/camera/image_raw 或 /camera/left/image_raw + /camera/right/image_raw/camera/camera_info 或 /camera/left/camera_info + /camera/right/camera_info/image_combine_raw 是 StereoNet 处理后的 topic,需要运行 run_stereo.sh 才会有。
不要依赖 camera_info,直接视觉验证:
# 1. 找到相机驱动实际发布的图像 topic
ros2 topic list | grep image_raw
# 2. 用 rqt_image_view 查看
rqt_image_view /camera/left/image_raw # 替换为你实际的 topic
# 3. 拿棋盘格或直线物体靠近相机边缘观察
# 如果直线是直的 = GDC 生效
# 如果直线是弯的 = GDC 未生效
camera_info 不发布的问题既然 camera_info_url 是空的,有两种方案:
编辑 run_cam.sh 或其调用的 .launch.py 文件,添加 camera_info_url 参数:
# 在 run_cam.sh 中添加参数
bash run_cam.sh \
--mipi_gdc_enable True \
--out_format bgr8 \
--camera_info_url file:///userdata/rdk_cam/SC132gs_dual_calibration.yaml
或者修改 launch 文件(/opt/tros/humble/lib/mipi_cam/launch/ 下):
parameters=[{
'mipi_gdc_enable': True,
'camera_calibration_file_path': '/userdata/rdk_cam/SC132gs_dual_calibration.yaml',
'camera_info_url': 'file:///userdata/rdk_cam/SC132gs_dual_calibration.yaml', # 新增
'out_format_name': 'bgr8',
}]
camera_info(最稳定)# 终端 1: 运行相机
bash run_cam.sh --mipi_gdc_enable True --out_format bgr8
# 终端 2: 独立发布标定参数
ros2 run camera_calibration camera_info_publisher \
--ros-args \
-p url:=file:///userdata/rdk_cam/SC132gs_dual_calibration.yaml \
-p frame_id:=camera_link \
--remap camera_info:=/camera/left/camera_info # 替换为实际 topic 名称
/image_combine_raw(StereoNet 输出)你需要运行 run_stereo.sh 而不是 run_cam.sh:
bash run_stereo.sh \
--mipi_gdc_enable True \
--calib_method ros \
--publish_rectify_bgr True \
--codec_in_format bgr8
然后订阅:
ros2 topic echo /image_combine_raw/left/camera_info
rqt_image_view /image_combine_raw/left/rectify_image
请执行以下命令并提供结果:
# 1. 确认当前运行的节点
ros2 node list | grep -E "cam|stereo"
# 2. 确认所有图像 topic
ros2 topic list | grep image
# 3. 确认图像 topic 是否有数据
ros2 topic hz /camera/left/image_raw # 替换为你实际的 topic
# 4. 确认 camera_info topic
ros2 topic list | grep camera_info
| 现象 | 原因 | 解决 |
|---|---|---|
camera_info 无输出 |
camera_info_url 参数为空 |
添加该参数或用独立节点发布 |
/image_combine_raw 无数据 |
这是 StereoNet 的 topic,run_cam.sh 不发布 |
运行 run_stereo.sh 或订阅相机驱动的原始 topic |
| 图像看起来没去畸变 | 可能订阅了错误的 topic,或 GDC 参数未正确应用 | 视觉验证 + 确认 topic 名称 |
先确认你实际订阅的 topic 名称是否正确,这是最关键的一步!