4. 视觉数据采集:单目/双目/深度相机标定、图像与深度图同步采集、光照条件对视觉SLAM的影响

视觉传感器是SLAM系统的「眼睛」。但说实话,很多人一上来就急着跑算法,结果数据质量不行,后面全白干。我做了这么多年SLAM,踩过最大的坑就是——相机没标好,后面所有环节都在「将错就错」。这一章咱们就把视觉数据采集的底子打扎实。

视觉数据采集核心流程 单目 / 双目 / 深度 相机标定 同步采集 光照条件 · 曝光控制 · 图像质量 高质量视觉数据流

4.1 单目 / 双目 / 深度相机标定

标定是视觉SLAM的「第一粒扣子」。扣错了,后面全歪。我个人习惯用 Kalibr 或 ROS camera_calibration 做内参标定,但不管用哪个工具,核心都是要拿到准确的焦距、主点、畸变系数。

⚡ 核心标定参数:fx, fy, cx, cy(内参矩阵) + k1, k2, p1, p2, k3(畸变系数)

单目相机标定最简单,打印一张棋盘格,左右上下晃动采集20~30张图就行。但注意——不要只在一个距离上拍,远近都要有。我见过有人只拍了半米远的图,标出来的焦距偏差5%以上。

双目相机除了内参,还要标定左右相机的旋转和平移(外参)。这里有个坑:左右图像的分辨率、帧率必须一致,否则时间戳对不上。我曾经在项目里用了两颗不同型号的摄像头,折腾了三天才发现是硬件不匹配。

深度相机(比如Intel RealSense、Kinect)通常出厂带标定,但温度变化或震动后参数会漂。我建议每次采集前都做一次快速校验。用平面物体(比如地板)测一下深度误差,超过2cm就得重新标定。

💡 小技巧:标定双目时,把棋盘格贴在平整的墙面上,左右相机各拍一部分,保证重叠区域大于60%。这样外参才稳。

4.2 图像与深度图同步采集

视觉SLAM里,图像和深度图的时间戳必须严格对齐。差个10毫秒,点云投影就错位了。我一般用ROS的 message_filters::sync 做近似同步,或者直接用硬件触发。

// C++ 示例:使用 message_filters 同步彩色图与深度图
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <message_filters/sync_policies/approximate_time.h>

typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::Image, sensor_msgs::Image> SyncPolicy;

message_filters::Subscriber<sensor_msgs::Image> rgb_sub(nh, "/camera/color/image_raw", 10);
message_filters::Subscriber<sensor_msgs::Image> depth_sub(nh, "/camera/depth/image_raw", 10);
message_filters::Synchronizer<SyncPolicy> sync(SyncPolicy(10), rgb_sub, depth_sub);
sync.registerCallback(boost::bind(&callback, _1, _2));

实际采集时,我建议把图像和深度图都存成rosbag,不要直接存图片文件。因为rosbag保留了时间戳和话题结构,后期处理灵活得多。嗯,这里要注意:深度图一般是16位单通道,别当成8位图存了,否则精度全丢。

⚠️ 警告:深度相机在强阳光下(比如户外)深度值会大量缺失。室内采集时也要避免反光物体(镜子、玻璃),否则深度图会出现黑洞。

4.3 光照条件对视觉SLAM的影响

光照是视觉SLAM的「隐形杀手」。你以为算法鲁棒,其实它只是没遇到极端光照。我做过一个仓库项目,白天和晚上的定位精度差了3倍。为什么?因为光照变化导致特征点数量剧烈波动。

光照场景特征点数量SLAM稳定性建议
均匀明亮(300~800 lux)充足(>500)高理想条件
低光照(<50 lux)稀少(<100)低,容易跟丢补光或使用红外相机
强光直射/逆光分布不均中,易误匹配调整曝光/加偏振片
动态阴影/闪烁不稳定低,频繁丢失固定光源或使用HDR

说白了,视觉SLAM对光照的敏感度远超你的想象。我个人的经验是:采集时尽量保持光照均匀,如果场景光照变化大,一定要开启相机的自动曝光(AE),但自动曝光又会导致帧间亮度突变……所以最好的办法是手动固定曝光参数,然后通过后期图像增强来补偿。

🎯 避坑指南:我曾经在傍晚采集数据,自动曝光导致图像一会儿亮一会儿暗,特征匹配疯狂跳变。后来我固定了曝光时间,虽然暗部细节少了,但SLAM轨迹反而更平滑。

另外,高动态范围(HDR)场景(比如窗户边)会让图像过曝或欠曝。如果你用的是深度相机,过曝区域深度值直接为0。我建议在采集前用直方图观察一下,调整相机增益或光圈,让大部分像素落在中间灰度范围。

4.4 实战建议与总结

  • 标定频率:每次拆装相机后必须重新标定,温度变化超过15°C也建议重标。
  • 同步策略:能用硬件触发就用硬件触发,软同步至少保证时间戳误差 < 5ms。
  • 光照控制:室内用LED补光,户外避免正午强光,清晨或傍晚光照最均匀。
  • 数据检查:采集后立即回放rosbag,看图像是否模糊、深度图是否有大片黑洞。

视觉数据采集没有捷径,但只要你把标定、同步、光照这三个点抓牢了,后面SLAM算法跑起来会顺很多。