def ergas(GT, P, r=4, ws=8): """calculates erreur relative globale adimensionnelle de synthese (ergas). :param GT: first (original) input image. :param P: second (deformed) input image. :param r: ratio of high resolution to low resolution (default=4). :param ws: sliding window size (default = 8). :returns: float -- ergas value. """ GT, P = _initial_check(GT, P) rmse_map = None nb = 1 _, rmse_map = rmse_sw(GT, P, ws) means_map = uniform_filter(GT, ws) / ws**2 # Avoid division by zero idx = means_map == 0 means_map[idx] = 1 rmse_map[idx] = 0 ergasroot = np.sqrt(np.sum(((rmse_map**2) / (means_map**2)), axis=2) / nb) ergas_map = 100 * r * ergasroot s = int(np.round(ws / 2)) return np.mean(ergas_map[s:-s, s:-s])
def mse(GT, P): """Calculates mean squared error (mse). :param GT: first (original) input image :paran P: second (deformed) input image :returns: float -- mse value """ GT, P = _initial_check(GT, P) return np.mean((GT.astype(np.float64) - P.astype(np.float64))**2)
def rmse(GT, P): """Calculates root mean squared error (rmse). :param GT: first (original) input image :paran P: second (deformed) input image :returns: float -- rmse value """ GT, P = _initial_check(GT, P) return np.sqrt(mse(Gt, P))
def uqi(GT, P, ws=8): """calculates universal image quality index (uqi). :param GT: first (original) input image. :param P: second (deformed) input image. :param ws: sliding window size (default = 8). :returns: float -- uqi value. """ GT, P = _initial_check(GT, P) return np.mean( [_uqi_single(GT[:, :, i], P[:, :, i], ws) for i in range(GT.shape[2])])
def msssim(GT, P, weights=[0.0448, 0.2856, 0.3001, 0.2363, 0.1333], ws=11, K1=0.01, K2=0.03, MAX=None): """calculates multi-scale structural similarity index (ms-ssim). :param GT: first (original) input image. :param P: second (deformed) input image. :param weights: weights for each scale (default = [0.0448, 0.2856, 0.3001, 0.2363, 0.1333]). :param ws: sliding window size (default = 11). :param K1: First constant for SSIM (default = 0.01). :param K2: Second constant for SSIM (default = 0.03). :param MAX: Maximum value of datarange (if None, MAX is calculated using image dtype). :returns: float -- ms-ssim value. """ if MAX is None: MAX = np.iinfo(GT.dtype).max GT, P = _initial_check(GT, P) scales = len(weights) fltr_specs = dict(fltr=Filter.GAUSSIAN, sigma=1.5, ws=11) if isinstance(weights, list): weights = np.array(weights) mssim = [] mcs = [] for _ in range(scales): _ssim, _cs = ssim(GT, P, ws=ws, K1=K1, K2=K2, MAX=MAX, fltr_specs=fltr_specs) mssim.append(_ssim) mcs.append(_cs) filtered = [uniform_filter(im, 2) for im in [GT, P]] GT, P = [x[::2, ::2, :] for x in filtered] mssim = np.array(mssim, dtype=np.float64) mcs = np.array(mcs, dtype=np.float64) return np.prod(_power_complex(mcs[:scales - 1], weights[:scales - 1])) * _power_complex( mssim[scales - 1], weights[scales - 1])
def vifp(GT, P, sigma_nsq=2): """calculates Pixel Based Visual Information Fidelity (vif-p). :param GT: first (original) input image. :param P: second (deformed) input image. :param sigma_nsq: variance of the visual noise (default = 2) :returns: float -- vif-p value. """ GT, P = _initial_check(GT, P) # GT,P = GT[:,:,np.newaxis],P[:,:,np.newaxis] return np.mean([ _vifp_single(GT[:, :, i], P[:, :, i], sigma_nsq) for i in range(GT.shape[2]) ])
def scc(GT, P, win=[[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], ws=8): """calculates spatial correlation coefficient (scc). :param GT: first (original) input image. :param P: second (deformed) input image. :param fltr: high pass filter for spatial processing (default=[[-1,-1,-1],[-1,8,-1],[-1,-1,-1]]). :param ws: sliding window size (default = 8). :returns: float -- scc value. """ GT, P = _initial_check(GT, P) coefs = np.zeros(GT.shape) for i in range(GT.shape[2]): coefs[:, :, i] = _scc_single(GT[:, :, i], P[:, :, i], win, ws) return np.mean(coefs)
def psnr(GT, P, MAX=None): """Calculates peak signal-to-noise ratio (psnr) :param GT: frist (orginal) input image. :param P: second (deformed) input image. :param MAX: maximum value of datarange (if None, MAX is calculated using image dtype) return: float -- psnr value in dB. """ if MAX is None: MAX = np.iinfo(GT.dtype).max GT, P = _initial_check(GT, P) mse_value = mse(GT, P) if mse_value == 0: return np.inf return 10 * np.log10(MAX**2 / mse_value)
def rmse_sw(GT, P, ws=8): """calculates root mean squared error (rmse) using sliding window. :param GT: first (original) input image. :param P: second (deformed) input image. :param ws: sliding window size (default = 8). :returns: tuple -- rmse value,rmse map. """ GT, P = _initial_check(GT, P) rmse_map = np.zeros(GT.shape) vals = np.zeros(GT.shape[2]) for i in range(GT.shape[2]): vals[i], rmse_map[:, :, i] = _rmse_sw_single(GT[:, :, i], P[:, :, i], ws) return np.mean(vals), rmse_map
def rase(GT, P, ws=8): """calculates relative average spectral error (rase). :param GT: first (original) input image. :param P: second (deformed) input image. :param ws: sliding window size (default = 8). :returns: float -- rase value. """ GT, P = _initial_check(GT, P) _, rmse_map = rmse_sw(GT, P, ws) GT_means = uniform_filter(GT, ws) / ws**2 N = GT.shape[2] M = np.sum(GT_means, axis=2) / N rase_map = (100. / M) * np.sqrt(np.sum(rmse_map**2, axis=2) / N) s = int(np.round(ws / 2)) return np.mean(rase_map[s:-s, s:-s])
def sam(GT, P): """calculates spectral angle mapper (sam). :param GT: first (original) input image. :param P: second (deformed) input image. :returns: float -- sam value. """ GT, P = _initial_check(GT, P) GT = GT.reshape((GT.shape[0] * GT.shape[1], GT.shape[2])) P = P.reshape((P.shape[0] * P.shape[1], P.shape[2])) N = GT.shape[1] sam_angles = np.zeros(N) for i in range(GT.shape[1]): val = np.clip( np.dot(GT[:, i], P[:, i]) / (np.linalg.norm(GT[:, i]) * np.linalg.norm(P[:, i])), -1, 1) sam_angles[i] = np.arccos(val) return np.mean(sam_angles)
def ssim(GT, P, ws=11, K1=0.03, K2=0.03, MAX=None, fltr_specs=None, mode='valid'): """Calculates structural similarity index (ssim). :param GT: first (original) input image :param P: second (deformed) input image :param ws: sliding window size (default = 11) :param K1: first constant for SSIM (default = 0.01) :param K2: second constant for SSIM (default = 0.03) :param MAX: Maximum value of datarange (if None, MAX is calculated using image dtype). :returns: tuple -- ssim value, cs value. """ if MAX is None: MAX = np.iinfo(GT.dtype).max GT, P = _initial_check(GT, P) if fltr_specs is None: fltr_specs = dict(fltr=Filter.UNIFORM, ws=ws) C1 = (K1 * MAX)**2 C2 = (K2 * MAX)**2 ssims = [] css = [] for i in range(GT.shape[2]): ssim, cs = _ssim_single(GT[:, :, i], P[:, :, i], ws, C1, C2, fltr_specs, mode) ssims.append(ssim) css.append(cs) return np.mean(ssims), np.mean(css)