【问题标题】:How to implement PSNR in JavaCV?如何在 JavaCV 中实现 PSNR?
【发布时间】:2013-10-10 16:58:32
【问题描述】:

我找到了用 C++ 编写的 OpenCV 中 PSNR 的实现,但在 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;
 }
}

例如:

  • 什么是垫子类型?和 JavaCV 中的 MatVector 一样吗?
  • 如何为 MatVector 做 absdiff?
  • 我找不到标量类型。
  • sum(s1)怎么做?

感谢和问候,

杰森

【问题讨论】:

    标签: image opencv computer-vision match javacv


    【解决方案1】:

    在这种情况下,Mat 是图像中的 RGB 值数组。 在这种情况下,标量是 3 个数字的列表。

    什么 absdiff(I1, I2, s1) 是说您从具有彩色/灰度/rgba 通道等的第一张图像 (I1) 中获取一个像素,然后从图像 2(I2) 中的像素中减去它,取绝对值差异的值,然后将其作为第一个元素存储在分配的 Matrix/Array(s1) 中。如果你有一个 rgb 图像,你会得到绝对差异 |R1-R2|,|G1-G2|,|B1-B2|并存储这 3 个值,其中 1 来自图像 1,2 来自图像 2,对所有像素都这样做。

    sum(s1) 是什么意思,在 s1 中存储两个图像的颜色差异,将所有红色值相加,将所有蓝色值相加,并将所有绿色值相加,并返回一个列表代表每种颜色的总数的 3 个数字。

    只需将 RGB 替换为 YMK 或您可能正在使用的任何其他东西。

    有关基本类型(包括矩阵和标量)的更多信息可以在此处的 opencv 文档中找到:http://opencv.willowgarage.com/documentation/cpp/basic_structures.html,并且可以在此文件和目录附近找到一些代码:https://github.com/Itseez/opencv/blob/master/modules/core/include/opencv2/core/types_c.h

    “Mat 类表示一个 2D 数值数组,可以作为矩阵(进一步称为矩阵)、图像、光流图等。它与 OpenCV 早期版本的 CvMat 类型非常相似,并且与 CvMat 类似,矩阵可以是多通道的,但它也完全支持 ROI 机制,就像 IplImage 一样。”

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,并使用 JavaCV 将上面的代码翻译成 Java。这是我的代码:

      private static double getPSNR(CvMat I1, CvMat I2) {     
          CvMat s1 = CvMat.create(I1.rows(), I1.cols(), I1.depth(), I1.nChannels()); //create matrix with same size as I1
          cvAbsDiff(I1, I2, s1); // |I1 - I2|
      
          CvMat s1_squared = cvCreateMat(s1.rows(), s1.cols(), CV_32FC3); //convert mat to 32bit and 3 channels
          cvMul(s1, s1, s1_squared, 1); // |I1 - I2| ^2
      
          CvScalar scalar = cvSum(s1_squared); // sum elements per channel
          double sse = scalar.getVal(0) + scalar.getVal(1) + scalar.getVal(2); // sum channels
      
          double mse = sse / (double) (s1.channels() * s1.total());
          double psnr = 10.0 * Math.log10((255*255) / mse);
      
          return psnr;
      }
      

      【讨论】:

        猜你喜欢
        • 2012-11-25
        • 2017-12-10
        • 1970-01-01
        • 2019-09-14
        • 1970-01-01
        • 1970-01-01
        • 2021-08-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多