---
# System prepended metadata

title: Adaptive Gamma Correction 1
tags: [low-light, zh-TW]

---

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