# 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)