Buckets:
| # Copyright (c) Microsoft Corporation. | |
| # Licensed under the MIT License. | |
| import numpy as np | |
| from scipy import signal | |
| from scipy import ndimage | |
| def fspecial_gauss(size, sigma): | |
| x, y = np.mgrid[-size // 2 + 1:size // 2 + 1, -size // 2 + 1:size // 2 + 1] | |
| g = np.exp(-((x**2 + y**2) / (2.0 * sigma**2))) | |
| return g / g.sum() | |
| def calc_ssim(img1, img2, data_range=255): | |
| img1 = img1.astype(np.float64) | |
| img2 = img2.astype(np.float64) | |
| size = 11 | |
| sigma = 1.5 | |
| window = fspecial_gauss(size, sigma) | |
| K1 = 0.01 | |
| K2 = 0.03 | |
| C1 = (K1 * data_range)**2 | |
| C2 = (K2 * data_range)**2 | |
| mu1 = signal.fftconvolve(window, img1, mode='valid') | |
| mu2 = signal.fftconvolve(window, img2, mode='valid') | |
| mu1_sq = mu1 * mu1 | |
| mu2_sq = mu2 * mu2 | |
| mu1_mu2 = mu1 * mu2 | |
| sigma1_sq = signal.fftconvolve(window, img1 * img1, mode='valid') - mu1_sq | |
| sigma2_sq = signal.fftconvolve(window, img2 * img2, mode='valid') - mu2_sq | |
| sigma12 = signal.fftconvolve(window, img1 * img2, mode='valid') - mu1_mu2 | |
| return (((2 * mu1_mu2 + C1) * (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) * | |
| (sigma1_sq + sigma2_sq + C2)), | |
| (2.0 * sigma12 + C2) / (sigma1_sq + sigma2_sq + C2)) | |
| def calc_msssim(img1, img2, data_range=255): | |
| ''' | |
| img1 and img2 are 2D arrays | |
| ''' | |
| level = 5 | |
| weight = np.array([0.0448, 0.2856, 0.3001, 0.2363, 0.1333]) | |
| height, width = img1.shape | |
| if height < 176 or width < 176: | |
| # according to HM implementation | |
| level = 4 | |
| weight = np.array([0.0517, 0.3295, 0.3462, 0.2726]) | |
| if height < 88 or width < 88: | |
| assert False | |
| downsample_filter = np.ones((2, 2)) / 4.0 | |
| im1 = img1.astype(np.float64) | |
| im2 = img2.astype(np.float64) | |
| mssim = np.array([]) | |
| mcs = np.array([]) | |
| for _ in range(level): | |
| ssim_map, cs_map = calc_ssim(im1, im2, data_range=data_range) | |
| mssim = np.append(mssim, ssim_map.mean()) | |
| mcs = np.append(mcs, cs_map.mean()) | |
| filtered_im1 = ndimage.filters.convolve(im1, downsample_filter, | |
| mode='reflect') | |
| filtered_im2 = ndimage.filters.convolve(im2, downsample_filter, | |
| mode='reflect') | |
| im1 = filtered_im1[::2, ::2] | |
| im2 = filtered_im2[::2, ::2] | |
| return (np.prod(mcs[0:level - 1]**weight[0:level - 1]) * | |
| (mssim[level - 1]**weight[level - 1])) | |
| def calc_msssim_rgb(img1, img2, data_range=255): | |
| ''' | |
| img1 and img2 are arrays with 3xHxW | |
| ''' | |
| msssim = 0 | |
| for i in range(3): | |
| msssim += calc_msssim(img1[i, :, :], img2[i, :, :], data_range) | |
| return msssim / 3 | |
| def calc_psnr(img1, img2, data_range=255): | |
| ''' | |
| img1 and img2 are arrays with same shape | |
| ''' | |
| img1 = img1.astype(np.float64) | |
| img2 = img2.astype(np.float64) | |
| mse = np.mean(np.square(img1 - img2)) | |
| if np.isnan(mse) or np.isinf(mse): | |
| return -999.9 | |
| if mse > 1e-10: | |
| psnr = 10 * np.log10(data_range * data_range / mse) | |
| else: | |
| psnr = 999.9 | |
| if psnr > 99.9: | |
| psnr = 99.9 | |
| return psnr | |
Xet Storage Details
- Size:
- 3.17 kB
- Xet hash:
- 5352b41cb19cf0c71dc877101988667bb4913e628c4810b429e479bd9fa7bead
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.