Opencv如何计算PSNR和MSE

什么是PSNR和MSE

最近正在做超分辨率相关的工作,在底层图像处理(或者说是CV领域的low-level vision)工作中,评价标准有两种:

  1. 主观方法
    通过人眼去判断,给出主观评价
  2. 客观方法
    主要有MSE(Mean Square Error 平均平方误差)和PSNR(Peak Signal Noise Ratio,峰值信噪比)等
    MSE


    Opencv如何计算PSNR和MSE_第1张图片
    image.png
image.png

如何用OpenCV实现PSNR的计算

在使用Opencv的时候,我们可以借用矩阵的操作,而不用循环嵌套去一个一个计算,特别地,要把uint8转换成float,否则在精度问题上的出错会导致很大的偏差

double compute_PSNR(cv::Mat Mat1, cv::Mat Mat2)
{

    cv::Mat M1 = Mat1.clone();
    cv::Mat M2 = Mat2.clone();

    int rows = M2.rows;
    int cols = M2.cols 
    // 确保它们的大小是一致的
    cv::resize(mGND,mGND,cv::Size(cols,rows) );

    mGND.convertTo(M1,CV_32F);
    mSR.convertTo(mSR,CV_32F);
    // compute PSNR
    Mat Diff;
    // Diff一定要提前转换为32F,因为uint8格式的无法计算成平方
    Diff.convertTo(Diff,CV_32F);    
    cv::absdiff(M1,M2,Diff); //  Diff = | M1 - M2 |

    Diff=  Diff.mul(Diff);            //     | M1 - M2 |.^2
    Scalar S = cv::sum(Diff);  // 分别计算每个通道的元素之和

    double sse;   // square error
    if (mDiff.channels()==3)
        sse = S.val[0] +S.val[1] + S.val[2];  // sum of all channels
    else
        sse = S.val[0];

    int nTotalElement = mGND.channels()*mGND.total();
    
    double mse = ( sse / (double)nTotalElement );  // 
   
    // 加上0.0000001作为偏置,不至于发生除了的错误
    double psnr = 10.0 * log10( 255*255 / (Mse+0.0000001) );
    std::cout<< "PSNR : " << Psnr << std::endl;
    return psnr;

你可能感兴趣的:(Opencv如何计算PSNR和MSE)