什么是PSNR和MSE
最近正在做超分辨率相關(guān)的工作饶辙,在底層圖像處理(或者說是CV領(lǐng)域的low-level vision)工作中轴总,評(píng)價(jià)標(biāo)準(zhǔn)有兩種:
- 主觀方法
通過人眼去判斷沟绪,給出主觀評(píng)價(jià) -
客觀方法
主要有MSE(Mean Square Error 平均平方誤差)和PSNR(Peak Signal Noise Ratio怔檩,峰值信噪比)等
MSE
如何用OpenCV實(shí)現(xiàn)PSNR的計(jì)算
在使用Opencv的時(shí)候褪秀,我們可以借用矩陣的操作,而不用循環(huán)嵌套去一個(gè)一個(gè)計(jì)算薛训,特別地媒吗,要把uint8轉(zhuǎn)換成float,否則在精度問題上的出錯(cuò)會(huì)導(dǎo)致很大的偏差
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一定要提前轉(zhuǎn)換為32F闸英,因?yàn)閡int8格式的無法計(jì)算成平方
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); // 分別計(jì)算每個(gè)通道的元素之和
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作為偏置,不至于發(fā)生除了的錯(cuò)誤
double psnr = 10.0 * log10( 255*255 / (Mse+0.0000001) );
std::cout<< "PSNR : " << Psnr << std::endl;
return psnr;