"""
The reconstruct package provides reconstruction algorithms,
as well as preprocessing tools and performance scores.
"""
# Copyright (c) 2020 Idiap Research Institute, http://www.idiap.ch/
# Written by François Marelli <francois.marelli@idiap.ch>
#
# This file is part of CBI Toolbox.
#
# CBI Toolbox is free software: you can redistribute it and/or modify
# it under the terms of the 3-Clause BSD License.
#
# CBI Toolbox is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# 3-Clause BSD License for more details.
#
# You should have received a copy of the 3-Clause BSD License along
# with CBI Toolbox. If not, see https://opensource.org/licenses/BSD-3-Clause.
#
# SPDX-License-Identifier: BSD-3-Clause
import numpy as np
[docs]def psnr(ref, target, norm=None, limit=None, in_place=False):
"""
Computes the Peak Signal-to-Noise Ratio:
PSNR = 10 log( limit ^ 2 / MSE(ref, target) )
Parameters
----------
ref : numpy.ndarray
The ground-truth reference array.
target : numpy.ndarray
The reconstructed array.
norm : str
Normalize the images before computing snr, default is None.
limit: float, optional
The maximum pixel value used for PSNR computation,
default is None (max(ref)).
in_place : bool, optional
Perform normalizations in-place, by default False.
Returns
-------
float
The PSNR.
"""
if norm is None:
pass
elif norm == "mse":
target = scale_to_mse(ref, target, in_place)
else:
ref = normalize(ref, in_place)
target = normalize(target, in_place)
if limit is None:
limit = ref.max()
return 10 * np.log10(limit**2 / mse(ref, target))
[docs]def mse(ref, target):
"""
Computes the Mean Squared Error between two arrays
Parameters
----------
ref : numpy.ndarray
Reference array.
target : numpy.ndarray
Target array.
Returns
-------
float
The MSE.
"""
return np.square(np.subtract(ref, target)).mean()
[docs]def normalize(image, mode="std", in_place=False):
"""
Normalize an image according to the given criterion.
Parameters
----------
image : numpy.ndarray
Image to normalize, will be modified.
mode : str, optional
Type of normalization to use, by default 'std'.
Allowed: ['std', 'max', 'sum']
in_place : bool, optional
Perform computations in-place, by default False.
Returns
-------
array
The normalized image (same as input).
Raises
------
ValueError
For unknown mode.
"""
if mode == "std":
f = np.std(image)
elif mode == "max":
f = np.max(image)
elif mode == "sum":
f = np.sum(image)
else:
raise ValueError("Invalid norm: {}".format(mode))
if not in_place:
image = image / f
else:
image /= f
return image
[docs]def scale_to_mse(ref, target, in_place=False):
"""
Scale a target array to minimise MSE with reference
Parameters
----------
ref : numpy.ndarray
The reference for MSE.
target : numpy.ndarray
The array to rescale.
in_place : bool, optional
Perform computations in-place, by default False.
Returns
-------
numpy.ndarray
The rescaled target.
"""
w = np.sum(ref * target) / np.sum(target**2)
if not in_place:
target = target * w
else:
target *= w
return target