import numpy def psnr(dataset1, dataset2, maximumDataValue, ignore=None): """ title:: psnr description:: This method will compute the peak-signal-to-noise ratio (PSNR) between two provided data sets. The PSNR will be computed for the ensemble data. If the PSNR is desired for a particular slice of the provided data, then the data sets provided should represent those slices. attributes:: dataset1 An array-like object containing the first data set. dataset2 An array-like object containing the second data set. maximumDataValue The maximum value that might be contained in the data set (this is not necessarily the maximum value in the data set, but rather it is the largest value that any member of the data set might take on). ignore A scalar value that will be ignored in the data sets. This can be used to mask data in the provided data set from being included in the analysis. This value will be looked for in both of the provided data sets, and only an intersection of positions in the two data sets will be included in the computation. [default is None] author:: Carl Salvaggio copyright:: Copyright (C) 2015, Rochester Institute of Technology license:: GPL version:: 1.0.0 disclaimer:: This source code is provided "as is" and without warranties as to performance or merchantability. The author and/or distributors of this source code may have made statements about this source code. Any such statements do not constitute warranties and shall not be relied on by the user in deciding whether to use this source code. This source code is provided without any express or implied warranties whatsoever. Because of the diversity of conditions and hardware under which this source code may be used, no warranty of fitness for a particular purpose is offered. The user is advised to test the source code thoroughly before relying on it. The user must assume the entire risk of using the source code. """ # Make sure that the provided data sets are numpy ndarrays, if not # convert them and flatten te data sets for analysis if type(dataset1).__module__ != numpy.__name__: d1 = numpy.asarray(dataset1).flatten() else: d1 = dataset1.flatten() if type(dataset2).__module__ != numpy.__name__: d2 = numpy.asarray(dataset2).flatten() else: d2 = dataset2.flatten() # Make sure that the provided data sets are the same size if d1.size != d2.size: raise ValueError('Provided datasets must have the same size/shape') # Check if the provided data sets are identical, and if so, return an # infinite peak-signal-to-noise ratio if numpy.array_equal(d1, d2): return float('inf') # If specified, remove the values to ignore from the analysis and compute # the element-wise difference between the data sets if ignore is not None: index = numpy.intersect1d(numpy.where(d1 != ignore)[0], numpy.where(d2 != ignore)[0]) error = d1[index].astype(numpy.float64) - d2[index].astype(numpy.float64) else: error = d1.astype(numpy.float64)-d2.astype(numpy.float64) # Compute the mean-squared error meanSquaredError = numpy.sum(error**2) / error.size # Return the peak-signal-to-noise ratio return 10.0 * numpy.log10(maximumDataValue**2 / meanSquaredError)