4.17. 传感器调节项¶
除了 pixformat() 和 framesize() 之外,CSI 类还提供了若干几乎每个应用迟早都会用到的逐传感器控制项——安装朝向、曝光、增益、白平衡以及一些调试辅助功能。每一项都直接对应前文介绍过的某个传感器概念;API 只是为驱动在底层执行的寄存器写入提供了一个 Python 句柄。
下面所有方法都作用于底层传感器。它们都通过传感器的 I2C 控制总线 写入寄存器,因此开销只有几微秒,且新设置会在 下一次 曝光时生效——通常就是下一次 snapshot()。
4.17.1. 朝向¶
摄像头并不知道自己是以哪个方向安装的。在传感器端施加两个翻转标志,即可在任何像素离开芯片之前把画面摆正:
csi0.hmirror(True)
csi0.vflip(True)
hmirror() 进行左右翻转,vflip() 进行上下翻转。两者结合即可覆盖实践中遇到的各种情况:倒装的板子(两个标志都为 True)、置于前表面反射镜后方的板子(仅 hmirror),或从下方观察反射场景的板子(仅 vflip)。
由于翻转发生在传感器的读出逻辑中,因此没有 CPU 开销,也没有内存开销——帧落入帧缓冲区时就已经是正确朝向的了。
4.17.2. 曝光¶
曝光即积分时间——每个像素中的光电二极管在该行被读出之前收集电荷的时长,以微秒为单位。驱动启动时会运行传感器的自动曝光环路,因此摄像头会尝试将平均像素值保持在目标附近。禁用该环路会将曝光固定为应用所选择的值:
csi0.auto_exposure(False, exposure_us=8000)
当场景亮度稳定,且应用需要可预测的运动模糊或逐帧一致的强度以进行阈值处理时,固定曝光是正确的选择。读回当前曝光值——无论它是由环路设置的还是由应用设置的——是另一个单独的调用:
us = csi0.exposure_us()
以 True 调用 auto_exposure() 而不传入曝光值,会将控制权交还给环路。
4.17.3. 增益¶
增益是在像素电压到达 ADC 之前对其施加的放大量,以分贝为单位。与曝光类似,驱动启动时会开启自动增益环路。常见两种用法。设定上限可让环路适应光照,但避免它在昏暗场景中无限放大噪声:
csi0.auto_gain(True, gain_db_ceiling=16)
当应用同时固定曝光时,固定增益是正确的做法——对于像颜色跟踪这种需要逐帧比较像素值的应用而言,增益的稳定性至关重要:
csi0.auto_gain(False, gain_db=0)
当前增益通过 gain_db() 读回。每当应用禁用自动增益时,也应当同时禁用自动白平衡和自动曝光——否则仍在运行的控制环路会以破坏固定增益的方式来回调整图像。
4.17.4. 白平衡¶
白平衡是 ISP 对去拜耳阶段输出的红、绿、蓝三个通道分别施加的逐通道增益,使白色物体在任何颜色的光照下都呈现为白色。自动白平衡环路根据 ISP 在每帧上收集的逐区域 统计数据 计算出这三个增益,并在下一帧应用它们。
大多数应用会让该环路保持运行。颜色跟踪是常见的例外——这些增益也正是环路用来追逐有色物体的调整对象,因此如果应用试图寻找红色色块,环路会悄悄地调暗红色通道,色块就不再匹配了。锁定环路即可解决此问题:
csi0.auto_whitebal(False)
传入一个以分贝为单位的明确 (r, g, b) 元组,可实现可重复的颜色校准——在不同板子和不同会话之间使用相同的增益:
csi0.auto_whitebal(False, rgb_gain_db=(0.0, 0.0, 0.0))
当前增益通过 rgb_gain_db() 以元组形式读回。
4.17.5. 帧率上限¶
传感器默认以其原生帧率运行——大多数器件为每秒 30 到 60 帧,在帧尺寸足够小时,高速传感器可达到远高于此的帧率。设定帧率上限可让应用将摄像头限制到下游处理能够跟上的速率:
csi0.framerate(15)
在支持硬件帧率控制的传感器上,该调用还会延长每帧的曝光预算,这在弱光下会有帮助;在其他传感器上,驱动只是在帧缓冲区层面跳过多余的帧。
4.17.6. 测试图案¶
彩条测试图案内置于大多数传感器中,可用于区分 成像 问题和 输出 问题。开启它会绕过光电二极管阵列,并沿同一条像素数据通路发送一个固定图案:
csi0.colorbar(True)
如果测试图案看起来正常但实时图像不正常,则故障出在光学系统或传感器的模拟前端;如果连测试图案都损坏了,则问题出在像素数据总线上的某处,或出在 pixformat() / framesize() 配置中。传入 False 即可返回实时图像。