// Catalano Imaging Library
// The Catalano Framework
//
// Copyright © Diego Catalano, 2012-2016
// diego.catalano at live.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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 GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
package Catalano.Imaging.Tools;
import Catalano.Imaging.FastBitmap;
/**
* Objective Fidelity Criteria.
*
* The Objective criteria, although widely used, are not necessarily correlated with out perception of image quality. For instance,
* an image with a low error as determined by an objective measure may actually look much worse than an image with a high error metric.
* References: http://uotechnology.edu.iq/sweit/lecture%202013n/4th%20Image%20Processing%20_Lectures/DIP_Lecture13.pdf
*
* @author Diego Catalano
*/
public class ObjectiveFidelity {
private FastBitmap original, reconstructed;
/**
* Get Original image.
* @return Original image.
*/
public FastBitmap getOriginalImage() {
return original;
}
/**
* Set Original image.
* @param original Original image.
*/
public void setOriginalImage(FastBitmap original) {
this.original = original;
}
/**
* Get Reconstructed image.
* @return Reconstructed image.
*/
public FastBitmap getReconstructedImage() {
return reconstructed;
}
/**
* Set Reconstructed Image.
* @param reconstructed Reconstructed image.
*/
public void setReconstructedImage(FastBitmap reconstructed) {
this.reconstructed = reconstructed;
}
/**
* Initialize a new instance of the ObjectiveFidelity class.
* @param original Original image.
* @param reconstructed Reconstructed image.
*/
public ObjectiveFidelity(FastBitmap original, FastBitmap reconstructed) {
this.original = original;
this.reconstructed = reconstructed;
if ((original.getWidth() != reconstructed.getWidth()) || (original.getHeight() != reconstructed.getHeight()))
throw new IllegalArgumentException("The both images must be equal dimensions");
if(original.getColorSpace() != reconstructed.getColorSpace())
throw new IllegalArgumentException("The both images must be the same pixel format.");
}
/**
* Calculate total error.
* @return Total error.
*/
public int getTotalError(){
int sumError = 0;
for (int x = 0; x < original.getHeight(); x++) {
for (int y = 0; y < original.getWidth(); y++) {
sumError += Math.abs(reconstructed.getGray(x, y) - original.getGray(x, y));
}
}
return sumError;
}
/**
* Calculate mean absolute error.
* @return Mean absolute error.
*/
public double getMAE(){
double sumError = 0;
for (int x = 0; x < original.getHeight(); x++) {
for (int y = 0; y < original.getWidth(); y++) {
sumError += Math.abs(reconstructed.getGray(x, y) - original.getGray(x, y));
}
}
return (1/(double)(original.getWidth() * original.getHeight())) * sumError;
}
/**
* Calculate Root mean square Error.
* @return MSE.
*/
public double getMSE(){
int sumError = 0;
double squareDiff;
for (int x = 0; x < original.getHeight(); x++) {
for (int y = 0; y < original.getWidth(); y++) {
squareDiff = Math.pow(reconstructed.getGray(x, y) - original.getGray(x, y), 2);
sumError += squareDiff;
}
}
double size = 1D/(double)(original.getWidth() * original.getHeight());
return Math.sqrt(size * sumError);
}
/**
* Calculate Mean square signal-to-noise ratio.
* @return SNR.
*/
public double getSNR(){
double squareImg = 0;
double squareRecon = 0;
for (int x = 0; x < original.getHeight(); x++) {
for (int y = 0; y < original.getWidth(); y++) {
int g = reconstructed.getGray(x, y);
squareRecon += g*g;
squareImg += Math.pow(g - original.getGray(x, y), 2);
}
}
if(squareImg == 0) return 0;
return Math.sqrt(squareRecon/squareImg);
}
/**
* Derivative Signal noise ratio.
* D-SNR consider the sentivity of the human eye to the edges.
* Reference: A New Objective Fidelity Criterion For Image Processing: Derivative SNR - Hakki Tarkan Yalazan, and Melek D. Yucel.
* @return D-SNR.
*/
public double getDSNR(){
int w = original.getWidth();
int h = original.getHeight();
double sumGradO = 0;
double sumGradDiff = 0;
for (int i = 0; i < h - 1; i++) {
for (int j = 0; j < w - 1; j++) {
int gradO = Math.abs(original.getGray(i, j) - original.getGray(i + 1, j)) + Math.abs(original.getGray(i, j) - original.getGray(i, j + 1));
sumGradO += gradO * gradO;
int gradR = Math.abs(reconstructed.getGray(i, j) - reconstructed.getGray(i + 1, j)) + Math.abs(reconstructed.getGray(i, j) - reconstructed.getGray(i, j + 1));
sumGradDiff += Math.pow(gradO - gradR, 2);
}
}
if(sumGradDiff == 0) return 0;
double r = sumGradO / sumGradDiff;
return 10 * Math.log10(r);
}
/**
* Calculate PEAK signal-to-noise ratio.
* @return PSNR.
*/
public double getPSNR(){
return getPSNR(256);
}
/**
* Calculate PEAK signal-to-noise ratio.
* @param l Number of gray levels.
* @return PSNR.
*/
public double getPSNR(int l){
double sum = 0;
for (int x = 0; x < original.getHeight(); x++) {
for (int y = 0; y < original.getWidth(); y++) {
sum += Math.pow(reconstructed.getGray(x, y) - original.getGray(x, y), 2);
}
}
if(sum == 0) return 0;
int size = original.getWidth() * original.getHeight();
sum = (1D/(double)size) * sum;
sum = l*l / sum;
sum = 10D * Math.log10(sum);
return sum;
}
/**
* Calculate Universal Quality Index.
* References: Wang, Zhou, and Alan C. Bovik. "A universal image quality index." Signal Processing Letters, IEEE 9.3 (2002): 81-84.
*
* @return Universal Image Quality Index.
*/
public double getUniversalQualityIndex(){
double xMean = 0;
double yMean = 0;
//Calculate mean
int width = original.getWidth();
int height = original.getHeight();
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
xMean += original.getGray(i, j);
yMean += reconstructed.getGray(i, j);
}
}
xMean /= (double)(width*height);
yMean /= (double)(width*height);
//Calculate std deviation
double xStd = 0;
double yStd = 0;
double xyStd = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
xStd += Math.pow(original.getGray(i, j) - xMean, 2);
yStd += Math.pow(reconstructed.getGray(i, j) - yMean, 2);
xyStd += (original.getGray(i, j) - xMean) * (reconstructed.getGray(i, j) - yMean);
}
}
xStd /= (double)(width*height - 1);
yStd /= (double)(width*height - 1);
xyStd /= (double)(width*height - 1);
return (4 * xyStd * xMean * yMean) / ((xStd + yStd) * (xMean*xMean + yMean*yMean));
}
}
Ads help maintain this website.