4. 视觉数据采集:单目/双目/深度相机标定、图像与深度图同步采集、光照条件对视觉SLAM的影响
视觉传感器是SLAM系统的「眼睛」。但说实话,很多人一上来就急着跑算法,结果数据质量不行,后面全白干。我做了这么多年SLAM,踩过最大的坑就是——相机没标好,后面所有环节都在「将错就错」。这一章咱们就把视觉数据采集的底子打扎实。
4.1 单目 / 双目 / 深度相机标定
标定是视觉SLAM的「第一粒扣子」。扣错了,后面全歪。我个人习惯用 Kalibr 或 ROS camera_calibration 做内参标定,但不管用哪个工具,核心都是要拿到准确的焦距、主点、畸变系数。
单目相机标定最简单,打印一张棋盘格,左右上下晃动采集20~30张图就行。但注意——不要只在一个距离上拍,远近都要有。我见过有人只拍了半米远的图,标出来的焦距偏差5%以上。
双目相机除了内参,还要标定左右相机的旋转和平移(外参)。这里有个坑:左右图像的分辨率、帧率必须一致,否则时间戳对不上。我曾经在项目里用了两颗不同型号的摄像头,折腾了三天才发现是硬件不匹配。
深度相机(比如Intel RealSense、Kinect)通常出厂带标定,但温度变化或震动后参数会漂。我建议每次采集前都做一次快速校验。用平面物体(比如地板)测一下深度误差,超过2cm就得重新标定。
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),但自动曝光又会导致帧间亮度突变……所以最好的办法是手动固定曝光参数,然后通过后期图像增强来补偿。
另外,高动态范围(HDR)场景(比如窗户边)会让图像过曝或欠曝。如果你用的是深度相机,过曝区域深度值直接为0。我建议在采集前用直方图观察一下,调整相机增益或光圈,让大部分像素落在中间灰度范围。
4.4 实战建议与总结
- 标定频率:每次拆装相机后必须重新标定,温度变化超过15°C也建议重标。
- 同步策略:能用硬件触发就用硬件触发,软同步至少保证时间戳误差 < 5ms。
- 光照控制:室内用LED补光,户外避免正午强光,清晨或傍晚光照最均匀。
- 数据检查:采集后立即回放rosbag,看图像是否模糊、深度图是否有大片黑洞。
视觉数据采集没有捷径,但只要你把标定、同步、光照这三个点抓牢了,后面SLAM算法跑起来会顺很多。