"""Peak Signal-to-Noise Ratio metric.""" import datasets import numpy as np from skimage.metrics import peak_signal_noise_ratio from typing import Dict, Optional import evaluate _DESCRIPTION = """ Compute the Peak Signal-to-Noise Ratio (PSNR) for an image. Please pay attention to the `data_range` parameter with floating-point images. """ _KWARGS_DESCRIPTION = """ Args: predictions (`list` of `np.array`): Predicted labels. references (`list` of `np.array`): Ground truth labels. sample_weight (`list` of `float`): Sample weights Defaults to None. Returns: psnr (`float`): Peak Signal-to-Noise Ratio. The SSIM values are positive. Typical values for the PSNR in lossy image and video compression are between 30 and 50 dB, provided the bit depth is 8 bits, where higher is better. Examples: Example 1-A simple example >>> psnr = evaluate.load("jpxkqx/peak_signal_to_noise_ratio") >>> results = psnr.compute(references=[[0, 0], [-1, -1]], predictions=[[0, 1], [0, 0]]) >>> print(results) {"Peak Signal-to-Noise Ratio": 23.010298856486173} """ _CITATION = """ @article{boulogne2014scikit, title={Scikit-image: Image processing in Python}, author={Boulogne, Fran{\c{c}}ois and Warner, Joshua D and Neil Yager, Emmanuelle}, journal={J. PeerJ}, volume={2}, pages={453}, year={2014} } """ @evaluate.utils.file_utils.add_start_docstrings(_DESCRIPTION, _KWARGS_DESCRIPTION) class PeakSignaltoNoiseRatio(evaluate.Metric): def _info(self): return evaluate.MetricInfo( description=_DESCRIPTION, citation=_CITATION, inputs_description=_KWARGS_DESCRIPTION, features=datasets.Features(self._get_feature_types()), reference_urls=["https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio"], ) def _get_feature_types(self): if self.config_name == "multilist": return { # 1st Seq - num_samples, 2nd Seq - Height, 3rd Seq - Width "predictions": datasets.Sequence( datasets.Sequence(datasets.Sequence(datasets.Value("float32"))) ), "references": datasets.Sequence( datasets.Sequence(datasets.Sequence(datasets.Value("float32"))) ), } else: return { # 1st Seq - Height, 2rd Seq - Width "predictions": datasets.Sequence( datasets.Sequence(datasets.Value("float32")) ), "references": datasets.Sequence( datasets.Sequence(datasets.Value("float32")) ), } def _compute( self, predictions, references, data_range: Optional[float] = None, sample_weight=None, ) -> Dict[str, float]: samples = zip(np.array(predictions), np.array(references)) psnrs = list(map( lambda args: peak_signal_noise_ratio(*args, data_range=data_range), samples )) return np.average(psnrs, weights=sample_weight)