4. 帧同步机制

多摄像头系统里,帧同步是个绕不开的坎儿。

说白了,就是让所有摄像头在同一时刻“咔嚓”一下。你想想看,如果每个相机各自为政,拍出来的画面时间对不上,那后面的融合、拼接、测距全都会乱套。我最早做双目视觉的时候,就吃过这个亏——两个相机差了十几毫秒,结果运动物体的位置算出来全是错的。

4.1 帧同步信号设计

帧同步的核心,是给所有摄像头一个统一的“心跳”。这个心跳,我们通常叫它帧同步信号(Frame Sync Signal)。

常见的实现方式有两种:

  • 硬件触发(Hardware Trigger):用一根信号线,把主控的PWM或GPIO输出接到每个相机的触发引脚。所有相机在同一时刻收到上升沿,同时开始曝光。
  • 软件同步(Software Sync):通过网络或总线广播一个同步命令。这种方式延迟大、抖动也大,一般只用于对同步精度要求不高的场景。

我个人习惯,只要条件允许,一定用硬件触发。为什么?因为软件同步的延迟太不可控了。我在一个项目中试过用UDP广播做同步,结果抖动达到了±2毫秒,根本没法用。

硬件触发信号设计要点:

  • 信号电平:3.3V或5V,取决于相机IO口
  • 脉冲宽度:一般要求大于相机的最小触发脉宽(通常1-10μs)
  • 上升/下降沿:越陡越好,建议<5ns
  • 阻抗匹配:长线传输时注意终端匹配,防止反射

下面这张图,是我常用的多相机硬件同步架构:

多相机硬件帧同步架构 主控(FPGA/MCU) 帧同步信号(PWM/GPIO) 信号分线器 Camera 1 Camera 2 Camera N 所有Camera同时收到同步信号,开始曝光。信号线长度应尽量等长,避免传播延迟差异。

4.2 抖动分析与补偿

有了同步信号,是不是就万事大吉了?不是的。还有一个讨厌的东西叫“抖动”(Jitter)。

抖动,就是同步信号到达每个相机的时间不一致。哪怕只有几微秒的差异,对于高速运动物体来说,都会造成明显的像素偏移。

抖动的来源主要有三个:

抖动来源 典型量级 影响
信号传播延迟差异 ±1-5 ns/m 线缆长度不匹配时明显
相机内部PLL抖动 ±10-100 ns 不同品牌相机差异大
曝光开始时间离散性 ±1-10 μs 滚动快门相机更严重

我曾经在一个项目中,用了三种不同品牌的相机。结果发现,即使同一根同步信号线分出来的,它们的实际曝光开始时间也差了将近20微秒。后来一查,是相机内部PLL锁定时间不同导致的。

我的补偿经验:

对于固定抖动,可以在系统初始化时做一次标定。让所有相机对着同一个LED闪光灯拍照,通过分析LED亮起的位置,反算出每个相机的延迟偏移。然后在软件里做补偿。

补偿的方法,我一般分两步走:

  1. 粗补偿:调整每个相机的触发延迟寄存器,让它们的曝光中心对齐。很多工业相机都支持这个功能。
  2. 精补偿:在图像处理层面,根据标定出的延迟差,对图像做亚像素级的时域插值。说白了,就是根据运动矢量,把图像“推”到正确的时刻。

4.3 多相机帧对齐策略

信号同步做好了,但还有个问题:不同相机的帧率可能不一样,或者虽然帧率一样,但曝光时间不同。这时候就需要做“帧对齐”。

帧对齐,就是把不同相机拍摄的图像,按照时间戳对齐到同一个时间轴上。

常用的策略有三种:

  • 最近邻对齐:找到时间戳最接近的两帧,直接配对。简单,但误差大,最大误差可达半个帧周期。
  • 线性插值对齐:根据前后两帧的时间戳,对图像做线性插值。精度高一些,但计算量大。
  • 运动补偿对齐:利用光流或特征点匹配,估计出帧间的运动,然后做精确补偿。精度最高,但实现复杂。

注意:滚动快门(Rolling Shutter)相机在做帧对齐时,要特别小心。因为它的每一行曝光时间不同,直接做帧对齐会引入行间错位。我建议,如果条件允许,尽量用全局快门(Global Shutter)相机做多摄像头系统。

下面这个表格,是我在实际项目中对三种对齐策略的对比:

策略 精度 计算开销 适用场景
最近邻对齐 ±1/2帧周期 极低 低速场景、预览模式
线性插值对齐 ±1/10帧周期 中等 一般运动场景
运动补偿对齐 ±1/100帧周期 高 高速运动、高精度测量

嗯,这里要注意一点。帧对齐不是越精确越好。你得考虑系统的实时性要求。我做过一个自动驾驶的项目,要求30fps实时处理,运动补偿对齐根本跑不动,最后用了线性插值加硬件加速,才勉强达标。

最后,分享一个我踩过的坑。有一次,我用了四个相机做全景拼接,帧同步信号都接好了,对齐算法也写了,但拼接出来的画面总是有撕裂。查了两天,最后发现是其中一个相机的曝光时间设置得比其他相机长了一倍。曝光时间不同,导致帧中心时刻偏移,对齐算法再怎么补偿也救不回来。所以,多相机系统里,曝光参数一定要统一。