什么是PSNR和MSE
最近正在做超分辨率相关的工作,在底层图像处理(或者说是CV领域的low-level vision)工作中,评价标准有两种:
- 主观方法
通过人眼去判断,给出主观评价 -
客观方法
主要有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;