Background
Low-light image synthesis
Low-light images differ from normal images duento two dominant features: low brightness/contrast and the presence of noise.
Lv et.al introduced a simulation method to perform transformation to covert the normal image to underexposed low-light image.
\[I^i_{out} = \beta \times (\alpha \times I^i_{in})^\gamma\]where $\alpha \sim U(0.9,1); \beta U(0.5,1); \gamma \sim U(1.5,5)$
As shown in Figure 4, the synthetic low-light images are approximately the same to real low-light images.
Example from LOL Dataset
LOL Dataset is introduced by Wei et.al. We take an example from LOL Dataset to perform the low-light image synthesis.
1
2
3
4
5
6
7
8
9
import requests
from io import BytesIO
from PIL import Image
url = "https://s2.loli.net/2023/01/17/4zOYDIMfxjZ1nsp.png"
response = requests.get(url)
init_img = Image.open(BytesIO(response.content)).convert("RGB")
init_img = init_img.resize((768, 512))
The low light image systhesis program
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import random
import numpy as np
low_img = np.asarray(init_img) / 255.0
beta = 0.5 * random.random() + 0.5
alpha = 0.1 * random.random() + 0.9
gamma = 3.5 * random.random() + 1.5
low_img = beta * np.power(alpha * low_img, gamma)
low_img = low_img * 255.0
low_img = (low_img.clip(0, 255)).astype("uint8")
# low_img = Image.fromarray(cv2.cvtColor(low_img, cv2.COLOR_BGR2RGB))
# img_in, img_tar = get_patch(low_img, high_image, self.patch_size, self.upscale_factor)
Image.fromarray(low_img)
The low light image reference as
1
2
3
ref_img_url = "https://s2.loli.net/2023/01/17/pWlfs6hSyGmYHng.png"
ref_img = Image.open(BytesIO(requests.get(ref_img_url).content)).convert("RGB")
ref_img = ref_img.resize((768, 512))
Progressive low light systhesis
We want to make the darken process is performed progressively as diffusion forward process. like
Refering to original equation $I^i_{out} = \beta \times (\alpha \times I^i_{in})^\gamma $, we simply the equation to $ x_T = \beta x_0^\gamma$, and we can have
\[\begin{aligned} \eta^T &= \gamma \\ \eta &= \gamma^{\frac{1}{T}} \\ \alpha &= \beta^{\frac{\eta (1-\eta^T)}{1 -\eta}} \end{aligned}\]By letting $\beta = 0.9, \gamma = 3.5, T = 10$, we can make darkening process progressively s.t.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
beta_enligten, gamma_enlighten, T_max = 0.9, 3.5, 10
eta = gamma_enlighten**(1/T_max)
power = (1-eta)/(eta*(1-eta**T_max))
alpha = beta_enligten**power
def p_darken(x_prev):
x_t = (alpha*x_prev)**eta
return x_t
img = np.asarray(init_img) / 255.0
imgs = []
for i in range(T_max):
img = p_darken(img)
img_temp = img*255
img_temp = img_temp.clip(0,255).astype('uint8')
imgs.append(Image.fromarray(img_temp))
-
Previous
Code Review: Denoising Diffusion Probabilistic Models (DDPM) -
Next
Review: Generative Modeling by Estimating Gradients of the Data Distribution