第四章 图像采集与预处理:摄像头驱动与ISP调优

好,咱们进入第四章。这一章,说白了就是嵌入式视觉系统的「眼睛」怎么睁开、怎么看清的问题。

我刚开始做嵌入式视觉那会儿,踩过最大的坑就是——摄像头能出图,但图像质量一塌糊涂。后来才发现,不是传感器不行,是驱动没配好,ISP参数没调对。嗯,这节课咱们就把这些坑一个个填上。

4.1 摄像头驱动:MIPI与USB

摄像头接口,目前主流就两派:MIPI CSI 和 USB。我个人习惯,能走MIPI就走MIPI,延迟低、带宽大、可控性强。但USB也有它的好处——即插即用,开发快。

4.1.1 MIPI CSI驱动要点

MIPI驱动,核心就三件事:

  • 时钟配置:MIPI的时钟是差分对,频率要跟传感器和主控匹配。我遇到过一块板子,摄像头死活不出图,查了两天,结果是时钟相位反了。
  • 数据通道:1-lane、2-lane、4-lane,通道数越多带宽越大,但布线也越复杂。量产项目我建议用2-lane,性价比最高。
  • I2C控制:传感器寄存器配置全靠I2C。注意上拉电阻,我吃过这个亏——I2C波形不对,寄存器写不进去。

重要:MIPI驱动调试时,先看时钟有没有输出,再看数据通道有没有信号。用示波器量一下,比看代码快得多。

4.1.2 USB摄像头驱动

USB摄像头就简单多了。Linux下UVC驱动基本通吃。但要注意:

  • USB带宽有限,高分辨率高帧率容易丢帧
  • USB 2.0理论带宽480Mbps,实际能跑300Mbps就不错了
  • USB 3.0好很多,但功耗也上去了

经验之谈:我曾经在一个无人机项目里用USB摄像头,结果飞行时图像卡顿。后来发现是USB线太长,信号衰减。换成屏蔽线就好了。

4.2 图像格式:RAW、YUV、RGB

图像格式这块,很多新手容易搞混。我简单梳理一下。

格式 特点 典型应用
RAW 传感器原始数据,未经过任何处理 专业摄影、ISP调优
YUV 亮度+色度分离,压缩效率高 视频编码、传输
RGB 三通道彩色,人眼直观 显示、图像处理

4.2.1 RAW格式

RAW格式说白了就是传感器每个像素点的原始电压值。Bayer阵列最常见,RGGB模式。为什么用RAW?因为后期处理空间大。你想想看,白平衡、去马赛克、降噪,这些在RAW域做效果最好。

注意:RAW格式数据量巨大。一个1200万像素的传感器,一张RAW图就要20MB以上。嵌入式设备存储和带宽都要考虑。

4.2.2 YUV格式

YUV格式把亮度(Y)和色度(UV)分开。人眼对亮度敏感,对色度不敏感,所以UV可以降采样。YUV420最常见,UV分量只有Y的1/4。

我记得有个项目,客户要求视频流实时传输。用RGB直接传,带宽不够。换成YUV420,带宽直接降到1/3,效果还看不出差别。

4.2.3 RGB格式

RGB最直观,但数据量大。嵌入式设备里,RGB888一个像素3字节,RGB565一个像素2字节。我建议能用RGB565就用RGB565,省带宽省内存。

4.3 分辨率与帧率配置

分辨率和帧率,是嵌入式视觉系统里最纠结的权衡。分辨率高,细节多,但帧率上不去。帧率高,运动捕捉好,但分辨率得降。

我一般这样选:

  • 人脸检测:640x480 @ 30fps 就够了
  • 车牌识别:1280x720 @ 25fps
  • 工业缺陷检测:1920x1080 @ 60fps(需要硬件加速)

核心原则:先满足帧率要求,再尽量提高分辨率。帧率不够,算法再强也白搭。

4.3.1 配置示例

以OV5640传感器为例,配置1080p @ 30fps的代码片段:

// 设置分辨率
write_sensor_reg(0x3808, 0x07);  // 宽度高字节
write_sensor_reg(0x3809, 0x80);  // 宽度低字节 (1920)
write_sensor_reg(0x380A, 0x04);  // 高度高字节
write_sensor_reg(0x380B, 0x38);  // 高度低字节 (1080)

// 设置帧率
write_sensor_reg(0x3035, 0x11);  // PLL分频
write_sensor_reg(0x3036, 0x46);  // PLL倍频
write_sensor_reg(0x3037, 0x08);  // 输出分频

小技巧:配置完分辨率后,一定要读回确认。我遇到过寄存器写成功但实际没生效的情况,读回才发现是I2C时序问题。

4.4 ISP基础调优

ISP(图像信号处理器)是嵌入式视觉的灵魂。同样的传感器,ISP调好了,图像质量天差地别。

4.4.1 黑电平校正

黑电平校正,说白了就是把传感器暗电流导致的偏置去掉。不校正的话,黑色场景会发灰。

我曾经在一个夜视项目里,图像总是偏绿。查了半天,发现是黑电平校正参数没更新。换了新传感器,参数得重新标定。

4.4.2 白平衡

白平衡让白色在不同光源下看起来都是白色。自动白平衡(AWB)算法很多,格雷世界法、完美反射法。我建议用灰度世界法,简单稳定。

4.4.3 去马赛克

去马赛克就是把Bayer阵列恢复成彩色图像。算法好坏直接影响图像细节。双线性插值最快,但边缘有锯齿。自适应插值效果好,但计算量大。

我的建议:嵌入式设备里,用双线性插值+边缘增强,性价比最高。别追求顶级算法,跑不动等于白搭。

4.4.4 降噪

降噪是ISP里最耗算力的模块。空域降噪(如高斯滤波)简单,但会模糊细节。时域降噪效果好,但需要帧缓存。

我一般这样配:低光照场景开强降噪,正常光照开弱降噪或者不开。动态调整比固定参数好得多。

4.4.5 调优流程

  1. 先调黑电平,确保黑色场景正确
  2. 再调白平衡,让颜色准确
  3. 然后调去马赛克,保证细节
  4. 最后调降噪,平衡噪声和细节

重要提醒:ISP参数不是调一次就完事的。不同光照条件、不同场景,参数都要微调。量产前一定要做充分的场景覆盖测试。

嗯,这一章的内容就这些。图像采集和预处理是嵌入式视觉的地基,地基打不好,上层算法再牛也白搭。下一章咱们聊聊图像预处理算法,包括缩放、旋转、色彩空间转换这些基本功。