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