Home | History | Annotate | Download | only in refocus
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.renderscript.cts.refocus;
     18 
     19 import android.graphics.Bitmap;
     20 import android.graphics.Color;
     21 import java.lang.Math;
     22 
     23 public class ImageCompare {
     24 
     25     /**
     26      * Compute the luma channel of an RGB image, i.e., the Y channel of the
     27      * equivalent YCbCr image.
     28      * https://en.wikipedia.org/wiki/YCbCr
     29      */
     30     private static double luma(int pixel) {
     31         final int R = Color.red(pixel);
     32         final int G = Color.green(pixel);
     33         final int B = Color.blue(pixel);
     34         return 0.299 * R + 0.587 * G + 0.114 * B;
     35     }
     36 
     37     /**
     38      * Compute peak signal-to-noise ration (PSNR) between two images
     39      * The greater the value of psnr, the closer the two images are to each
     40      * other. For identical images, psnr = +infinity.
     41      * For 8-bit images, a psnr above 50 is commonly acceptable for a lossy
     42      * conversion.
     43      *
     44      * References:
     45      * http://www.mathworks.com/help/vision/ref/psnr.html
     46      * https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio
     47      */
     48     public static double psnr(Bitmap bitmap1, Bitmap bitmap2) {
     49         if (bitmap1.getWidth() != bitmap2.getWidth() ||
     50             bitmap1.getHeight() != bitmap2.getHeight()) {
     51             throw new RuntimeException("images were of diffrent size");
     52         }
     53 
     54         if (bitmap1.sameAs(bitmap2)) {
     55             android.util.Log.i("RefocusTest",
     56                                "bitmaps verified to be identical in fast path.");
     57             return Double.POSITIVE_INFINITY;
     58         }
     59 
     60         final int width = bitmap1.getWidth();
     61         final int height = bitmap1.getHeight();
     62         final int numPixels = width * height;
     63 
     64         double noise = 0;
     65         for (int y = 0; y < height; y++) {
     66             for (int x = 0; x < width; x++) {
     67                 int pixel1 = bitmap1.getPixel(x, y);
     68                 int pixel2 = bitmap2.getPixel(x, y);
     69                 if (pixel1 != pixel2) {
     70                     final double Y1 = luma(pixel1);
     71                     final double Y2 = luma(pixel2);
     72                     noise += (Y1 - Y2) * (Y1 - Y2);
     73                 }
     74             }
     75         }
     76 
     77         final double mse = noise / numPixels;
     78         final double psnr = 20 * Math.log10(255) - 10 * Math.log10(mse);
     79         return psnr;
     80     }
     81 }
     82