x5 132gs想自行标定,出流后想看到实时图像但打不开http://192.168.127.10:8000/TogetheROS/

好的,那就不用yaml,走camera_info
hobot_stereonet 版本是 2.5.5
你说的‘PLY 都得自己反投影——官方链路本身只输出左视图对应的视差图和深度图,不含点云文件’‘点云都得自己反投影是什么意思呢?,地瓜官方的hobot_stereonet不生成点云文件吗?我记得我之前保存过单帧的点云文件的。
地瓜官方有能生成点云的算法吗?

我输入:ros2 topic echo /image_combine_raw/right/camera_info --once
日志:WARNING: topic [/image_combine_raw/right/camera_info] does not appear to be published yet
Could not determine the type for the passed topic
接下来应该怎么做呢?

1. camera_info 那个报错是话题根本没发,不是类型问题。 Could not determine the type 表示 /image_combine_raw/right/camera_info 不在当前 ROS 图里。先确认:

ros2 topic list | grep -i camera_info
ros2 node list

拼接图的标定话题从 TROS 2.5.1 起才改名为 image_combine_raw/left|right/camera_info(版本发布记录 2.5.1),你 2.5.5 版本够;列表里为空,就说明你终端 A 那个 ros2 run mipi_cam mipi_cam 这次没把标定信息发出来。此外官方 magicbox 那条命令是 run_stereo.sh 自己拉起 magicbox 的相机节点,--camera_info_topic /image_combine_raw/right/camera_info 指的是那套节点发的话题(双目深度估计)。所以先停掉终端 A 的 mipi_cam(两个进程抢同一路 sensor),按官方那条命令起,再 echo 才是能对上的一份。要让 stereonet 用你自标的结果,就自己发:写个小节点往 /my_calib/left/camera_info、/my_calib/right/camera_info 发 sensor_msgs/CameraInfo,K 填 664.43/664.70/542.56/640.03,D 填完整 5 个,右目 P 的 P[0,3] = -fx*0.08002 ≈ -53.17,再用 --camera_info_topic /my_calib/right/camera_info 重跑。width/height 必须和 stereonet 实际消费的分辨率一致,别拿 1088×1280 的 K 直接套 640×352 的推理结果。

2. “自己反投影”就是把深度图的每个像素还原成 3D 点,公式只有三行:X=(u-cx)·Z/fx、Y=(v-cy)·Z/fy,基线只在前一步视差→深度时用到(Z=fx·b/d)。写成 PLY 也就是十几行:

u, v = np.meshgrid(np.arange(w), np.arange(h))
valid = depth > 0                      # depth: float32,单位米
X = (u - cx) * depth / fx; Y = (v - cy) * depth / fy
pts = np.stack([X[valid], Y[valid], depth[valid]], -1)   # 左目坐标系,米

3. stereonet 的产物只到视差图和深度图。 官方原话是“输出为左视图对应的视差图和深度图”,X5 上只有 V2.4_int8 和 V2.4_int16 两档量化(15/23fps),是同一个网络的两种精度,不是多条网络;PLY 不在它的输出里。你之前保存过的单帧点云,大概率是你自己那段 StereoSGBM + cv2.reprojectImageTo3D 写的(SGBM 是 OpenCV 传统块匹配,跟 stereonet 无关)——把当时那条命令或脚本名贴一下就能确认。地瓜这条双目光路上没有额外要跑的“点云算法”,深度图 + 内参反投影就够了;ROS 侧若已装 depth_image_proc,point_cloud_xyz 也能直接把深度图 + camera_info 转成 PointCloud2。

4. 你要的四件套:把 save_stereo.py 里的视差来源从 SGBM 换成订阅 stereonet 的深度话题,切左右原图、remap 出矫正左图、存 PLY 三段代码不用改。先 ros2 topic list | grep -i -E "depth|disparity" 拿到实际话题名,再 ros2 topic echo <话题> --once 看 width/height——深度图通常不是原图分辨率(网络输入 640×352),点云和 remap 的内参要按这个尺寸换算 fx/cx/cy,否则整幅距离会整体缩放。

你现在 stereonet 起来后 ros2 topic list 里有哪些 depth/disparity 话题?贴出来我按实际话题名给你保存和反投影那段的完整改法。

有,hobot_stereonet 2.5.5 就支持点云话题和 .pcd 保存,不必另写点云算法。自标定用 calib_method:=custom、stereo_calib_file_path:=标定文件绝对路径;输入原图时关闭 GDC,不必等当前未发布的 camera_info 话题。

不过你这组 T 主要在 Y 方向,先把左右原图统一转成水平双目方向后重新标定,不能只交换 T 的分量;YAML 用 OpenCV FileStorage 格式,并保留完整的 5 个畸变系数,别截掉 k3。运行时图像方向须与标定一致。

正常出深度后,执行 ros2 param set /StereoNetNode save_result_once true,可保存该次处理的矫正图、深度和点云;还要保存原图时启用 publish_origin_enable:=True。

2.5.5 官方脚本:https://github.com/D-Robotics/hobot_stereonet/blob/tros_2.5.5/script/run_stereo.sh

1. Could not determine the type 只是说明这个话题此刻没有节点在发,和你的用法无关。 先确认是名字不对还是压根没发:

source /opt/tros/humble/setup.bash
ros2 topic list | grep -iE "camera_info|cloud|depth|disparity"
ros2 node list
  • 出现的是别的名字:echo 那个实际名字。
  • 一条都没有:说明当前在跑的相机节点没发布标定信息,或者你终端A 手动起的 mipi_cam 已经停了。run_stereo.sh 自己会拉起相机节点,两个进程抢同一路 sensor,所以先停掉你手动起的那条,在 run_stereo.sh 运行期间再 echo,那份才对得上。

另外有一点要先定清:本贴里对 2.5.5 的实测反馈是 calib_method:=custom 走 stereo_calib_file_path,且 custom 模式不再订阅 CameraInfo(上游为修参数冲突改的)。所以"自标定走 camera_info"这条路能不能成,取决于你这个 2.5.5 节点在 custom 下还订不订阅 CameraInfo——用上面的 ros2 topic list 和后面的 ros2 param list 直接看,别按文档描述硬套。

2. "自己反投影"就是把深度图每个像素还原成三维点,不是另一套算法:视差先转深度 Z=fx·b/d,再 X=(u-cx)·Z/fx、Y=(v-cy)·Z/fy,得到左目坐标系下的 XYZ(米)。网络内部算深度也是这一步的逆过程,"有没有点云文件"只差在它替不替你做完最后这步。

3. 有没有点云输出,用你板上的 2.5.5 现场判定。 我上一轮说"官方链路不含点云"依据的是 magicbox 双目深度估计 里"输出为左视图对应的视差图和深度图"这句描述;但你保存过单帧点云、且本贴实测反馈 2.5.5 有点云话题并支持 .pcd 保存,那就以节点实际行为为准:

ros2 param list | grep -iE "calib|save|pcd"
ros2 param set /StereoNetNode save_result_once true   # 节点名以 node list 为准

出现点云话题就直接订阅它、用 save_result_once 出一组;没有才需要自己反投影。地瓜这条链路上没有额外的"点云算法"包,深度图 + 内参反投影就是点云的全部。

建议的下一步顺序:

  1. 停掉终端A 手动起的 mipi_cam;
  2. 按官方命令起(先不加 custom,跑通默认链路):
cd /userdata/magicbox
source /opt/tros/humble/setup.bash
source app/ros_ws/install/setup.bash
bash app/ros_ws/src/magicbox/hobot_stereonet/script/run_stereo.sh \
  --mipi_rotation 0.0 --stereonet_version v2.4_int8 \
  --camera_info_topic /image_combine_raw/right/camera_info
  1. 在它运行中再执行第 1、3 步那几条命令,把话题名、参数名和 camera_info 的 K/width/height 贴出来。

拿到这些我就能确定你的自标定参数该填进 stereo_calib_file_path 的 yaml,还是靠自己发布 CameraInfo,一次写全。提前说一个坑:你的 T 主要在 Y 轴(上下拼接的 1088×2560),而网络输入是横置的 640×352,极线校正会把图绕光轴转约 90°;更稳的做法是把左右图摆成水平双目方向重标一次,而不是在参数里硬改 T 的分量。

好的,’hobot_stereonet 2.5.5 支持点云话题和 .pcd 保存‘就不用走camera_info话题了对吧?
所以先转成水平方向自行标定后就可以采集同一帧的原始图、矫正后的左图、点云深度图了对吗?麻烦提供正确的思路哈,别绕来绕去了。

T怎么转成水平方向呢?dual_combine:=2你们说是上下拼接,是不是把他转成水平拼接就可以了呢?如果是那怎么转呢?另外有一个问题,虽然是上下拼接的但是我把他对半切分成了左右原始图,为什么还会算成在Y方向呢?
这是我写的采集图片的切分的脚本:
img = self.frame
h, w = img.shape[:2]
assert w == 1088 and h % 2 == 0, (w, h) # 预期 w*h=1088x2560
half = h // 2
ok1 = cv2.imwrite(f’{OUT}/left_{self.count:04d}.png’, img[:half, :])
ok2 = cv2.imwrite(f’{OUT}/right_{self.count:04d}.png’, img[half:, :])
print(f’saved {self.count:04d}, {w}x{h} → 单目 {w}x{half}, write={ok1},{ok2}')

你说的‘ 正常出深度后,执行 ros2 param set /StereoNetNode save_result_once true ,可保存该次处理的矫正图、深度和点云;还要保存原图时启用 publish_origin_enable:=True’是否可以选择保存某一单帧的原始图、矫正后的左图、点云深度图呢?

四问直接答: ①点云不用另写反投影算法,2.5.5 有点云话题和 .pcd 保存(我上一轮“官方链路不含点云”只对应 magicbox 双目深度估计 里“输出视差图和深度图”那句描述,以你板端实际话题为准);②camera_info 不是必经路径,但走 yaml 还是走 camera_info 要看你这个 2.5.5 节点在 calib_method:=custom 下还订不订阅 CameraInfo,一条 node info 就能定;③T 落在 Y 是图像朝向问题,不用重拍,把已存的图转 90° 重标即可;④单帧“原图 + 矫正左图 + 点云”能一次存下来。

1. 为什么切分了 T 还在 Y

T 是在左目图像自身坐标系里表达的。你的单目图是 1088(宽)×1280(高) 的竖幅,实测两目光心在这个坐标系的上下方向相差 80mm,说明这组图里基线是竖的。对半切只是把一张大图分成上下两块,每块自己的 x/y 轴没变,所以 T 仍在 Y——文件名叫 left/right 不代表几何方向。

2. 转成水平双目(复用已有图片,不用重新采集)

import cv2, glob, os
src = os.path.expanduser('~/calib_data'); dst = os.path.expanduser('~/calib_data_h')
os.makedirs(dst, exist_ok=True)
for p in glob.glob(src + '/left_*.png') + glob.glob(src + '/right_*.png'):
    cv2.imwrite(os.path.join(dst, os.path.basename(p)),
                cv2.rotate(cv2.imread(p), cv2.ROTATE_90_CLOCKWISE))

然后同一条命令重跑你的标定脚本,只换目录:--image_dir ~/calib_data_h(棋盘格 11×8 内角点、0.030 不变)。

验收三个数:图像变成 1280×1088;T ≈ (+80, 0, 0) mm,T[0] 必须为正;双目 RMS 仍在 0.2px 量级(旋转只换坐标系,不改变几何)。若 T[0]≈-80,把上面换成 cv2.ROTATE_90_COUNTERCLOCKWISE 再跑一遍,这一步决定了后面视差是正是负。

3. 自标定数据怎么进 stereonet 2.5.5

先判定入口,别猜:

ros2 node list | grep -i stereo
ros2 node info /StereoNetNode | grep -i camera_info
ros2 param list /StereoNetNode
ros2 param get /StereoNetNode stereo_calib_file_path
  • node info 里没有 camera_info 订阅、param list 里有 stereo_calib_file_path:把重标结果写进那个文件(字段照它现在这份默认文件的格式和字段名来,别自己造),畸变系数填完整的 5 个,你这个 k3≈-0.02/-0.03 不能截。启动加 calib_method:=custom stereo_calib_file_path:=<绝对路径>。
  • 若仍订阅 camera_info:就由脚本发 sensor_msgs/CameraInfo,K/D/P 用同一组重标结果(右目 P[0,3]=-fx*0.080),两条路不要混用。

注意标定和运行时的图像朝向必须一致:重标用的是转 90° 的图,运行时也要转(mipi_rotation 或你自己的节点),拿棋盘格在 Web 预览里确认方向,再看深度值正负和大小。

4. 同一帧四件套

ros2 topic list | grep -iE "cloud|depth|disparity"   # 拿到实际点云/深度话题名
ros2 param set /StereoNetNode save_result_once true  # 出一次矫正图、深度、点云

起节点时加 publish_origin_enable:=True 才会同时输出原图。要严格保证“同一帧”,就在一个脚本里同时订阅原图话题和点云话题落盘;点云是左目坐标系、分辨率通常是网络尺寸(不是 1280×1088),后续量尺寸时内参要按那个尺寸换算。

把 ros2 param list /StereoNetNode 的输出和点云话题名贴出来,我按实际参数名给 run_stereo.sh 那条完整命令。

好的,有个问题,我写的save_frame.py(见第一条对话)脚本里没写转90°,为什么采图时会转90°呢?

2.转成水平双目‘怎么判断向左转还是向右转呢?




目前132gs搭建的方向如上图,采集的左右图如下图

3.sunrise@ubuntu:~$ source /opt/tros/humble/setup.bash
sunrise@ubuntu:~$ ros2 node list | grep -i stereo
ros2 node info /StereoNetNode | grep -i camera_info
ros2 param list /StereoNetNode
ros2 param get /StereoNetNode stereo_calib_file_path
Unable to find node ‘/StereoNetNode’
Node not found
Node not found
你下次写命令能不能一次性写全,不写全来回问很浪费时间啊

1. 那 90° 不是你的脚本转的,是图像到 save_frame.py 之前就已经转好了。 你脚本里只有 cv2.imwrite 切片,没有任何旋转,所以旋转只可能发生在 mipi_cam 的输出环节。依据:GS130W 官方规格单路是 1280×1080(横置)、基线 80mm(产品简介),而你切出来的单目是 1088×1280——正好是 1280×1088 转 90° 的形状(1088 是 1080 按 16 对齐的宽度)。dual_combine:=2 的拼接输出就是按这个朝向给的,所以左右两张都“躺着”,T 也就落在 Y。想确认是哪一层转的:单独起单目(去掉 dual_combine)看输出尺寸,如果还是 1088×1280,就确认在 mipi_cam 这一层,旋转相关参数以 hobot_mipi_cam 对应版本的节点参数为准。

2. 别靠看图猜方向,用“T 的符号”一次定死。 模组两个镜头是水平并排的,出图里这条连线变竖直就说明整幅被转了 90°。做法:把已存的图批量 cv2.ROTATE_90_CLOCKWISE 后重跑你的标定脚本(只换 --image_dir),看三个数——单目变 1280×1088、双目 RMS 仍约 0.2px、T ≈ (+80, 0, 0) mm 且 T[0] 为正。若 T[0]≈-80,改成 cv2.ROTATE_90_COUNTERCLOCKWISE 再跑一次,最多两次必定定死;定死后全部图按这个方向重转,运行时也必须同方向。

想重标前先快速预判,可在未旋转的左右图上比角点(同朝向、只差视差):

import cv2
L = cv2.imread('left_0001.png', 0); R = cv2.imread('right_0001.png', 0)
_, c1 = cv2.findChessboardCorners(L, (11, 8))
_, c2 = cv2.findChessboardCorners(R, (11, 8))
d = (c2.reshape(-1, 2) - c1.reshape(-1, 2)).mean(0)
print(d)   # d[1] > 0 → 顺时针;d[1] < 0 → 逆时针

3. Node not found / Unable to find node 是因为那几条命令执行时节点根本没在跑,ros2 node info、ros2 param get 只查询运行中的节点,而且节点名也不一定叫 /StereoNetNode。这次按顺序整段复制:

# 终端1:先起 stereonet
source /opt/tros/humble/setup.bash
ls $(ros2 pkg prefix hobot_stereonet)/share/hobot_stereonet/launch
ros2 launch hobot_stereonet <上一条列出的 launch 文件> publish_origin_enable:=True
# 终端2:确认终端1 还在跑,再执行
source /opt/tros/humble/setup.bash
ros2 node list
ros2 topic list | grep -iE "camera_info|depth|disparity|cloud"
NODE=$(ros2 node list | grep -i stereo | head -1); echo "节点名: $NODE"
ros2 node info "$NODE"
ros2 param list "$NODE" | grep -iE "calib|save|pcd|origin"

按 node info / param list 的结果分叉,别混用:node info 里没有 camera_info 订阅、param list 里有 stereo_calib_file_path,就把重标结果写进那个文件(字段照它现有默认文件的格式,畸变系数填完整 5 个,你这个 k3≈-0.02/-0.03 不能截),启动加 calib_method:=custom stereo_calib_file_path:=<绝对路径>;若仍订阅 camera_info,就由你自己的节点发布同一组 sensor_msgs/CameraInfo(右目 P[0,3]=-fx*0.08002)。

点云不用另写算法:本贴对 2.5.5 的反馈是拥有 save_result_once 和 .pcd 保存,正常出深度后 ros2 param set "$NODE" save_result_once true 即取该单帧的矫正图、深度和点云,配 publish_origin_enable:=True 同时拿到原图;参数名以你上面的 param list 实际输出为准。

把终端2 的 node list、node info、param list 输出贴上来,我按实际节点名和参数名把启动命令与 yaml 字段一次写死。

你是ai吗?写的太复杂了。

地瓜有没有人工回答,有没有官方人工技术支持啊

之前dual_combine:=2是上下拼接图,上图是左图吗?上下图固定是上左下右吗?还是随机的?

三句先答:有官方人工渠道(见下);上下两半的顺序是固定的、不随机;但“上图=左图”不能假定,遮挡一次就能定死。

1. 官方人工支持
论坛这边可以继续追;像双目自标定与 stereonet 联调这种项目级问题,可以通过 DGP 项目对接与技术支持 对接 FAE。纯资料查找走 RDK 资料中心。

2. 顺序固定,但“上/下”不等于“左/右”
拼接图两半的排列由 pipeline 拼装顺序决定,同一套启动参数每次一致,不会随机。但 dual_combine 只是把两路流按固定次序叠进一张图,和你在脚本里把它命名为 left/right 没有关系——img[:half] 只是“上半张”。官方 GS130W 页面也没有写哪一半对应左目,所以这件事只能实测:

遮住模组的一个镜头(手指或纸片都行),看 /image_combine_raw 预览里哪一半变黑,黑的那半就是被遮的那一路。先遮左目、再遮右目,各确认一次,然后把这个对应关系固定下来,后面标定、切图、运行时全按它来。

3. 你看到的 T_y 为负,先别下结论
cv2.stereoCalibrate 的 T 是 cam1 原点在 cam0 坐标系下的位置;图像 y 轴向下。你把上半图当 cam0、下半图当 cam1,测出 T=(0.07, -80.02, -0.23) mm,T_y 为负——这只说明在这组图的朝向下 cam1 落在相反方向。因为你的单目图是 1088×1280 的竖幅(由 1280×1088 旋转而来),物理水平基线被转到了图像竖直方向,符号取决于旋转是顺时针还是逆时针,所以不能单凭这一个数断定 left/right 命名反了。先用第 2 步的遮挡结果对齐命名,再看重标后 T 是否落在符合物理关系的那一轴、T[0](或对应轴)为正。

4. 一条能省掉“转 90°”的官方启动方式
你现在这条 ros2 run mipi_cam mipi_cam ... 没给分辨率,单路出来就是竖幅 1088×1280。官方 GS130W 的启动方式是:

source /opt/tros/humble/setup.bash
ros2 launch mipi_cam mipi_cam_dual_channel.launch.py mipi_image_width:=1280 mipi_image_height:=1088

单路按 1280×1088 横置输出,对上模组两镜头左右并排的物理关系,标出来的 T 会落在 X 方向、极线天生水平,后续接 stereonet 也少一层朝向对齐。官方 Web 端双目预览形态可对照 GS130W 快速开始。

建议顺序:遮挡确认哪半是左目 → 用上面这条官方 launch 看单路是否直接给 1280×1088 → 再按确认后的左右关系重标一次。把遮挡结果告诉我,我按确认后的对应关系给下一步的完整命令。


这个是X5 132GS的相机模组,图中红圈确定是右相机吗

不能凭这张照片确定。 官方的 GS130W 硬件说明 只按连接器标注「① 右目 MIPI Camera 接口」「② 左目 MIPI Camera 接口」,标的是 FPC 接口位置,不是镜头面;文档里也没有"镜头朝向用户时哪一侧是左/右"的定义。所以红圈那只究竟是哪一路,只能实测。

两个可直接用的官方事实:

  • 右目接口那一路同时承载 IMU 数据(左目接口只有视频)。如果你这块是带 IMU 的 GS130WI,接 6 轴 IMU 的那路接口就是右目,可用它交叉核对红圈位置。
  • 左右是按相机光轴方向定义的:从模组背后顺着镜头看出去,靠左那只是左目。正对镜头面(脸对着模组)看时,左目在你右手边,这里最容易反。

一次定死的方法(约两分钟):

  1. 起官方双通道(单路横置 1280×1088):
source /opt/tros/humble/setup.bash
ros2 launch mipi_cam mipi_cam_dual_channel.launch.py mipi_image_width:=1280 mipi_image_height:=1088
  1. 用你现有的 save_frame.py 存一张完整拼接图(先别切)。
  2. 手指遮住红圈那只镜头,再存一张。两张对比,变黑的那一半(上/下)就是红圈那只对应的通道;再遮另一只验一次。
  3. 命名要跟着标定结果走:切成左右图后按之前定的方向转 90° 重标,只有"左目那路做 cam0"且算出 T ≈ (+80, 0, 0) mm、T[0] 为正时,左右命名、旋转方向和后面视差的正负才自洽;若 T[0]≈-80,交换左右后重跑即可,不用重拍。

告知遮挡结果(红圈镜头对应上半还是下半),我再把切图、重标、接 stereonet 的命令按这个对应关系一次写全。

你说的https://developer.d-robotics.cc/dgp打开是

你们官方有没有能人工远程的售后技术支持啊

有官方人工渠道,但不是"远程协助/售后工单",公开资料里只有三种。 依据是官方技术支持页(RDK 文档的技术支持章节列的是同一套):

你打开的 DGP 页是"项目对接"入口,不是通用售后。 官方对它的定位写得很明确:面向"产品化/量产规划、模块适配与性能优化、商业项目联合开发、批量采购前技术确认"这类明确的项目或商业落地需求,提交后分级响应;“日常技术问题建议优先通过社区问答或 FAQ 解决”(生态项目对接支持)。所以:公司项目要做双目自标定 + stereonet 联调,可以走这条,提交时写清板型 X5、GS130W 模组、hobot_stereonet 2.5.5、卡在"自标定参数如何进 custom 标定文件/极线方向";纯上手问题留在论坛更快。

公开渠道里没有承诺"远程接管/远程协助"这一项,我也不替它做承诺;模组硬件本身的换货、供货问题找购买时的京东/淘宝店客服。

回到你手上的正事(红圈是否右目):官方硬件说明只标接口不标镜头面,仍需遮挡一次定死上下两半的对应关系,把结果告诉我,我按它把切图、重标、接 stereonet 的命令一次写全。

你打开的DGP页面没错,它是企业项目申请入口,不是即时远程客服。需要人工支持,可联系购买渠道,或发邮件到官方开发者邮箱 developer@d-robotics.cc,附本帖链接并说明需要双目标定远程协助;能否安排远程由对接同事确认。

相机这边,你的上下切分没问题,顺序也不会随机。官方①标的是右目接口,但红圈对应你文件里的哪一路,直接遮住它看上、下哪半变黑即可,不用换线或重启。我之前说“水平”指两张单目图的方向,不是改成左右拼接,抱歉没说清楚。

官方联系方式见页底:https://developer.d-robotics.cc/rdkx5

发邮件到官方开发者邮箱 developer@d-robotics.cc要多久能有回复呢?

联系购买渠道具体如何联系,是跟客服说要售后能否安排远程吗?

公开资料只列了渠道,没有任何回复时效承诺,我不替官方给数字。想快一点,用 技术支持页 里的飞书技术交流群,比邮件链路短。

邮件按这几点写清,能省一轮来回:

  • 标题:X5 + GS130W 双目自标定接入 hobot_stereonet 2.5.5 协助(附本帖链接 x5 132gs想自行标定,出流后想看到实时图像但打不开http://192.168.127.10:8000/TogetheROS/
  • 硬件/版本:X5、GS130W(1088×1280 输出)、hobot_stereonet 2.5.5、TROS 2.5.5
  • 已完成:上下拼接切图、棋盘格 11×8/30mm、单目 RMS 0.27/0.16px、双目 0.23px、T≈(−0.08m 落在 Y)
  • 卡点:如何转成水平双目方向、自标定结果以 calib_method:=custom + stereo_calib_file_path 还是 CameraInfo 进节点
  • 诉求:希望远程协助确认标定文件字段与极线方向

购买渠道就是下单的京东/淘宝店客服:说明"模组使用中的技术问题,需要转技术对接/售后",换货、供货这类归店铺客服;标定与 stereonet 联调这类技术问题,店铺一般也只能转回官方(邮箱/DGP),不会替代两边任一渠道。

遮挡那只镜头看上下哪半变黑的结论出来后贴一下,我按对应关系把切图、重标、接 stereonet 的命令一次写全。

飞书交流群也没用,重新提供确认左右相机的方法

这件事不需要等群里或邮件——它不依赖任何未公开资料,两次测量就能定死,而且都不用看照片猜。

先说清依据:官方硬件说明只标「① 右目 MIPI Camera 接口(同时走 IMU)」「② 左目 MIPI Camera 接口」,标的是 FPC 接口,没有定义镜头面朝你时哪边是左。所以对 stereonet 来说,真正可用的标准是:校正后右图必须落在左图的图像 x 正方向一侧,即标定结果 T[0] > 0。下面两步就是为此定名。

第一步:红圈那只镜头对应上半还是下半(用亮度,不用肉眼)

source /opt/tros/humble/setup.bash
ros2 run mipi_cam mipi_cam --ros-args -p device_mode:="dual" \
  -p out_format:="bgr8" -p dual_combine:=2 -p framerate:=10.0 -p gdc_enable:=false
# ~/lr_check.py
import os, rclpy, cv2
from rclpy.node import Node
from sensor_msgs.msg import Image
from cv_bridge import CvBridge

class N(Node):
    def __init__(self):
        super().__init__('lr_check'); self.b = CvBridge(); self.f = None
        self.create_subscription(Image, '/image_combine_raw', self.cb, 10)
    def cb(self, m): self.f = self.b.imgmsg_to_cv2(m, 'bgr8')

rclpy.init(); n = N()
while n.f is None: rclpy.spin_once(n, timeout_sec=0.5)
img = n.f; h, w = img.shape[:2]; half = h // 2
cv2.imwrite(os.path.expanduser('~/lr_check.png'), img)
print(f'{w}x{h} top={img[:half].mean():.1f} bottom={img[half:].mean():.1f}')

另一终端跑 python3 ~/lr_check.py:先不遮挡记一组 top/bottom,再用纸片贴住红圈镜头口再跑一组。数值明显掉下去的那一半,就是红圈那只。两个坑:遮挡后数字几乎不变 → 还有别的 mipi_cam 在发旧帧,先 pkill -f mipi_cam 重来;两次必须是同一条命令起的流。

第二步:哪一半是右目(用你已有的棋盘格图)

import cv2, glob, os
L = sorted(glob.glob(os.path.expanduser('~/calib_data/left_*.png')))[0]
R = sorted(glob.glob(os.path.expanduser('~/calib_data/right_*.png')))[0]
def pts(p, rot):
    g = cv2.rotate(cv2.imread(p, 0), rot)
    ok, c = cv2.findChessboardCorners(g, (11, 8)); assert ok, p
    return c.reshape(-1, 2), g.shape
for name, rot in [('CW', cv2.ROTATE_90_CLOCKWISE), ('CCW', cv2.ROTATE_90_COUNTERCLOCKWISE)]:
    pl, sh = pts(L, rot); pr, _ = pts(R, rot)
    d = (pr - pl).mean(0)
    cv2.imwrite(os.path.expanduser(f'~/sample_{name}.png'), cv2.rotate(cv2.imread(L, 0), rot))
    print(name, sh, 'dx=%.2f dy=%.2f' % (d[0], d[1]))

先打开 ~/sample_CW.png、~/sample_CCW.png,选画面正立(椅子、棋盘格竖直)的那张对应方向;该方向下 dx < 0 表示 right_*.png 确实是物理右目,dx > 0 说明切图时命名反了,交换即可。

两步交叉即可定死:第一步得"红圈 → 上半/下半",第二步得"半幅 → 左/右"。定完按这个方向重跑标定,验收只看三点:单目变 1280×1088、T ≈ (+80, 0, 0) mm 且 T[0] 为正、双目 RMS 仍 0.2px 量级;运行时 mipi_rotation 必须与标定时一致。把两次 top/bottom 和 dx 贴出来,我按确认后的对应关系把切图、重标、接 stereonet 的命令一次写全。

这是我调整好左右图并且旋转90°之后跑的内外参结果:
左目单标 RMS: 0.158946 px
右目单标 RMS: 0.274290 px
左目内参 K:
[[664.63469876 0. 639.41814797]
[ 0. 664.5063645 541.63896472]
[ 0. 0. 1. ]]
右目内参 K:
[[664.69555993 0. 638.96998159]
[ 0. 664.43433026 542.55599486]
[ 0. 0. 1. ]]
左目畸变: [-3.29345322e-01 1.37608022e-01 5.53902581e-05 -2.83585909e-05
-3.02146722e-02]
右目畸变: [-3.17217218e-01 1.17015378e-01 -2.47865317e-04 1.81395038e-04
-2.09041291e-02]

===== 双目标定(radtan,fix_intrinsics=1)=====
双目 RMS(OpenCV): 0.234000 px
R:
[[ 0.99999364 0.00331003 0.00132688]
[-0.00330733 0.99999247 -0.00203245]
[-0.0013336 0.00202805 0.99999705]]
T: [-0.08002304 0.00019714 0.00033433] (m)
基线 norm(T): 80.02 mm
基线 abs(Tx): 80.02 mm
预期模组基线: 80 mm (GS130W)

去畸变后直线度 RMS(左目,radtan): 0.1628 px(越小越直)

后续我要用这个标定结果采集图片生成点云和原始左右图和矫正后左图,要怎么做?
别给错误答案