【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
整个isp的流水线还是比较好懂的。它的输入是sensor的bayer图像,这是由sensor基本结构决定的。它的输出是yuv,或者是rgb图像,也就是最终我们要想的结果。整个isp当中有很多的算法,每一个算法的输入,都是前面一个算法的输出,全部算法是采用pipeline机制完成的。也就是说,所有的算法都是并发执行的,不存在一个算法等另外一个算法的情形。但除此之外,isp还有一个特殊的机制,那就是反馈机制,值得我们研究一下。

1、什么是反馈机制
所谓的反馈机制,就是等到某一个算法执行之后,比如上图中的alg2,我们通过某个函数获取alg2结果中的一些统计信息。等拿到这些结果之后,就可以用于设置前面的alg1算法。这就意味着,alg1的输出不仅和input有关,还和alg2的输出结果有关。
2、一般统计信息
isp最重要的信息统计主要是3a,即自动曝光、自动对焦、自动白平衡。至于拿到这些结果,怎么对算法进行调优,这里每家都有自己的know-how,并没有一个明确的标准。
3、基于统计的流水线算法
上一次代码分析当中,我们看到只是执行了run_pipeline,中间也拿到了统计数据,但是并没有对这些统计数据进行使用,今天看看是怎么使用的。代码还是位于infinite_isp.py,
def execute_with_3a_statistics(self):
"""
Execute Infinite-ISP with AWB gains and correct exposure
"""
# Maximum Iterations depend on total permissible gains
max_dg = len(self.parm_dga["gain_array"])
# Run ISP-Pipeline
self.run_pipeline(visualize_output=False)
self.load_3a_statistics()
while not (
(self.ae_feedback == 0)
or (self.ae_feedback == -1 and self.dga_current_gain == max_dg)
or (self.ae_feedback == 1 and self.dga_current_gain == 0)
or self.ae_feedback is None
):
self.run_pipeline(visualize_output=False)
self.load_3a_statistics()
self.run_pipeline(visualize_output=True)
4、分析execute_with_3a_statistics函数
这个函数和run_pipeline最大的区别就是,它执行了流水线之后,还会继续调用load_3a_statistics函数。很明显,这里的load_3a_statistics就是利用了流水线的统计结果,对算法的入参做了修正。当然这里的execute_with_3a_statistcis当中出现了多次run_pipeline和load_3a_statistics的操作,只是为了演示使用流程。**在实际的pipeline流水线当中,因为图像是一直从sensor里面出来的,所以当前的统计结果只会对下一个frame有影响,对当前的image其实是没有效果的。**这一点需要注意下,并不会像python函数中显示的那样,会不停对同一张图片进行循环处理。
def load_3a_statistics(self, awb_on=True, ae_on=True):
"""
Update 3A Stats into WB and DG modules parameters
"""
# Update 3A in c_yaml too because it is output config
if awb_on is True and self.parm_dga["is_auto"] and self.parm_awb["is_enable"]:
self.parm_wbc["r_gain"] = self.c_yaml["white_balance"]["r_gain"] = float(
self.awb_gains[0]
)
self.parm_wbc["b_gain"] = self.c_yaml["white_balance"]["b_gain"] = float(
self.awb_gains[1]
)
if ae_on is True and self.parm_dga["is_auto"] and self.parm_ae["is_enable"]:
self.parm_dga["ae_feedback"] = self.c_yaml["digital_gain"][
"ae_feedback"
] = self.ae_feedback
self.parm_dga["current_gain"] = self.c_yaml["digital_gain"][
"current_gain"
] = self.dga_current_gain
5、继续分析load_3a_statistics函数
这个函数看上去就比较明白了,之前我们拿到的self.awb_gains和self.ae_feedbac在这里就发挥了用处,直接赋值给对应的算法模块,方便下一次图像处理,也就是下一次的run_pipeline调用。
6、算法的参数配置
不同算法的参数差异很大,有的参数很多,有的参数很少,这都是不一定的。具体的算法模块,都是位于modules子目录下面,大家可以好好看一看。算法参数,则可以参考config子目录,
crop:
is_enable: false
is_debug: false
new_width: 1280
new_height: 720
is_save: false
随便挑一个crop模块分析。is_enable表示是否启用,is_debug表示是否添加打印信息,new_width和new_height应该是最终裁剪的大小,is_save表示是否保存。特别是最后一个,有的时候为了查看调试算法效果,需要把中间的图像结果保存下来,用于对比使用。