在我的知识星球中,我正在教大家如何编程实现摄影图像的后期处理与优化。目前我的进度在图像的畸变校正这一部分,如下图所示:
这里我所说的畸变校正包括了两个部分。一个部分是画面的几何畸变校正,这部分的原理我在文章手机中的计算摄影4-超广角畸变校正和66. 三维重建1——相机几何模型和投影矩阵中都有提到过。
另外一部分,则是被我强行纳入畸变范畴的 它有一个拉风的名字——晕影,英文教材里面称作Vignetting,我在文章2. 从入射光到JPEG相片-数码相机内部的秘密中提到过它。
我在上一篇文章IQE12: 晕影(Vignetting)产生原理及去除中为你展示了晕影(Vignetting)的光学原理,及消除晕影的Adobe模型。然而,由于篇幅限制,我没有仔细分析晕影消除前后的图像的差异,而这个差异中恰好隐藏着一个重要的陷阱!今天我就来阐述这一点,这样你对晕影消除会有更进一步的理解。
在上一篇文章中,我做晕影校正是在Gamma校正后的sRGB空间的图像上进行的,其流程如下:
在Gamma校正后做晕影校正
我们得到的动图展示如下:
从整体图来看,晕影校正后边角确实提亮了,不过四角似乎变得过于亮了。上一篇文章中,就有网友指出,晕影校正后的图像似乎不如校正前好看了,我的理解是“校正过度,显得过于夸张了”。
进一步,如果你仔细观察图像中高亮部分,会看到什么?
我想你立刻就会注意到,晕影校正后的图像丢失了细节,有大量的像素过曝了!
从直方图中我们也能看到,晕影校正后图像的暗区减少了,但很多像素由于校正导致过曝,在最大值处产生了截断,我们无法再看到此处的细节了!
我在我的星球文章Python图像后处理与优化13-Gamma对晕影去除的影响中展示了一个实验:分别在Gamma校正前后进行晕影校正,并对比效果。下面是结果图的对比。肉眼看起来已经可以看到左侧的图像的边角要显得稍微暗一点点,并且在之前提到的区域似乎保留了更多的细节
左图:在Gamma编码前做晕影消除,右图:在Gamma编码后做晕影消除
再看看细节对比。在Gamma校正前做晕影消除,既能够提亮图像边角,又不像在Gamma校正后才做晕影消除将边角提亮得那么夸张:
在Gamma校正前后做晕影消除的对比
而且很明显,在Gamma校正后做晕影消除,丢失了很多细节,很多像素过曝了。而在Gamma校正前做晕影消除,则还保留了一定的细节
在Gamma校正前后做晕影消除的对比
为什么会出现2.2节中的现象呢?回过头看上一篇文章IQE12: 晕影(Vignetting)产生原理及去除,我提到了Adobe的晕影参数模型:
实际上,这里的图像I都是在线性空间中的,而不是经过了非线性的Gamma编码的。Gamma编码后图像的整体值会变大,如果进一步对边角做不同程度的增益,显然就会导致过曝。
Gamma校正的过程会提亮图像
所以按照这个模型,我们真正的流程至少是:
晕影消除应该在Gamma编码前才符合原理
这就是关键点!
实际上,由于晕影是光学原因,每个像素都会受到影响,我们甚至可以把晕影校正提前到刚刚处理完黑电平和饱和后完成。由于时间原因,我没有完成这个实验,感兴趣的读者可以试一试。
晕影消除在彻底的初始线性图像上执行更符合原理
通过今天的文章,我想你已经明白了:晕影校正应该在线性空间中进行,至少应该在Gamma编码之前进行,我们后续还会讲到去除色差,这个动作也应该在线性空间中进行。