Search code examples
imageopencvcomputer-visionmatchjavacv

How to implement PSNR in JavaCV?


I have found the implementation of PSNR in OpenCV written in C++, but I am having trouble to implement this in JavaCV.

http://docs.opencv.org/doc/tutorials/highgui/video-input-psnr-ssim/video-input-psnr-ssim.html#image-similarity-psnr-and-ssim

double getPSNR(const Mat& I1, const Mat& I2)
{
 Mat s1;
 absdiff(I1, I2, s1);       // |I1 - I2|
 s1.convertTo(s1, CV_32F);  // cannot make a square on 8 bits
 s1 = s1.mul(s1);           // |I1 - I2|^2

 Scalar s = sum(s1);         // sum elements per channel

 double sse = s.val[0] + s.val[1] + s.val[2]; // sum channels

 if( sse <= 1e-10) // for small values return zero
     return 0;
 else
 {
     double  mse =sse /(double)(I1.channels() * I1.total());
     double psnr = 10.0*log10((255*255)/mse);
     return psnr;
 }
}

For example:

  • What is Mat type? Is it same as MatVector in JavaCV?
  • how to do absdiff for MatVector?
  • I can't find the type Scalar.
  • How to do sum(s1)?

Thanks and Regards,

Jason


Solution

  • In this case Mat is an array of RGB values from your image. Scalar in this case is a list of 3 numbers.

    What absdiff(I1, I2, s1) is saying you take a pixel from your first image(I1) which has color/grayscale/rgba channels ect and subtract it from the pixel in image 2(I2), take the absolute value of the difference and then store it in your allocated Matrix/Array(s1) as the first element. If you had an rgb image you'd get the absolute difference |R1-R2|,|G1-G2|,|B1-B2| and store those 3 values, where 1 is from image one, and 2 is from image 2, doing so for all pixels.

    What sum(s1) is saying, in s1 which stores the differences in color from the two images, sum up all the red values, sum up all the blue values, and sum up all the green values, and return a list of 3 numbers representing the totals of each color.

    Just replace RGB with YMK or anything else you might be using.

    More information about the basic types including Matrix and Scalar can be found in the opencv documentation here: http://opencv.willowgarage.com/documentation/cpp/basic_structures.html and some code can be found near this file and directory: https://github.com/Itseez/opencv/blob/master/modules/core/include/opencv2/core/types_c.h

    "The class Mat represents a 2D numerical array that can act as a matrix (and further it’s referred to as a matrix), image, optical flow map etc. It is very similar to CvMat type from earlier versions of OpenCV, and similarly to CvMat , the matrix can be multi-channel, but it also fully supports ROI mechanism, just like IplImage ."