接上一篇,上一篇是原理篇,这一篇是实战篇,为了实现下面框图中的不完美ISP。
第一章 做一张RAW图自己用
不是所有的人都能获得raw图,即使获得了raw图也需要对应的sensor参数才能把它用起来,所以我找了一条野路子可以把任意一张.jpg、.bmp或.png图像做成raw图,这样就可以避免对设备的依赖。
ISP的pipeline正向使用可以把raw图解析成人眼适宜观看的rgb图像,把rgb图像沿着ISP的pipeline反着推导回去,也可以获得raw图,而且参数可调。
1.1. 挑选一张输入图像
我喜欢使用色卡,色卡图像没有复杂的线条,并且包含丰富的色块,所以pipeline的第一张测试图,我选择用色卡开始,fig.1是我挑选的测试图。
1.2. 模糊图像——锐化的反变换
采用高斯滤波,把fig.1模糊掉,效果如fig.2所示:
1.3. 加高斯噪声——降噪的反变换
挑选一个力度的高斯噪声,加到fig.2的图像上,得到的效果如fig.3所示:
1.4. 亮度调整——Gamma的反变换
gamma系数选择2.2,得到的效果如fig.4所示:
1.5. RGB域转到XYZ域——CCM的反变换
这步可能会有争议,毕竟CCM和一些相机参数有关,但是我现在没有相机参数,而我手里有标准RGB域和XYZ域互转的3x3矩阵,所以我选择把CCM转到XYZ域,得到的效果如fig.5所示:
1.6. 设置k系数——白平衡的逆变换
得到的效果如fig.6所示:
1.7. 拆成bayer模式——demosaic的逆变换
把RGB图按照byaer模式抽点,得到的效果如fig.7所示,图片中分方块是分辨率的问题,显示的分辨率过大matlab会出现这样的情况,全屏就可以了。
1.8. 加入椒盐噪声——坏点的反变换
加入椒盐噪声的效果如fig.8所示,图像中的块仍然是显示问题,全屏或者设置imshow函数的参数就能解决。
1.9. 加入偏置——black level的反变换
得到的效果如fig.9所示,这一步其实也可以忽略,因为原理很简单,且sensor参数会明确告知,省掉也不影响算法理解。
1.10. 保存图像
直接用save保存成.mat文件,不要用imwrite函数写成.bmp或者其他的格式的输出文件,因为.bmp格式的文件会压缩,压缩就意味着数据精度有一定的丢失,且用眼睛几乎看不出来,这样后面调试ISP的时候都不知道是在哪里丢失了精度。
具体代码可以参考input_to_raw.m
第二章 用做出来的RAW图调试ISP
有了raw图就可以进行ISP中每一步的调试了,现在要开始走正向的ISP了,先把刚才保存的.mat文件load进来。pipeline中的每个模块都写成了函数的形式,直接调用就可以,只是有些参数在函数里面,未使用传参统一管理。
2.1. Black Level
前面加了多少偏置还记得吧,减掉就可以了,得到的效果图如fig.10所示,块效应仍然是显示问题,全屏可以解决。
2.2. 坏点矫正
坏点矫正的原理见本专栏:坏点矫正,效果图如fig.11所示:
2.3. Demosaic
Demosaic的原理见本专栏:Demosaic,效果图如fig.12所示,边缘看起来似乎没有问题?这是因为这张色卡图的边缘很规整,测试不了复杂的边缘,所以调试一个ISP用一张图像就远远不够的,需要很多张图像。
2.4. 白平衡
白平衡的原理见本专栏:白平衡,效果图如fig.13所示,右下角的白色由fig.12中的偏粉色变成了白色,说明白平衡效果正常。
2.5. CCM
CCM的原理见本专栏:CCM和Gamma,效果图如fig.14所示,这个效果明显不正常,这说明即使我用的是标准的RGB和XYZ互转的矩阵,在加入了其他模块之后,也变不回原来的颜色了,需要用其他的方法做进一步的调整,或者可以考虑关闭input_to_raw.m里面的RGB转到XYZ域的功能。
2.6. Gamma
Gamma的原理见本专栏:CCM和Gamma,效果图如fig.15所示,CCM不正确,Gamma很难正确。
2.7. Denoise
Denoise的原理见本专栏:Denoise,效果图如fig.16所示,denoise函数内化了双边、导向双边和NLM共3个降噪算法,通过mode控制,目前使用的是双边降噪。
2.8. Sharpen
Sharp的原理见本专栏:sharpen,效果图如fig.17所示:
2.9. 总结
一个完整的ISP pipeline流程已经走完了,运行代码中的isp_basic.m就可以看见文章中的效果,能直接看出来的两个问题是CCM和降噪做的不好,CCM需要标定,也可以借助专业的软件Imatest或者是其他的软件对色卡做色差计算。降噪的问题是力度不够,但是在YUV域做很大的降噪会损失细节,可以考虑在RAW域增加一个降噪和后面的YUV域降噪相互配合。
不管怎么说,已经拥有了一个ISP的雏形,且刚需模块都在里面了,能够做的工作也变多了,接下来就是一步一步完善它,给每个模块用上更复杂更有效的算法,或者是增加更高级的模块获得更好的效果。
如果需要matlab代码可以从这里提取:代码链接。