尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

039、瑞芯微RK3588的ISP 3A框架调试——从AE/AWB统计到硬件收敛的实战问题

039、瑞芯微RK3588的ISP 3A框架调试——从AE/AWB统计到硬件收敛的实战问题 039、瑞芯微RK3588的ISP 3A框架调试——从AE/AWB统计到硬件收敛的实战问题开篇一个让我熬了两周的AE振荡问题先讲个真事。去年做一款双目行车记录仪主控RK3588前摄IMX415后摄GC2053。方案定下来的时候原厂FAE拍胸脯说RK3588的ISP 3A很成熟直接跑rkaiq就行。结果样机一上电前摄在傍晚逆光场景下画面亮度像呼吸灯一样——忽明忽暗周期大概两秒一次肉眼可见的难受。示波器挂上I2C抓曝光寄存器发现AE目标亮度在120到180之间来回跳增益在2.4倍和3.6倍之间反复横跳但统计值始终没稳定下来。当时第一反应是tuning参数没调好把AE的收敛步长调小阻尼系数加大结果振荡更严重了。后来查了整整两周最后定位到问题根本不在AE算法本身而是AWB的统计窗口和AE的统计窗口重叠AWB在低色温下把R通道增益拉得过高导致AE统计的Y值被R通道的过曝像素污染。这种跨模块耦合的问题在RK3588这种多ISP核的架构上特别容易踩。RK3588的ISP 3A框架到底长什么样先别急着调参数得把框架摸清楚。RK3588的ISP是双核的每个核可以独立跑一条sensor pipeline但3A统计模块是共享的。也就是说你前摄和后摄的AE/AWB统计都会写到同一块DDR缓冲区然后由rkiq瑞芯微的3A算法库统一处理。这个设计有个好处——两个sensor可以共用一套3A策略但坏处是——如果你两个sensor的曝光时间差异很大统计值的时序戳会打架。具体到代码层面RK3588的3A框架分三层底层是ISP驱动负责把硬件统计值AE histogram、AWB的R/G/B平均值、AF的对比度值通过vbuf机制上报到用户态。这里有个关键点——统计值的格式是固定的比如AE统计是256bin的亮度直方图AWB统计是分成5x5的网格每个网格输出R/G/B的平均值和饱和度。别去改这个格式改了你后面所有算法都得跟着改。中间层是rkiq库这是瑞芯微提供的闭源算法库里面跑着AE、AWB、AF的算法主体。rkiq对外暴露的接口很简单——你给它统计值它给你曝光、增益、白平衡增益的设定值。但rkiq内部是有状态机的比如AE有快速收敛模式和慢速稳定模式AWB有灰色世界和白色世界两种假设。这些状态切换的时机rkiq不会告诉你你只能通过调试日志去猜。最上层是应用层就是你自己的3A策略代码。你可以完全不用rkiq自己写AE/AWB算法但那样工作量巨大。大多数方案商的做法是——用rkiq的默认算法然后通过rkaiq的tuning工具去调参数。但这里有个坑——rkaiq的tuning工具只暴露了部分参数很多内部状态机的阈值你是改不到的。AE统计的硬件细节——别被datasheet骗了RK3588的AE统计硬件上支持两种模式全局直方图和分区加权直方图。全局直方图就是整个画面256个bin的亮度分布分区加权是把画面分成15x15的网格每个网格可以单独设置权重。默认情况下rkaiq用的是分区加权模式权重矩阵在tuning文件里配置。但实际调试中发现分区加权模式有个隐藏问题——网格的权重是线性叠加的不是归一化的。如果你把中心区域的权重设成10边缘设成1那么统计出来的直方图总量是各个网格加权后的累加而不是平均。这会导致一个问题——如果画面里有一小块高亮区域比如车灯即使它只占一个网格它的权重也会被放大从而拉高整个AE的目标亮度。我踩过的坑是——把中心权重设成8边缘设成1结果在夜间场景下路灯直射的区域把AE目标亮度拉高了20个灰阶整个画面发灰。后来把权重改成中心4、边缘2问题就缓解了。所以调AE权重的时候一定要记住——权重是乘法关系不是加法关系高权重区域的统计值会主导整个AE的收敛方向。另外RK3588的AE统计有个硬件特性——它统计的是Y值但Y值的计算方式是Y (R77 G150 B*29) 8这个公式是固定的你改不了。但你可以通过调整AWB的增益来间接影响Y值——如果AWB把R通道增益拉高那么Y值里R的贡献就会变大。这就是我开篇说的那个问题的根源——AWB的R增益过高导致AE统计的Y值被R通道污染。AWB统计的网格陷阱RK3588的AWB统计是5x5网格每个网格输出R/G/B的平均值和饱和度。但注意——这个平均值是网格内所有像素的算术平均不是加权平均。如果你的画面里有一个网格同时包含白色区域和彩色区域那么该网格的R/G/B平均值会被拉向灰色导致AWB算法误判。调试AWB时我习惯先把5x5网格的统计值dump出来用Python画成热力图看看每个网格的色温分布。RK3588的rkiq库支持通过debugfs节点dump统计值路径是/sys/kernel/debug/rkisp/video0/awb_stat。这个节点输出的格式是——每行一个网格依次是R、G、B的平均值和饱和度共25行。有一次调试一个室内场景发现网格(2,3)的R值异常高但那个区域明明是一面白墙。后来查了sensor的配置发现是IR cut filter没有完全切换导致红外光进入了R通道。这个问题在RK3588上特别容易忽略——因为RK3588的ISP支持IR cut filter的自动控制但默认配置下IR cut filter的切换是由GPIO控制的不是由ISP自动管理的。如果你用的是定焦模组IR cut filter是固定的那没问题。但如果是变焦模组IR cut filter的切换时序没调好AWB就会在室内外切换时出现严重的偏色。硬件收敛的时序问题——这是最容易被忽视的3A收敛不只是算法的事还涉及硬件时序。RK3588的ISP pipeline里AE和AWB的统计值是在曝光结束后的VSYNC中断里读取的但曝光和VSYNC之间有一个延迟——这个延迟取决于sensor的曝光模式rolling shutter还是global shutter和行时间。具体来说RK3588的ISP驱动会在VSYNC中断里读取统计值但统计值对应的是上一次曝光的画面。也就是说你读到统计值的时候sensor已经在进行下一次曝光了。如果你在应用层直接根据统计值去设置曝光和增益那么你设置的值会作用到下一次曝光但统计值对应的画面和下一次曝光的画面之间有一个帧的延迟。这个延迟在慢速场景下没问题但在快速运动的场景下——比如行车记录仪拍对面来车——会导致AE和AWB的收敛滞后。我调试时发现RK3588的rkiq库内部其实已经做了时序补偿但补偿的帧数是通过tuning参数配置的默认是2帧。如果你把补偿帧数改成1收敛速度会变快但稳定性会变差——在闪烁光源下比如LED路灯AE会跟着闪烁频率振荡。这里有个经验值——对于60fps的sensor补偿帧数设2帧比较稳对于30fps的sensor设3帧比较稳。但具体还要看sensor的曝光模式如果是global shutter补偿帧数可以少一帧因为曝光和读取是同时完成的。实战问题AE振荡的根因分析回到开篇那个AE振荡问题。当时我做了以下排查步骤第一步dump AE统计值看直方图的分布。发现直方图在低亮度区域bin 0-50有一个明显的峰值但高亮度区域bin 200-255也有一个小的峰值。这说明画面里同时存在暗部和亮部AE算法在权衡两个峰值时出现了犹豫。第二步检查AWB的统计值。发现R通道的增益在1.8到2.2之间波动而G和B的增益相对稳定。进一步看AWB的5x5网格发现网格(0,4)画面右上角的R值异常高那个区域正好是傍晚的天空——色温低R值本来就高但AWB算法把整个画面的R增益都拉高了。第三步把AWB的统计窗口缩小只保留画面中央的3x3网格排除天空区域的影响。结果AE振荡消失了但画面中央的色温偏冷——因为AWB失去了对天空区域的参考。最终解决方案是——在tuning文件里把AWB的统计窗口改成中央5x3网格横向5个纵向3个同时把AE的分区权重改成中心区域权重为6边缘为2。这样既保留了AWB对中央区域的色温参考又避免了边缘高亮区域对AE的干扰。这个问题的本质是——AE和AWB的统计窗口重叠但两个算法的目标函数不同。AE希望整体亮度均匀AWB希望找到中性色参考。当画面里同时存在高亮和低色温区域时两个算法的优化方向会冲突。解决思路不是去调算法的收敛参数而是去调整统计窗口的几何形状让两个算法各取所需。调试工具链——别只靠肉眼RK3588的调试工具链比之前的RK3288/RK3399完善很多但依然有坑。最常用的工具是rkaiq_tool_server它可以通过网络连接PC端的RKISP Tuning Tool实时查看AE/AWB/AF的统计值和算法状态。但注意——这个工具默认只支持单sensor调试如果你同时跑两个sensor需要开两个server实例端口要错开。另一个好用的工具是v4l2-ctl可以直接读取ISP的统计节点。比如v4l2-ctl -d /dev/video0 --get-ctrl ae_stat可以拿到AE统计的原始值。但这里有个坑——RK3588的ISP驱动把统计值放在一个自定义的control里不是标准的V4L2 control所以v4l2-ctl的--list-ctrls看不到它。你需要用media-ctl先找到对应的entity然后直接用ioctl去读。我个人的习惯是——写一个小的Python脚本周期性地读取AE/AWB统计值然后画成曲线。这样能看到收敛过程的动态变化比看静态截图直观得多。脚本的核心逻辑很简单——打开/dev/video0用VIDIOC_QUERY_EXT_CTRL去读自定义control解析出统计值然后用matplotlib画图。注意——读统计值的频率不能太高否则会占用ISP的带宽影响sensor的帧率。我一般设成10Hz也就是每100ms读一次。量产时的3A参数固化调试完的3A参数最终要固化到产线。RK3588的tuning参数是放在一个JSON文件里的产线烧录时会把JSON文件烧到系统的/etc/iqfiles/目录下。但这里有个坑——JSON文件里有些参数是sensor相关的比如AE的曝光范围、AWB的色温范围这些参数在产线校准后需要更新。产线校准通常做两件事——一是暗电流校准二是白平衡校准。暗电流校准是拍一张全黑画面记录每个像素的暗电流值然后写入sensor的寄存器。白平衡校准是拍一张标准灰卡计算R/G/B的增益然后写入tuning文件。但RK3588的tuning文件里白平衡增益是分色温段的——比如低色温段2500K-3500K一个增益中色温段3500K-5000K一个增益高色温段5000K-7500K一个增益。产线校准通常只校准一个色温段一般是D65即6500K其他色温段沿用默认值。这会导致一个问题——如果产线校准时的光源色温不准那么其他色温段的增益就会偏。我建议产线校准用双光源——一个D65一个A光源2856K分别校准两个色温段的增益然后线性插值得到中间色温段的增益。但这样会增加产线工时所以很多方案商为了省时间只校准D65。结果就是——室内暖光灯下偏黄室外阴天偏蓝。这个问题的根因不在算法而在产线校准的流程设计。个人经验总结做RK3588的ISP 3A调试我最大的体会是——不要一上来就调算法参数先花时间把统计值的硬件特性摸清楚。RK3588的ISP统计硬件和之前的高通、联发科平台都不一样它的网格统计是固定格式的但权重和窗口是可配置的。这些配置项之间的耦合关系datasheet里不会写清楚只能靠实测去摸索。另一个经验是——3A调试一定要有数据意识。不要靠肉眼判断画面好坏要把AE的曝光时间、增益、AWB的R/G/B增益、统计值的均值/方差都记录下来画成曲线。只有数据才能告诉你收敛过程是过冲还是欠冲是振荡还是稳定。最后量产前的3A参数固化一定要做产线校准的流程验证。很多问题在实验室里看不出来一到产线就暴露——比如光源色温不稳定、sensor的暗电流不一致、IR cut filter的切换时序偏差。这些问题的排查思路和算法调试完全不同需要的是流程设计和统计分析而不是调参。RK3588的ISP 3A框架说复杂也复杂说简单也简单。复杂在于它把AE/AWB/AF的统计和算法分成了两层中间还有时序补偿的机制。简单在于它的统计值格式是固定的只要摸清了统计值的物理含义调试思路就清晰了。希望这篇笔记能帮你少走一些弯路。
返回列表