Coverage for crip\metric.py: 97%
39 statements
« prev ^ index » next coverage.py v7.5.2, created at 2024-07-16 01:15 +0800
« prev ^ index » next coverage.py v7.5.2, created at 2024-07-16 01:15 +0800
1'''
2 Metrics module of crip.
4 https://github.com/SEU-CT-Recon/crip
5'''
7import numpy as np
8from scipy.stats import ttest_ind, ttest_rel
9from skimage.metrics import structural_similarity, peak_signal_noise_ratio
11from .utils import *
12from ._typing import *
15def computeMAPE(x: TwoOrThreeD, y: TwoOrThreeD, eps=1e-6) -> float:
16 ''' Compute the Mean Absolution Percentage Error (%) where `x` is the prediction
17 and `y` is the ground truth.
18 '''
19 cripAssert(isOfSameShape(x, y), 'Input images must have the same shape.')
21 return np.mean(np.abs(x - y) / (y + eps)) * 100
24def computePSNR(x: TwoOrThreeD, y: TwoOrThreeD, range_=1) -> float:
25 ''' Compute the Peak Signal Noise Ratio (PSNR) (dB) between `x` and `y`.
26 '''
27 cripWarning(range_ in [1, 255],
28 '`range_` for PSNR is usually 1 or 255. Be sure your behavior follows your intention.')
29 cripAssert(isOfSameShape(x, y), 'Input images must have the same shape.')
31 return peak_signal_noise_ratio(x, y, data_range=range_)
34def computeSSIM(x: TwoOrThreeD, y: TwoOrThreeD, range_=1) -> float:
35 ''' Compute the Structural Similarity (SSIM) between `x` and `y`.
36 '''
37 cripWarning(range_ in [1, 255],
38 '`range_` for SSIM is usually 1 or 255. Be sure your behavior follows your intention.')
39 cripAssert(isOfSameShape(x, y), 'Input images must have the same shape.')
41 return structural_similarity(x, y, data_range=range_, channel_axis=0 if is3D(x) else None)
44def computeRMSE(x: TwoOrThreeD, y: TwoOrThreeD, pixelwise: bool = False) -> Or[float, TwoOrThreeD]:
45 ''' Compute the Root Mean Squared Error (RMSE) between `x` and `y`.
46 '''
47 se = (x - y)**2
48 reducer = identity if pixelwise else np.mean
50 return np.sqrt(reducer(se))
53def computeMAE(x: TwoOrThreeD, y: TwoOrThreeD, pixelwise: bool = False) -> Or[float, TwoOrThreeD]:
54 ''' Compute the Mean Absolute Error (MAE) between `x` and `y`.
55 '''
56 ae = np.abs(x - y)
57 reducer = identity if pixelwise else np.mean
59 return reducer(ae)
62def pvalueInd(control: NDArray, treated: NDArray, equalVar: bool = True) -> float:
63 ''' Compute the two-sided p-value of the independent t-test between metrics `control` and `treated`.
64 '''
66 return ttest_ind(control.flatten(), treated.flatten(), equal_var=equalVar).pvalue
69def pvalueRel(control: NDArray, treated: NDArray) -> float:
70 ''' Compute the two-sided p-value of the related t-test between metrics `control` and `treated`.
71 '''
73 return ttest_rel(control.flatten(), treated.flatten()).pvalue
76class AverageMeter():
77 ''' Computes and stores the average and current value in `avg` and `val` respectively.
78 '''
80 def __init__(self):
81 self.val = 0 # current value
82 self.avg = 0 # average value
83 self.sum = 0 # sum of all values
84 self.count = 0 # number of values
86 def update(self, val):
87 self.val = val
88 self.sum += val
89 self.count += 1
90 self.avg = self.sum / self.count