ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RealSense 深度相机标定:3 分钟拿到内外参,避开 90% 的坑

RealSense 深度相机标定:3 分钟拿到内外参,避开 90% 的坑 RealSense 深度相机标定3 分钟拿到内外参避开 90% 的坑【免费下载链接】librealsenseRealSense SDK项目地址: https://gitcode.com/GitHub_Trending/li/librealsense点云和彩色图对不齐、早上量的距离和晚上对不上、换台电脑数值就飘——多半不是算法的锅是标定的事。用 librealsenseRealSense 深度相机的官方 SDK配合 pyrealsense2一个下午能走完 RealSense 深度相机标定的完整链路取参、懂参、避坑、维护。动手用 pyrealsense2 3 分钟拿到内参矩阵和外参参数来自流描述stream profile即一路视频流的完整配置与元数据不是来自文件。流一起内参外参就能直接从 profile 上拿。下面这段只干两件事启动深度彩色然后从深度流取内参并用一行get_extrinsics_to取深度到彩色的变换。注意它不需要任何标定板拿到的是设备出厂已写入的基础参数。import pyrealsense2 as rs pipe, cfg rs.pipeline(), rs.config() cfg.enable_stream(rs.stream.depth, 848, 480, rs.format.z16, 30) cfg.enable_stream(rs.stream.color, 1280, 720, rs.format.rgb8, 30) prof pipe.start(cfg) depth_prof prof.get_stream(rs.stream.depth).as_video_stream_profile() color_prof prof.get_stream(rs.stream.color).as_video_stream_profile() intri depth_prof.get_intrinsics() # 内参焦距/主点/畸变 extri depth_prof.get_extrinsics_to(color_prof) # 外参深度-彩色 4x4 变换 print(焦距 fx,fy:, intri.fx, intri.fy, 主点:, intri.ppx, intri.ppy) print(外参平移(mm):, extri.translation) pipe.stop()结果怎么读fx/fy单位是像素D435 深度流一般在几百到一千多ppx/ppy贴近图像中心外参的translation单位是毫米两颗镜头物理间距只有几厘米量级应在几十 mm。跑出来是 0 或异常大往下看避坑部分。字段单位含义fx,fy像素焦距决定像素到 3D 射线的张角ppx,ppy像素主点光轴与像面交点coeffs无量纲畸变系数描述边缘弯曲translation毫米外参中两传感器原点的相对位置内参修什么、外参修什么为什么 Y16 必须是原始流内参修单颗镜头内部的变形。镜头是曲面画面边缘的像素会向四周漂移离主点越远漂得越厉害。内参就是用fx/fy、ppx/ppy和coeffs把这个漂移建模出来给定一个像素你能反推出它对应空间里的哪条射线。没有它棋盘格边缘会弯成桶形测距随画面位置变化。外参把一颗镜头的坐标系搬到另一颗。深度相机外参把红外坐标系搬彩色坐标系的 4×4 变换描述的是传感器在板子上的相对位置和夹角。D400 系列的深度红外与彩色是两颗物理独立的镜头外参不准深度点云贴彩色纹理时怎么调都对不上。多传感器之间的这种坐标变换关系示意图如下以 T265 为例原理相同为什么 Y16 原始流是标定前提。Y16 是红外传感器直接输出的 16 位原始数据像素值未经 SDK 处理而平时拿到的 z16 深度流是时序滤波、空间滤波、空洞填充等后处理后的结果像素已被修过。在修过的数据上拟合等于拿失真的样本建模型而且从已校正流上读到的畸变系数是全零——SDK 替你把畸变消化掉了。规则很硬标定时用原始 Y16运行时才切 z16。避坑帧率、零畸变、温度漂移三个高频翻车场景⚠️ 下面三个场景几乎覆盖了全部新手翻车现场每个按现象 → 原因 → 修复过一遍。Couldnt resolve requests启动即报错。现象pipeline.start直接抛这个异常流一个都起不来。原因Y16 格式在 USB 3.0 连接下只开放 15fps 和 25fps 两档Y16 是 16 位数据带宽占用是 8 位格式的两倍你配的 30fps 在设备侧不存在这个组合。修复Y16 场景把帧率改成 15 或 25非要 30fps 就改用 Y8代价是红外动态范围减半。畸变系数全零。现象intri.coeffs输出一排 0。原因你从后处理流或已校正流上取参SDK 已经做过畸变校正profile 里自然留了个空壳。修复按上面Y16 是前提一节从 Y16 原始流重新取一次仍为零再检查设备固件里的标定数据是否完整。深度值随温度漂移。现象相机连续运行升温后或者昼夜温差大深度边缘整体跳变几个毫米。原因红外发射器与镜头对温度敏感出厂标定参数是特定温度下的快照温度一变模型就偏。修复温度大幅变化后重跑片上标定librealsense 提供on-chip-calib接口和rs-on-chip-calib示例程序让设备自动完成内部自标定并把结果写回。一次标定不够怎么让它持续可用多距离采集别只贴一面墙按按钮。标定本质是拟合你喂的数据决定拟合范围。只站在 1m 前采一组保住的也只是 1m 附近。建议覆盖 0.5m、1.5m、3m 几个工作距离每个距离摆 15~20 个不同角度位置让标定模型横跨相机整个工作区间。参数落盘保存与重载。pyrealsense2 没有保存标定参数按钮但参数本来就是普通数据。把intrifx、fy、ppx、ppy、coeffs和extrirotation、translation序列化成一个 JSON 存到本地启动时读回来覆盖或校验即可。文件里记上设备序列号做绑定换机器部署时参数可复现——这一步直接消掉换台电脑数值就飘的问题。验证用重投影误差当验收线。把标定板角点的 3D 坐标用新参数投回 2D与实测像素坐标的偏差即重投影误差控制在 0.5 像素内才算合格。深度侧再看 Z 向精度深度误差与顶点坐标的变换关系如下图点云效果层面直接在 Viewer 里看深度彩色的融合纹理和几何贴合说明外参没问题整体偏移说明外参还有残差如下图 D435 在 Jetson 平台上的效果交付前对照检查标定取参用的是 Y16 原始流而不是 z16 深度流Y16 帧率只写 15 或 25不越设备支持范围fx/fy是像素量级、外参平移是毫米量级眼检通过多距离0.5/1.5/3m× 多角度共 15~20 组采集重投影误差验证通过控制在 0.5 像素内内外参已序列化落盘并与设备序列号绑定温度剧变或固件更新后已重跑片上标定【免费下载链接】librealsenseRealSense SDK项目地址: https://gitcode.com/GitHub_Trending/li/librealsense创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表