暗角映像是一種在現實中較為常見的映像,其主要特徵就是在映像四個角有較為顯著的亮度下降,比如下面兩幅圖:
在2014年Y.Zheng等人的《Single image vignetting correction》以及同樣有他們撰寫的論文《Single image vignetting correction using radial gradient symmetry》有講這方面的演算法,不過其實現的複雜度較高,即使能編程實現,速度估計也很慢,其實用性就不高了。
另一篇名為《Single-Image Vignetting Correction by Constrained Minimization of log-Intensity Entropy》的論文提供了相對簡單的演算法。該論文的核心思想為:
第一:
去暗角可以說是陰影校正的一種特例,而將整副映像的熵最小化也被證明為進行陰影校正的一種有效方法,但是普通的熵在最佳化過程中會最佳化到局部最優的。因此論文中提出了一種對數熵的概念(Log-Intensity Entropy),論文中用資料做了說明,假設一副普通正常的映像其長條圖是單峰分布,那麼如果這幅映像有暗角,其長條圖必然會存在另外一個低明度的分布,如下圖所示:
我們校正暗角的過程就是使低明度的分布向原來的正常明度靠近,由上圖第一行的資料可以看到,普通的熵計算直到兩個長條圖有部分重疊的時候熵才會下降,之前熵一直都是增加的,而對數熵則在沒有重疊前至少是保持不增的,因此能夠更好的擷取全域最優解。
論文提出的對數熵的實現:
1.1 將亮度進行對數映射,公式為:
就是將[0,255]內的像素值對應到[0, N-1]內,但不是線性映射,而是基於對數關係的映射,通常N就是取256,這樣映射後的像素範圍還是[0,255],但是注意這裡的i(L)已經是浮點數了。我們繪製出N等於256時上式的曲線:
由上圖可見,這種操作實際上把映像整體調亮了。由於映射後的色階已經是浮點數了,因此,長條圖資訊的統計就必須換種方式了,論文給出的公式為:
公式很複雜, 其實就是有點類似線性插值那種意思,不認識了那兩個數學符號了,就是向上取整和向下取整。這樣的對數熵長條圖資訊會由於巨大的色階調整,導致很多色階是沒有長條圖資訊的,一般可以對這個長條圖資訊進行下高斯平滑的,得到新的長條圖。
最後映像的對數熵,計算方法如下:
第二:
一個暗角映像亮度下降的關係式:
其中,x和y是映像每一點的座標,而則表示暗角的中心位置,他們和a、b、c均為未知量。我們可以看到,當r=0時,校正係數為1,即無需校正。當r=1時,校正係數為1+a+b+c。
那麼經過暗角校正後的映像就為:
論文總結了滿足下述關係的a,b,c:
第三:
上面描述了校正暗角映像的公式(帶參數)以及評價一副映像是否有暗角的指標,那麼最後一步就是用這個指標來確定公式的參數。我們未知的參數有5個,即a、b、c以及暗角的中心點。解這種受限的最優問題是有專門的演算法的,也是非常計算耗時的。因此,作者提出了一種快速的演算法:Hill climbing with rejection of invalid solutions.
我稍微看了下這個演算法,確實是個不錯的想法,不過我並沒有去實踐,我採用了另外一種粗略的最佳化方式。
首先,很明顯,為了計算這些最優參數,我們沒有必要直接在原圖大小上直接計算,這點在原論文也有說明,我們即使把他們的寬高分別縮小到原圖的1/5甚至1/10計算出來的結果也不會有太大的差異,而這些參數的差異對最終的的結果影響也不大,但是計算量就能減少到原來的1/25和1/100。
接著,我們觀察到a、b以及c的最優結果範圍一般都在-2和2之間,並且從g的計算公式中知道,由於r是屬於0和1之間的正數,r^2, r^4, r^6在數值遞減的非常快,比如r=0.8,則三者對應的結果就分別為0.64、0.4096、0.2621,因此,a和b及c在公式中的對最後結果的影響也依次越來越小。
那麼,我們可以參考以前的對比保留之彩色映像去色演算法---基礎演算法也可以上檔次一文中的最佳化方式,把a, b ,c 三個參數分別在[-2,2]之間離散化,考慮到參數稍微差異不會對結果有太大的影響,以及a、b、c的重要性,我們可以設定a、b、c三者的離散間隔分別為0.2、0.3、0.4,然後綜合上述判斷a、b、c是否為合理組合的函數,離散取樣的計算量組合大概有300種可能,對小圖計算著300種可能性的耗時是完全可以接受的,甚至考慮極端一點,把c的計算放到迴圈外側,即C取固定值0,然後計算出優選的a和b值後,在計算C值。
上述計算過程並未考慮暗角中心點的範圍,我們是固定把暗角的中心點放置在映像的正中心位置的,即 (Width/2, Height /2),實際上,對於大部分拍攝的圖來說,暗角就是位於中心位置的,因此這種假設也無可厚非,因為暗角中心計算的增加必然會嚴重增加計算量, 為了求出暗角中心的合理位置,我們在計算出上述a、b、c後,在小圖中以一定步長按照公式計算出粗略的中心位置,再放大到原圖中去。
計算出上述a、b、c以及中心點後,就可以再次按照校正公式來進行校正了,注意暗角的影響對每個通道都是等同的,因此,每個通道都應該乘以相同的值。
下面貼出一些用論文中的演算法處理的結果圖: