帧同步
帧同步
软件同步
有两种软件同步方法:如果我们想同步同一 OAK 的多个消息,例如:通过固件同步,我们监控漂移并对所有摄像头(左、右、彩色)的捕获时间戳进行对齐,这些时间戳在 MIPI 帧起始 (SoF) 事件时捕获。左/右全局快门摄像头由同一时钟驱动,通过 I2C 上的广播写入启动,因此即使在没有硬件同步的情况下自由运行,也不会随着时间的推移发生漂移。RGB 滚动快门在时钟/帧时间上存在细微差别,因此当我们检测到轻微漂移时,我们会通过微调下一帧的帧时间(行数)来进行补偿。如果传感器设置为相同的 FPS(默认值为 30),则上述两种方法已集成到 depthai 中并默认启用,这使我们能够在所有帧+ 这些帧生成的消息之间实现低于毫秒级的延迟!视差帧和彩色帧的时间戳表明我们实现了远低于亚毫秒级的精度。与序列号同步相反,时间戳同步可以同步:
序列号同步
- 来自 ColorCamera 或 MonoCamera 的摄像头帧(彩色、左帧和右帧)
- 由摄像头帧生成的消息(NN 结果、视差/深度、边缘检测、跟踪片段、编码帧、跟踪特征等)
Py
1# 从队列中获取消息
2message = queue.get()
3# message 可以是 ImgFrame, NNData, Tracklets, ImgDetections, TrackedFeatures...
4seqNum = message.getSequenceNum()Command Line
1[Seq 325] RGB timestamp: 0:02:33.549449
2[Seq 325] Disparity timestamp: 0:02:33.549402
3-----------
4[Seq 326] RGB timestamp: 0:02:33.582756
5[Seq 326] Disparity timestamp: 0:02:33.582715
6-----------
7[Seq 327] RGB timestamp: 0:02:33.616075
8[Seq 327] Disparity timestamp: 0:02:33.616031时间戳同步
- 不同 FPS 的流
- IMU 结果与其他消息
- 与连接到计算机的其他设备的消息,因为时间戳已与主机时钟同步 同步
- 删除来自较快流的一些消息以获得较慢流的同步 FPS
- 复制来自较慢流的一些消息以获得最快流的同步 FPS
Py
1# 从队列中获取消息
2message = queue.get()
3timestamp = message.getTimestamp() # 与主机时钟同步的时间戳
4
5# 如果消息是 ImgFrame,您可以选择曝光的开始/中间/结束
6# 也可以使用 .START 或 .END
7imgFrame.getTimestamp(dai.CameraExposureOffset.MIDDLE)Hardware syncing
允许在 多个摄像头传感器之间以及可能与其他硬件(例如闪光灯 LED、外部 IMU 或其他摄像头)之间实现精确同步(< 10µs)。FSYNC/FSIN(帧同步)信号是在每次帧捕获开始时驱动为高电平的脉冲。其长度与曝光时间不成比例。它可以是输入或输出。它工作在1.8V逻辑电平。在立体摄像头(OAK-D*)上,我们希望立体摄像头对(单色摄像头)能够完美同步,因此一个摄像头传感器(例如左侧)将 FSYNC 设置为输入,而另一个摄像头传感器(例如右侧)将 FSYNC 设置为输出。在此配置中,右侧摄像头驱动左侧摄像头。如果我们想通过外部信号驱动摄像头,我们需要将 FSIN 设置为摄像头传感器的输入。所有 Series 2 OAK PoE 型号 都配备了 M8 I/O 连接器,该连接器暴露了 FSIN 信号(以及 STROBE)。我们开发了 FSYNC Y 型适配器,允许您同步(菊花链式连接)多个 OAK 摄像头。您还可以通过 Script 组件中的 GPIO 控制 FSIN 线,请参阅此处的示例:https://gist.github.com/Erol444/a9189a8215371ff9f4cf4472960e1d66。如上文所述,只有部分传感器支持 FSYNC 同步。 FSYNC 同步有两种类型:
STROBE 信号是图像传感器的输出,在图像传感器曝光期间处于激活状态(高电平)。它可用于驱动外部 LED 照明,使照明仅在曝光期间激活,而不是一直亮着,从而降低照明的功耗和发热。我们在 OAK 摄像头 Pro 版本(带有板载照明红外 LED 和红外激光点投影仪)上使用了 STROBE 信号来驱动激光/LED。带有 M8 连接器的摄像头允许您将外部照明连接到 STROBE 信号,如下面的视频所示(博客文章在此):帧时间戳在 MIPI SoF(帧开始)事件时分配给帧,此时传感器开始流式传输帧(MIPI 读取)。对于全局快门传感器,这紧随整个帧的曝光完成之后,因此我们可以说分配的时间戳与曝光窗口的结束对齐(在几微秒的误差范围内)。以下是全局快门传感器时序的示例图,展示了何时将时间戳分配给帧:
对于滚动快门,示例图看起来略有不同。MIPI SoF 在图像的第一行完全曝光并开始流式传输之后出现,但后续行仍在曝光或可能尚未开始曝光(取决于曝光时间)。下面是滚动快门传感器(IMX378)在 1080p 和 30fps(33.3ms 帧时间)下的示例图。MIPI 读取时间因传感器/分辨率而异,但对于 IMX378,在 1080P 下为 16.54ms,在 4K 下为 23.58ms,在 12MP 下为 33.04ms。
在 OAK-FFC-4P 上,我们 有 4 个摄像头端口;A (rgb)、B (左)、C (右) 和 D (cam_d)。A 和 D 是 4 通道 MIPI,B 和 C 是 2 通道 MIPI。每对 (A&D 和 B&C) 共享一个 I2C 总线,并且 B&C 总线默认配置为硬件同步 左右摄像头。对于 A&D 端口,您需要显式启用硬件同步:Arducam FFC 摄像头有一个 22 引脚连接器,该连接器没有用于 FSIN/STROBE 的线路。 如下所示,要将 Arducam FFC 摄像头连接到我们的 OAK-FFC 底板,您需要使用 26 对 22 引脚的转换器连接器,该连接器仅通过测试焊盘暴露 STROBE/FSIN 线。要同步这些摄像头,您可以从测试焊盘焊接一根线到摄像头模块的 FSIN 排针引脚,或者将所有 FSIN 排针引脚连接在一起,如此处所示。
如前所述,所有 Series 2 OAK PoE 型号 都有一个带 FSYNC/STROBE 信号的 M8 I/O 连接器。但如果您不使用这些,您可能需要将一根线焊接到设备上的 PCB。大多数 PCB 设计是开源的(在 oak-hardware 存储库中), 因此您可以轻松检查 PCB 上的 FSIN/STROBE 信号位置。
如上图所示,在 OAK-FFC-4P 上,您可以启用 您可以在此论坛讨论中找到更多信息。DM9098 板上的 FSIN 线(OAK-D S2、 OAK-D W、OAK-D Pro、 OAK-D Pro W):
NG9093 板上的 FSIN 测试焊盘(OAK-1、 OAK-1 W、OAK-1 Lite、 OAK-1 Lite W、OAK-1 Max):

请注意,立体相机对和彩色相机未连接在一起。
FSYNC 信号
FSYNC 信号输出
目前,只有 OV9282/OV9782 可以输出 FSYNC 信 号,而 IMX378/477/577/等也应该具备该能力,但尚未在固件中支持(因此这些传感器不能驱动 FSYNC 信号,只能被其驱动)。AR0234 仅支持输入 FSYNC 触发。
外部同步帧
Py
1# 示例:我们有 3 个摄像头连接在端口 A、B 和 C 上
2cam_A.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT)
3cam_B.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT)
4cam_C.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT)传感器 FSYNC 支持
- 连续流式传输,带外部同步,通过
CameraControl.setFrameSyncMode()配置。在此模式下, FSIN 信号应以与配置的传感器 FPS 相匹配的连续速率到达,触发器不能在任意时间到达,因为这会干扰传感器的内部操作(导致帧错误等)。它只能纠正随时间产生的非常小的漂移。 - 快照模式,带外部同步,通过
CameraControl.setExternalTrigger()配置。在此模式下, 触发器可以随时到达传感器,传感器将拍摄照片/快照。
| 传感器 | 快门 | 支持情况 |
|---|---|---|
| OV9282、OV9782 | 全局 | 支持 FSYNC 输入/输出,连续模式和快照模式(任意外部触发) |
| OV7251 | 全局 | 应具有与 OV9*82 相同的硬件支持,但目前固件中未实现 |
| AR0234 | 全局 | 支持 FSYNC 输入,连续模式和快照模式 |
| IMX378、IMX477、IMX577、IMX380 | 滚动 | 支持 FSYNC 输入,滚动快门传感器仅支持连续模式。硬件也支持 FSYNC 输出,但固件中尚未实现 |
| IMX582 | 滚动 | 与 IMX378 类似,但尚未测试 |
| IMX296 (RPi GS Camera) | 全局 | XTR/XTRIG 引脚支持任意外部触发。脉冲长度决定曝光时间(传感器特性)。 全局 XTR/XTRIG 引脚支持任意外部触发。脉冲长度决定曝光时间(传感器特性)。 |
外部 FSYNC 示例
旧设备
这是一个如何使用外部 FSYNC 信号触发摄像头传感器的示例。您可以使用任何 Series 2 OAK-D PoE 型号来触发 FSYNC。我们使用了 M8 分线板来暴露 GND/FSYNC 线。
在此示例(脚本在此)中,传感器被设置为
Snapshot mode,因为我们使用开关按钮触发信号。 只有立体摄像头(2x OV9282)被按钮触发,因为 IMX378 彩色摄像头不支持快照模式。 如果我们使用 OV9782 彩色摄像头,它也可以被按钮触发。
FSYNC 触发
只有全局快门(OV9282、OV9782、AR0234...)摄像头支持照片/快照模式下的 FSYNC 触发。滚动快门摄像头(IMX378、IMX477、IMX577 等)不支持此功能。
Strobe 信号
Strobe 演示
帧捕获图
全局快门传感器时序

滚动快门传感器时序

OAK-FFC 硬件同步
Py
1cam_A.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.OUTPUT)
2cam_D.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT)Arducam FFC 摄像头同步

连接 FSIN/STROBE
OAK-FFC-4P FSIN

FSIN_4LANE 和 FSIN_2LANE 与 MXIO6 的连接。下面的脚本将同步连接到 OAK-FFC-4P 的所有 4 个摄像头。Python
1# CAM_A 将驱动所有其他摄像头的 FSIN 信号:
2cam_A.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT) # 4LANE
3cam_B.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.OUTPUT) # 2LANE
4cam_C.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT) # 2LANE
5cam_D.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT) # 4LANE
6
7# 并且重要的是通过设置 GPIO 来连接 A+D 和 B+C 对的 FSIN 信号:
8# OAK-FFC-4P 需要将 MXIO6 驱动为高电平 (FSIN_MODE_SELECT) 以将
9# A+D FSIN 组(4 通道对)与 B+C 组(2 通道对)连接在一起
10config = dai.Device.Config()
11config.board.gpio[6] = dai.BoardConfig.GPIO(dai.BoardConfig.GPIO.OUTPUT,
12 dai.BoardConfig.GPIO.Level.HIGH)
13
14with dai.Device(config) as device:
15 device.startPipeline(pipeline)CAM_B 和 CAM_C
CAM_B 和 CAM_C(2 通道 MIPI 端口)共享相同的 I2C 总线,这意味着如果它们都连接了相同的传感器(FFC 模块),它们将无论如何设置都会同步(因为 I2C 命令“start exporute”将同时到达)。此机制在 OAK-D 相机中用于同步立体相机对。
Series 2 USB OAK

USB OAK-1* FSIN

OAK-D-Lite FSIN

