您的位置:首页 > 其它

如何使用Opencv计算PSNR

2017-09-08 13:09 183 查看

什么是PSNR和MSE

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

1. 主观方法

通过人眼去判断,给出主观评价

2. 客观方法

主要有MSE(Mean Square Error 平均平方误差)和PSNR(Peak Signal Noise Ratio,峰值信噪比)等

MSE





如何用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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: