4、图像采集基础:摄像头帧格式(RGB565、YUV、JPEG)、分辨率与帧率对推理的影响
TinyML 视觉应用的第一公里,是从摄像头传感器到内存中的一帧图像。很多开发者将精力集中在模型结构优化上,却忽略了图像采集链路对端到端延迟、内存占用和推理精度的决定性影响。在资源受限的 MCU 上,摄像头输出的原始格式、分辨率与帧率,直接决定了预处理管线的复杂度、DMA 传输的带宽压力以及神经网络输入张量的填充方式。本章将系统拆解 RGB565、YUV、JPEG 三种主流帧格式的存储结构与适用场景,并量化分析分辨率与帧率对推理节拍的实际约束。
上图展示了从摄像头传感器到推理引擎的完整数据链路。在实际嵌入式系统中,每一个环节都可能成为瓶颈:传感器输出格式决定了每帧数据量,分辨率与帧率共同决定了单位时间内的数据吞吐需求,而 MCU 的 DMA 带宽和 SRAM 容量则限制了可用的缓冲策略。理解这条链路中的量化关系,是设计稳定视觉系统的前提。
4.1 核心原理:三种帧格式的存储结构与适用边界
摄像头传感器输出的原始数据格式,决定了每像素占用的比特数、色彩还原能力以及后续处理的复杂度。在 TinyML 场景中,最常遇到的三种格式是 RGB565、YUV422 和 JPEG。
| 格式 | 每像素位数 | 色彩空间 | 典型场景 | MCU 处理难度 |
|---|---|---|---|---|
| RGB565 | 16 bit | RGB (R:5bit, G:6bit, B:5bit) | 直接显示、简单阈值分割 | 低,可直接映射到 RGB 输入张量 |
| YUV422 | 16 bit (平均) | Y + U/V 色度采样 | 视频流传输、人脸检测前处理 | 中,需做 YUV→RGB 转换 |
| JPEG | 可变 (压缩) | YCbCr (DCT 变换) | 拍照存储、离线分析 | 高,需软件解码,内存开销大 |
RGB565 是大多数低端摄像头模块(如 OV7670)直接输出的格式。每个像素用 16 位表示,其中红色 5 位、绿色 6 位(人眼对绿色最敏感)、蓝色 5 位。这种格式的优势在于:无需任何转换即可直接填充到 TensorFlow Lite 的输入张量中(只需将 16 位拆分为 8 位通道)。但它的缺点是色彩精度有限,在光照剧烈变化时可能出现色带。
YUV422 将亮度(Y)与色度(U/V)分离,每两个像素共享一组 U/V 值。这种格式在视频传输中非常高效,因为人眼对亮度变化更敏感。但在 MCU 上使用时,必须先将 YUV 转换为 RGB 才能送入神经网络——这个转换过程涉及整数乘法和移位操作,在 Cortex-M4 上大约需要 5-10 个周期/像素。对于 320×240 分辨率,单帧转换需要约 40 万次操作,在 100 MHz 主频下耗时约 4 ms。
JPEG 是压缩格式,通常由带有 JPEG 编码器的摄像头(如 OV2640)直接输出。它的优势是存储占用极小(通常为原始数据的 1/10 到 1/20),适合通过 SPI 或 UART 传输。但代价是解码需要大量内存和计算:一个 320×240 的 JPEG 图像解码后需要 150 KB 的 RGB 缓冲,而解码过程在 MCU 上可能需要 100-300 ms。因此,JPEG 格式在 TinyML 实时推理中很少直接使用,除非有硬件 JPEG 解码器。
关键判断:对于绝大多数 TinyML 视觉应用,RGB565 是最佳选择。它避免了格式转换开销,且 16 位数据可以直接通过 DMA 搬运到内存。如果摄像头只支持 YUV 输出,则需评估转换耗时是否在帧间隔预算内。JPEG 仅适用于非实时或离线处理场景。
4.2 判断方法:分辨率与帧率对推理节拍的量化影响
分辨率决定了每帧的像素总数,帧率决定了每秒需要处理的帧数。两者共同决定了系统的数据吞吐率,进而影响推理节拍的设计。以下是具体的量化分析方法:
- 计算单帧数据量:对于 RGB565,单帧字节数 = 宽度 × 高度 × 2。例如 QVGA(320×240)为 153,600 字节(150 KB)。
- 计算传输时间:假设使用 8 位并行 DVP 接口,PCLK 为 24 MHz,则传输一帧需要 153,600 × 8 / 24,000,000 ≈ 51.2 ms。这意味着最高只能达到约 19 FPS。
- 评估预处理开销:包括格式转换(如有)、缩放(如从 320×240 缩放到 96×96)、归一化。在 Cortex-M4 上,双线性插值缩放 320×240→96×96 大约需要 15-25 ms。
- 估算推理时间:以 MobileNetV1 量化模型(输入 96×96)为例,在 200 MHz Cortex-M7 上推理时间约为 80-150 ms。
- 计算总帧周期:总时间 = 传输时间 + 预处理时间 + 推理时间。若总时间小于 1/目标帧率,则系统可行。
| 分辨率 | RGB565 帧大小 | 24MHz PCLK 传输时间 | 推理输入建议 | 典型帧率上限 |
|---|---|---|---|---|
| QQVGA (160×120) | 38.4 KB | 12.8 ms | 48×48 或 64×64 | 30 FPS |
| QVGA (320×240) | 150 KB | 51.2 ms | 96×96 或 128×128 | 15 FPS |
| VGA (640×480) | 600 KB | 204.8 ms | 128×128(需缩放) | 4 FPS |
从表中可以看出,分辨率越高,帧率上限越低。在 TinyML 场景中,通常建议使用 QVGA 或更低分辨率采集,然后通过裁剪或缩放得到模型输入尺寸。一个实用的原则是:采集分辨率不应超过模型输入分辨率的 3 倍,否则缩放开销会吞噬推理节省的时间。
4.3 案例拆解:基于 OV2640 的 QVGA 实时人脸检测系统
我们设计一个基于 STM32F746(Cortex-M7, 216 MHz)的人脸检测系统,使用 OV2640 摄像头,目标帧率 10 FPS。
初始参数与约束:
- 摄像头输出:RGB565,QVGA(320×240),PCLK = 24 MHz
- 模型输入:96×96×3,MobileNetV1 量化模型,推理时间约 120 ms
- SRAM 可用:256 KB(其中模型权重占用约 180 KB)
- DMA 通道:2 个,支持双缓冲
分析与决策过程:
首先计算帧传输时间:150 KB / 24 MB/s ≈ 6.25 ms(实际因行消隐略高,约 7 ms)。预处理(缩放+归一化)约 20 ms。推理 120 ms。总周期 = 7 + 20 + 120 = 147 ms,对应帧率约 6.8 FPS,未达到 10 FPS 目标。
优化措施:
- 将摄像头输出分辨率降为 QQVGA(160×120),帧大小降至 38.4 KB,传输时间降至 1.6 ms。
- 使用 DMA 双缓冲:在推理当前帧时,DMA 同时采集下一帧,隐藏传输时间。
- 将缩放操作改为最近邻插值(从 160×120 到 96×96),耗时从 20 ms 降至 5 ms。
- 优化后总周期 = 1.6(隐藏)+ 5 + 120 = 125 ms,帧率约 8 FPS。进一步将模型输入改为 64×64(推理时间降至 70 ms),总周期 = 5 + 70 = 75 ms,达到 13 FPS。
结果对比:
| 方案 | 采集分辨率 | 模型输入 | 推理时间 | 实际帧率 | 内存占用 |
|---|---|---|---|---|---|
| 初始方案 | 320×240 | 96×96 | 120 ms | 6.8 FPS | 150 KB×2 |
| 优化方案 | 160×120 | 64×64 | 70 ms | 13 FPS | 38.4 KB×2 |
风险与代价:降低采集分辨率会损失小目标检测能力(如距离较远的人脸)。如果应用场景需要检测小目标,则需保留 QVGA 采集,但接受较低的帧率,或使用更轻量的模型(如 MobileNetV2 0.35 倍宽度)。
经验复盘:在 TinyML 视觉系统中,帧率瓶颈往往不在推理,而在图像采集与预处理。优先降低采集分辨率,再考虑模型压缩。双缓冲是隐藏传输延迟的关键手段,但需要确保 DMA 描述符和缓冲区地址对齐(通常要求 4 字节对齐)。
4.4 常见误区与总结复盘
在实际项目中,开发者常陷入以下误区:
- 误区一:追求高分辨率采集。认为分辨率越高识别越准,忽略了 MCU 内存和带宽限制。实际上,模型输入分辨率才是决定精度的关键,采集分辨率只需略高于输入即可。
- 误区二:忽略 YUV 转换开销。某些摄像头默认输出 YUV422,开发者未做转换直接送入模型,导致推理结果异常。YUV 与 RGB 的转换必须显式完成,且应使用查表法或移位近似以加速。
- 误区三:JPEG 直接解码。在 MCU 上使用 JPEG 格式时,未评估解码时间。一个 320×240 JPEG 解码在纯软件下可能耗时 200 ms 以上,完全破坏实时性。
- 误区四:帧率计算错误。只计算推理时间,忽略了传输和预处理。正确的帧周期 = max(传输时间, 推理时间) + 预处理时间(若无法流水线化)。
总结:图像采集是 TinyML 视觉系统的第一道关卡。选择 RGB565 格式、合理设置分辨率(通常 QVGA 或更低)、利用 DMA 双缓冲隐藏传输延迟,是构建稳定实时系统的三大支柱。在项目初期,应使用本章的量化公式进行预算评估,避免后期返工。记住一个核心公式:可用帧率 = 1 / (max(传输时间, 推理时间) + 预处理时间),并始终为系统保留 20% 的余量以应对突发负载。
风险提示:当使用双缓冲时,务必确保在推理完成前不要覆盖正在使用的帧缓冲区。推荐使用三缓冲机制(采集、处理、推理各占一个缓冲区),但需评估内存是否充足。若内存不足,可采用"采集→推理→等待"的同步模式,但帧率会下降约 30%。