Spaces:
Running
on
Zero
Running
on
Zero
from skimage import color | |
import numpy as np | |
import torch | |
class deltaEab(): | |
def __init__(self, color_chart_area=0): | |
super().__init__() | |
self.color_chart_area = color_chart_area | |
def __call__(self, img1, img2): | |
""" Compute the deltaE76 between two numpy RGB images | |
From M. Afifi: https://github.com/mahmoudnafifi/WB_sRGB/blob/master/WB_sRGB_Python/evaluation/calc_deltaE.py | |
:param img1: numpy RGB image or pytorch tensor | |
:param img2: numpy RGB image or pytocrh tensor | |
:return: deltaE76 | |
""" | |
if type(img1) == torch.Tensor: | |
assert img1.shape[0] == 1 | |
img1 = img1.squeeze().permute(1, 2, 0).cpu().numpy() | |
if type(img2) == torch.Tensor: | |
assert img2.shape[0] == 1 | |
img2 = img2.squeeze().permute(1, 2, 0).cpu().numpy() | |
# Convert to Lab | |
img1 = color.rgb2lab(img1) | |
img2 = color.rgb2lab(img2) | |
# reshape to 1D array | |
img1 = img1.reshape(-1, 3).astype(np.float32) | |
img2 = img2.reshape(-1, 3).astype(np.float32) | |
# compute deltaE76 | |
de76 = np.sqrt(np.sum(np.power(img1 - img2, 2), 1)) | |
return sum(de76) / (np.shape(de76)[0] - self.color_chart_area) | |
class deltaE00(): | |
def __init__(self, color_chart_area=0): | |
super().__init__() | |
self.color_chart_area = color_chart_area | |
self.kl = 1 | |
self.kc = 1 | |
self.kh = 1 | |
def __call__(self, img1, img2): | |
""" Compute the deltaE00 between two numpy RGB images | |
From M. Afifi: https://github.com/mahmoudnafifi/WB_sRGB/blob/master/WB_sRGB_Python/evaluation/calc_deltaE2000.py | |
:param img1: numpy RGB image or pytocrh tensor | |
:param img2: numpy RGB image or pytocrh tensor | |
:return: deltaE00 | |
""" | |
if type(img1) == torch.Tensor: | |
assert img1.shape[0] == 1 | |
img1 = img1.squeeze().permute(1, 2, 0).cpu().numpy() | |
if type(img2) == torch.Tensor: | |
assert img2.shape[0] == 1 | |
img2 = img2.squeeze().permute(1, 2, 0).cpu().numpy() | |
# Convert to Lab | |
img1 = color.rgb2lab(img1) | |
img2 = color.rgb2lab(img2) | |
# reshape to 1D array | |
img1 = img1.reshape(-1, 3).astype(np.float32) | |
img2 = img2.reshape(-1, 3).astype(np.float32) | |
# compute deltaE00 | |
Lstd = np.transpose(img1[:, 0]) | |
astd = np.transpose(img1[:, 1]) | |
bstd = np.transpose(img1[:, 2]) | |
Cabstd = np.sqrt(np.power(astd, 2) + np.power(bstd, 2)) | |
Lsample = np.transpose(img2[:, 0]) | |
asample = np.transpose(img2[:, 1]) | |
bsample = np.transpose(img2[:, 2]) | |
Cabsample = np.sqrt(np.power(asample, 2) + np.power(bsample, 2)) | |
Cabarithmean = (Cabstd + Cabsample) / 2 | |
G = 0.5 * (1 - np.sqrt((np.power(Cabarithmean, 7)) / (np.power( | |
Cabarithmean, 7) + np.power(25, 7)))) | |
apstd = (1 + G) * astd | |
apsample = (1 + G) * asample | |
Cpsample = np.sqrt(np.power(apsample, 2) + np.power(bsample, 2)) | |
Cpstd = np.sqrt(np.power(apstd, 2) + np.power(bstd, 2)) | |
Cpprod = (Cpsample * Cpstd) | |
zcidx = np.argwhere(Cpprod == 0) | |
hpstd = np.arctan2(bstd, apstd) | |
hpstd[np.argwhere((np.abs(apstd) + np.abs(bstd)) == 0)] = 0 | |
hpsample = np.arctan2(bsample, apsample) | |
hpsample = hpsample + 2 * np.pi * (hpsample < 0) | |
hpsample[np.argwhere((np.abs(apsample) + np.abs(bsample)) == 0)] = 0 | |
dL = (Lsample - Lstd) | |
dC = (Cpsample - Cpstd) | |
dhp = (hpsample - hpstd) | |
dhp = dhp - 2 * np.pi * (dhp > np.pi) | |
dhp = dhp + 2 * np.pi * (dhp < (-np.pi)) | |
dhp[zcidx] = 0 | |
dH = 2 * np.sqrt(Cpprod) * np.sin(dhp / 2) | |
Lp = (Lsample + Lstd) / 2 | |
Cp = (Cpstd + Cpsample) / 2 | |
hp = (hpstd + hpsample) / 2 | |
hp = hp - (np.abs(hpstd - hpsample) > np.pi) * np.pi | |
hp = hp + (hp < 0) * 2 * np.pi | |
hp[zcidx] = hpsample[zcidx] + hpstd[zcidx] | |
Lpm502 = np.power((Lp - 50), 2) | |
Sl = 1 + 0.015 * Lpm502 / np.sqrt(20 + Lpm502) | |
Sc = 1 + 0.045 * Cp | |
T = 1 - 0.17 * np.cos(hp - np.pi / 6) + 0.24 * np.cos(2 * hp) + \ | |
0.32 * np.cos(3 * hp + np.pi / 30) \ | |
- 0.20 * np.cos(4 * hp - 63 * np.pi / 180) | |
Sh = 1 + 0.015 * Cp * T | |
delthetarad = (30 * np.pi / 180) * np.exp( | |
- np.power((180 / np.pi * hp - 275) / 25, 2)) | |
Rc = 2 * np.sqrt((np.power(Cp, 7)) / (np.power(Cp, 7) + np.power(25, 7))) | |
RT = - np.sin(2 * delthetarad) * Rc | |
klSl = self.kl * Sl | |
kcSc = self.kc * Sc | |
khSh = self.kh * Sh | |
de00 = np.sqrt(np.power((dL / klSl), 2) + np.power((dC / kcSc), 2) + | |
np.power((dH / khSh), 2) + RT * (dC / kcSc) * (dH / khSh)) | |
return np.sum(de00) / (np.shape(de00)[0] - self.color_chart_area) | |