用 Rerun 实时可视化 Intel RealSense 深度传感器:RGB 与深度流式管线实战
发布时间:2026/9/17 8:50:57 作者:尧图编辑部 阅读量:1,286

用 Rerun 实时可视化 Intel RealSense 深度传感器RGB 与深度流式管线实战【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun本篇技术指南基于 Rerun 仓库中的live_depth_sensor官方示例examples/python/live_depth_sensor/README.md讲解如何把 Intel RealSense 深度传感器实时流式采集的 RGB 彩色帧与深度帧接入 Rerun 3D 视图并借助针孔相机Pinhole模型实现 RGB 相机、深度相机与三维空间的坐标对齐。读完本文你将掌握Pinhole、Transform3D、Image、DepthImage等 Rerun 核心 archetype 的组合用法、meter深度单位换算的关键细节以及如何运行、自定义这套实时传感器可视化方案。示例概览把 RealSense 实时流接入 Rerun 3D 视图该示例的功能非常聚焦从一台已连接的 Intel RealSense 深度传感器上持续读取彩色RGB与深度Depth两种数据流并逐帧送入 Rerun 进行可视化。最终在 Rerun Viewer 中看到的不只是两张并排的图像而是一个带针孔相机模型的 3D 场景——RGB 相机与深度相机都被标定在正确的位置深度图在 3D 视图中被自动反投影为点云。硬件要求此示例需要一台真实连接USB的 Intel RealSense 深度传感器才能运行例如 D400 系列。正因为依赖硬件示例在 pyproject.toml 中通过[tool.rerun-example] skip true # requires hardware标记为跳过 CI 自动化执行。示例使用到的 Rerun 核心类型archetype共 4 种Archetype作用Pinhole描述相机透视投影内参负责图像坐标与相机坐标的映射Transform3D描述相机外参用于把 RGB 相机摆放到相对深度相机的正确位置Image记录 RGB 彩色图像DepthImage记录深度图像并携带深度单位meter信息运行环境与依赖按照示例文档你需要先准备好最新版 Rerun SDK 并检出仓库代码pip install --upgrade rerun-sdk # 安装最新版 Rerun SDK git clone https://gitcode.com/GitHub_Trending/re/rerun.git # 检出仓库 cd rerun git checkout latest # 检出与最新 SDK 发布版本匹配的提交然后安装该示例所需的依赖库pip install -e examples/python/live_depth_sensor依赖声明见 examples/python/live_depth_sensor/pyproject.toml核心依赖只有三个numpy用于把 RealSense 原始帧数据转为 NumPy 数组pyrealsense2macOS 上为pyrealsense2-macIntel RealSense 官方 Python SDK提供rs.pipeline()、get_intrinsics()、get_extrinsics_to()等接口rerun-sdkRerun 日志 SDK。示例同时声明了命令行入口脚本live_depth_sensor live_depth_sensor:main。运行示例主脚本python -m live_depth_sensor # 运行示例如果想自定义行为、探索更多功能或保存数据用--help查看全部 CLI 选项python -m live_depth_sensor --help代码结构总览示例主体是一个约 100 行的单文件脚本 examples/python/live_depth_sensor/live_depth_sensor.py流程可以概括为四个阶段声明坐标系把整个realsense空间声明为 RDF右、下、前坐标约定标定相机静态分别记录深度相机与 RGB 相机的内参Pinhole以及两者之间的外参Transform3D全部使用staticTrue只记录一次循环取流通过rs.pipeline()阻塞等待帧逐帧把深度图与彩色图 log 到对应实体路径清理退出finally中调用pipe.stop()释放 RealSense 管线。其中关键的相机标定与坐标约定逻辑如下。相机模型与坐标约定Pinhole Transform3D ViewCoordinates坐标约定RDFRealSense 的坐标系约定为RDFX 向右、Y 向下、Z 向前这与 Rerun 深度相机的默认坐标约定一致。示例在第一行就把它声明为静态属性rr.log(realsense, rr.ViewCoordinates.RDF, staticTrue) # Visualize the data as RDF从 rerun_py/rerun_sdk/rerun/archetypes/view_coordinates.py 的实现说明看[Right, Down, Forward]表示X指向右、Y指向下、Z指向前。RDF 是图像类数据所有图像都使用 RDF 像素坐标约定最自然的空间表示。深度相机内参示例把深度相机的坐标系原点直接当作世界原点——realsense/depth保持为单位变换Identity因此无需为深度相机记录外参。只记录深度相机的针孔内参rr.log( realsense/depth/image, rr.Pinhole( resolution[depth_intr.width, depth_intr.height], focal_length[depth_intr.fx, depth_intr.fy], principal_point[depth_intr.ppx, depth_intr.ppy], ), staticTrue, )三个参数分别对应 RealSense 内参结构depth_intr中的分辨率、焦距fx/fy与主点ppx/ppy来源是profile.get_stream(rs.stream.depth).as_video_stream_profile().get_intrinsics()。RGB 相机外参与内参RGB 相机与深度相机通常不在同一物理位置需要外参把 RGB 相机摆放到正确位姿。示例用get_extrinsics_to获取深度相机到 RGB 相机的变换并记录为Transform3Drgb_from_depth depth_profile.get_extrinsics_to(rgb_profile) rr.log( realsense/rgb, rr.Transform3D( translationrgb_from_depth.translation, mat3x3np.reshape(rgb_from_depth.rotation, (3, 3)), relationrr.TransformRelation.ChildFromParent, ), staticTrue, )这里的relationrr.TransformRelation.ChildFromParent表示该变换描述子实体RGB 相机相对父实体深度相机坐标系的姿态。之后 RGB 相机同样记录自己的针孔内参rr.log( realsense/rgb/image, rr.Pinhole( resolution[rgb_intr.width, rgb_intr.height], focal_length[rgb_intr.fx, rgb_intr.fy], principal_point[rgb_intr.ppx, rgb_intr.ppy], ), staticTrue, )从 rerun_py/rerun_sdk/rerun/archetypes/pinhole.py 的源码注释可以进一步理解Pinhole的语义它是一个相机透视投影 archetypeCamera perspective projection (a.k.a. intrinsics)resolution是子图像空间的像素分辨率宽、高image_from_camera投影到(0,0)到resolution - 1的范围内。当同一实体下记录了Transform3D时它表示相机外参并优先于Pinhole被用于空间定位而当DepthImage记录在Pinhole之下时深度图会沿相机朝向被自动反投影成 3D 点云——这正是本示例在 3D 视图中看到点云的原理。Pinhole还支持更多可选字段camera_xyz默认即RDF、image_plane_distance仅影响 3D 可视化中相机平截头体的显示距离、color与line_width相机线框的样式等均可按需扩展。记录 RGB 图像Image相机标定完成后进入主循环。每取到一帧先递增帧号并用rr.set_time把它写入时间轴再记录彩色图rr.set_time(frame_nr, sequenceframe_nr) rr.log(realsense/rgb/image, rr.Image(color_image))color_image由np.asanyarray(color_frame.get_data())转换而来即 RealSense 原始彩色帧数据BGR/RGB 排列的 H×W×C 数组。由于实体路径与之前Pinhole记录的路径一致realsense/rgb/image图像会自动与相机内参关联从而在 3D 视图中拥有正确的位置与投影。记录深度图像DepthImage 与 meter 单位换算深度图与彩色图同样逐帧记录但多了关键的meter参数rr.log( realsense/depth/image, rr.Pinhole( resolution[depth_intr.width, depth_intr.height], focal_length[depth_intr.fx, depth_intr.fy], principal_point[depth_intr.ppx, depth_intr.ppy], ), staticTrue, )rr.set_time(frame_nr, sequenceframe_nr) rr.log(realsense/depth/image, rr.DepthImage(depth_image, meter1.0 / depth_units))depth_units来自depth_frame.get_units()是 RealSense 深度值对应的物理长度单位为米。例如depth_units 0.001表示每个深度单位是 1 毫米此时meter 1.0 / 0.001 1000即 1 米对应 1000 个原生深度单位。根据 rerun_py/rerun_sdk/rerun/archetypes/depth_image.py 的字段文档meter的含义是原生深度单位中一米有多长。它对 2D 视图的影响仅是悬停时显示的物理深度值在 3D 视图中则直接决定点云中每个点的空间位置单位错误会导致点云被整体缩放或拉伸。若省略meterViewer 会默认浮点深度格式取1.0、整数格式取1000.0毫米。DepthImage还提供其它可视化相关字段可按需组合字段说明默认colormap深度渲染使用的颜色映射Turbo 色图depth_range期望的有效深度值范围超出部分在映射色图时被截断点云不受影响自动从数据估计point_fill_ratio缩放 3D 点云中点的半径1.0draw_order2D 视图下的绘制顺序-20.0magnification_filter2D 视图放大时的过滤方式仅 2D 有效—时间轴用 frame_nr 串联连续帧rr.set_time(frame_nr, sequenceframe_nr)每一帧都调用一次rr.set_time把序列时间点frame_nr写入 Rerun 时间轴。这样所有帧无论 RGB 还是深度都会被标记上同一帧号Viewer 可以按时间轴播放、拖动、对比不同帧的数据。这也是 Rerun 处理流式时序数据multimodal robotics data的标准方式。完整的帧循环综合上述各环节主循环在源码中的实现如下来自 examples/python/live_depth_sensor/live_depth_sensor.pyframe_nr 0 try: while True: if num_frames and frame_nr num_frames: break rr.set_time(frame_nr, sequenceframe_nr) frame_nr 1 frames pipe.wait_for_frames() for _f in frames: depth_frame frames.get_depth_frame() depth_units depth_frame.get_units() depth_image np.asanyarray(depth_frame.get_data()) rr.log(realsense/depth/image, rr.DepthImage(depth_image, meter1.0 / depth_units)) color_frame frames.get_color_frame() color_image np.asanyarray(color_frame.get_data()) rr.log(realsense/rgb/image, rr.Image(color_image)) finally: pipe.stop()num_frames由--num-frames命令行参数控制不传则无限流式运行直到按Ctrl-C中断此时finally块确保 RealSense 管线被正确关闭。CLI 选项script_add_args 带来的标准能力示例的main()除了自定义的--num-frames外还调用了rr.script_add_args(parser)与rr.script_setup(args, rerun_example_live_depth_sensor)。从 rerun_py/rerun_sdk/rerun/_script_helpers.py 的源码可以看到这组辅助函数会为脚本注入一整套标准 Rerun 参数--headless不弹出 GUI只记录数据--connect [URL]连接到一个外部运行的 Rerun Viewer不指定 URL 时连接默认地址--serve启动 gRPC 与 Web 服务器并打开浏览器端的 Web Viewer--url指定要连接的 Rerun URL--save path把数据保存为.rrd文件--stdout把数据写到标准输出供管道重定向到 Rerun Viewer。script_setup会根据这些参数自动完成rr.init与连接建立script_teardown负责收尾如在--serve模式下阻塞等待。因此本示例天然支持离线保存为 rrd 文件或无头模式采集等扩展用法无需修改任何业务代码。小结live_depth_sensor示例展示了 Rerun 处理实时多模态传感器数据的标准范式先以staticTrue一次性记录坐标系约定ViewCoordinates.RDF、相机内参Pinhole与外参Transform3D建立 3D 空间的标定骨架再逐帧用rr.set_time标记时间戳并通过Image与DepthImage配合meter单位换算持续记录数据流。这套模式可以直接迁移到任何深度相机、双目相机或 RGB-D 机器人感知管线上是理解 Rerun 相机模型与流式日志机制的最小可运行范本。【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考