blob: 0ea2af0d5840fa71807eb942f30db551072221e3 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.renderscript.cts.refocus;
import android.graphics.Bitmap;
import android.graphics.Color;
import java.lang.Math;
public class ImageCompare {
/**
* Compute the luma channel of an RGB image, i.e., the Y channel of the
* equivalent YCbCr image.
* https://en.wikipedia.org/wiki/YCbCr
*/
private static double luma(int pixel) {
final int R = Color.red(pixel);
final int G = Color.green(pixel);
final int B = Color.blue(pixel);
return 0.299 * R + 0.587 * G + 0.114 * B;
}
/**
* Compute peak signal-to-noise ration (PSNR) between two images
* The greater the value of psnr, the closer the two images are to each
* other. For identical images, psnr = +infinity.
* For 8-bit images, a psnr above 50 is commonly acceptable for a lossy
* conversion.
*
* References:
* http://www.mathworks.com/help/vision/ref/psnr.html
* https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio
*/
public static double psnr(Bitmap bitmap1, Bitmap bitmap2) {
if (bitmap1.getWidth() != bitmap2.getWidth() ||
bitmap1.getHeight() != bitmap2.getHeight()) {
throw new RuntimeException("images were of diffrent size");
}
if (bitmap1.sameAs(bitmap2)) {
android.util.Log.i("RefocusTest",
"bitmaps verified to be identical in fast path.");
return Double.POSITIVE_INFINITY;
}
final int width = bitmap1.getWidth();
final int height = bitmap1.getHeight();
final int numPixels = width * height;
double noise = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel1 = bitmap1.getPixel(x, y);
int pixel2 = bitmap2.getPixel(x, y);
if (pixel1 != pixel2) {
final double Y1 = luma(pixel1);
final double Y2 = luma(pixel2);
noise += (Y1 - Y2) * (Y1 - Y2);
}
}
}
final double mse = noise / numPixels;
final double psnr = 20 * Math.log10(255) - 10 * Math.log10(mse);
return psnr;
}
}