美文网首页
Opencv如何计算PSNR和MSE

Opencv如何计算PSNR和MSE

作者: 太阳上的日子 | 来源:发表于2017-09-07 14:26 被阅读0次

    什么是PSNR和MSE

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

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


      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

          本文链接:https://www.haomeiwen.com/subject/rnkijxtx.html