# Adaptive Gamma Correction 1 - [English](https://hackmd.io/@johnny95731/HkWft3lkze) - [程式碼(GitHub)](https://github.com/johnny95731/dip-blog-codes/tree/master/src/adaptive_gamma_correction1) 附註:會先在HackMD發表簡短內容,並在幾周之後發表增加細節的內容到Blogger. 咖瑪校正(Gamma correction, GC)──$I_{\text{out}}=I_{\text{in}}^\gamma,\ I_{\text{in}}(x,y)\in[0,1],\ \gamma\in(0,\infty)$,是影像強化的基礎工具。當γ>1時,顏色會變更深;反之,當γ<1時,顏色會變亮。本文會談論一些簡單的方法來自動選取合適的γ。 ## 符號與預備工具 ### 符號 - $\text{gray}(I)$: 將影像$I$轉換為灰階、亮度。 - $m$: 灰階影像$\text{gray}(I)$的平均值。 - $m_{k\times k}(x,y)$: 灰階影像$\text{gray}(I)$的局部平均值。 從灰階來計算gamma可以**降低**計算量與色彩失真。並且我們會用頻率域的高斯濾波來近似局部平均,以避免大卷積核帶來大量的邊界填充運算(PyTorch捲積僅內建零填充,其他填充方式要額外呼叫函數)。 ### 影像亮度 不同的色彩空間會用不同的方法來估計亮度,舉例來說 - HSV: max(R, G, B) - HSL: (max(R, G, B)+min(R, G, B))/2 - HSI: (R+G+B)/3 - YUV(BT.470): 0.299*R+0.587*G+0.114*B 考慮到視覺感知,我們在本文使用YUV的公式。 ## 透過平均值計算自適應gamma > Journal, A. CS IJ, and Parham Zarei. Automatic Gamma Correction Based on Average of Brightness. P. Zarei等人提出一個簡單的方法來估計gamma。其選擇的gamma需滿足 $$ m^\gamma = 0.5. $$ 上式可以簡單地求出 $$ \tag{1} \gamma = \frac{\log{0.5}}{\log{m}} = \log_{m}{0.5} $$ 這個演算法以下會稱作"GAGC" ## Local Adaptive Gamma Correction 有時我們想要提升暗部亮度並調暗亮部。此時GAGC就沒辦法完成,因為整張圖片都使用了**同樣**的gamma。 ### Simple local adaptive gamma 以下的演算法簡稱為"SLAGC"。因為GAGC的方法有效,最直接的方法是將公式(1)中的平均值m替換為局部平均值$m_{k\times k}$ $$ \tag{2} \gamma(x,y) = \frac{\log{0.5}}{m_{k\times k}(x,y)}. $$ <figure> <img src="https://hackmd.io/_uploads/SJSsKtTRZg.jpg" alt="GAGC and SLAGC (1)"> <figcaption style="text-align: center;">GAGC and SLAGC (1)</figcaption> </figure> <figure> <img src="https://hackmd.io/_uploads/rkEWrnaAWg.jpg" alt="GAGC and SLAGC (2)"> <figcaption style="text-align: center;">GAGC and SLAGC (2)</figcaption> </figure> <figure> <img src="https://hackmd.io/_uploads/HyNWB3aC-x.jpg" alt="GAGC and SLAGC (3)"> <figcaption style="text-align: center;">GAGC and SLAGC (3)</figcaption> </figure> <figure> <img src="https://hackmd.io/_uploads/r1EZr2T0Zg.jpg" alt="GAGC and SLAGC (4)"> <figcaption style="text-align: center;">GAGC and SLAGC (4)</figcaption> </figure> <figure> <img src="https://hackmd.io/_uploads/r1VbShaRbl.jpg" alt="GAGC and SLAGC (5)"> <figcaption style="text-align: center;">GAGC and SLAGC (5)</figcaption> </figure> SLAGC可以針對陰影與亮部分別強化,但是有時會出現光暈(halo)。這會發生大區塊亮部或暗部的邊界;而大片亮或暗區塊的gamma會被迅速推向兩端,而邊緣則會接近0.5,見下圖。 <figure> <img src="https://hackmd.io/_uploads/BJwtLgzJze.png" alt="The graph of eq(2)"> <figcaption style="text-align: center;">The graph of eq(2)</figcaption> </figure> #### 其他構想1 將局部平均/均值濾波改為edge preserving filters,例如**雙邊濾波**(bilateral filter)或**導引濾波**(guided filter),或許可以改善halo。 ### Another local adaptive gamma 我們提出另一種LAGC(local adaptive gamma correction)演算法: $$ \tag{3} \gamma(x,y) = \max(0,\,gain*(\text{m}_{k\times k}(x,y)-0.5)+basic), $$ 其中$gain,basic\in(0,\infty)$。 概念是以參數basic為中心,將亮度遠離0.5的值向外推。參數預設為$gain=1.3$與$basic=1$。 公式(3)為分段線性函數,而SLAGC包含了對數與倒數f(x)=1/x。因此色彩變化較為平滑 <figure> <img src="https://hackmd.io/_uploads/H1msR6pR-x.jpg" alt="LAGC (1)"> <figcaption style="text-align: center;">LAGC (1)</figcaption> </figure> <figure> <img src="https://hackmd.io/_uploads/rymjA6a0Wl.jpg" alt="LAGC (2)"> <figcaption style="text-align: center;">LAGC (2)</figcaption> </figure> <figure> <img src="https://hackmd.io/_uploads/SJQjCp6CZx.jpg" alt="LAGC (3)"> <figcaption style="text-align: center;">LAGC (3)</figcaption> </figure> <figure> <img src="https://hackmd.io/_uploads/SJQjRapAbg.jpg" alt="LAGC (4)"> <figcaption style="text-align: center;">LAGC (4)</figcaption> </figure> #### Additional Ideas 2 $gain*\frac{m_{k\times k}(x,y)-0.5}{std}+basic$對參數更敏感,需要較小的gain。其餘的例子還沒測試。 - 加入全域或局部標準差(std)項,例如 1. $\max(0,\,gain*\frac{m_{k\times k}(x,y)-0.5}{std}+basic)$ 2. $\max(0,\,gain*\frac{I(x,y)-m_{k\times k}(x,y)}{std}+basic)$ 3. $\max(0,\,gain*\frac{m_{k\times k}(x,y)-m}{std}+basic)$ - 可以更進一步地結合累積分布函數,或許能提升暗部並保留亮部(因$0\le cdf\le1$) - $gain*\text{cdf}(\frac{I(x,y)-m_{k\times k}(x,y)}{std}),$ 其中cdf是累積分布函數 - 多項式Polynomials 1. $\max(0,\,gain*(m_{k\times k}(x,y)-c)^k+basic),\,\text{where }k\in\mathbb{N}\text{ is odd and }c\in[0,1].$ 2. $\max(0,\,gain*(m_{k\times k}(x,y)^k-c)+basic),\,\text{where }k\in(0,\infty)\text{ and }c\in[0,1].$ 3. $gain*m_{k\times k}(x,y)^k,\,\text{where }k\in(0,\infty).$ ### 程式碼 GAGC, SLAGC與LAGC的實作在[這裡](https://github.com/johnny95731/dip-blog-codes/tree/master/src/adaptive_gamma_correction1)