峰值信噪比(PSNR),一种评价图像的客观标准。它具有局限性,PSNR是“PeakSignaltoNoiseRatio”的缩写。peak的中文意思是顶点。而radio的意思是比率或比列的。整个意思就是到达噪音比率的顶点信号,psnr是一般是用于最大值信号和背景噪音之间的一个工程项目。通常在经过影像压缩之后,输出的影像通常都会有某种程度与原始影像不一样。为了衡量经过处理后的影像品质,我们通常会参考PSNR值来认定某个处理程序够不够令人满意。它是原图像与处理图像之间均方误差相对于(2^n-1)^2的对数值(信号最大值的平方,n是每个采样值的比特数),它的单位是dB。公式如下:
其中,MSE是原图像与处理图像之间均方误差。公式中的符号采用了MATLAB的用法。Peak就是指8bits表示法的最大值255。MSE指MeanSquareError,I(角标n)指原始影像第n个pixel值,P(角标n)指经处理后的影像第n个pixel值。PSNR的单位为dB。所以PSNR值越大,就代表失真越少。
PSNR是最普遍,最广泛使用的评鉴画质的客观量测法,不过许多实验结果都显示,PSNR的分数无法和人眼看到的视觉品质完全一致,有可能PSNR较高者看起来反而比PSNR较低者差。这是因为人眼的视觉对于误差的敏感度并不是绝对的,其感知结果会受到许多因素的影响而产生变化(例如:人眼对空间频率较低的对比差异敏感度较高,人眼对亮度对比差异的敏感度较色度高,人眼对一个区域的感知结果会受到其周围邻近区域的影响)。
实现了灰度图像的PSNR的计算,如下代码虽说是针对灰度图像的,但能很容易扩展到多通道图像的PSNR的计算。#include "opencv2/opencv.hpp" int _tmain(int argc, _TCHAR* argv[]) { IplImage* img = cvLoadImage("test.jpg",0); /////////////////////////////////////////////////////////////// //提供两种方法,实现PSNR计算。 ////////////////////////////////////////////////////////////// //一种方法:使用OpenCV库提供的函数,实现PSNR的计算: CvScalar sum=cvSum(img); CvScalar mean=cvAvg(img); CvScalar stddev; cvAvgSdv(img,NULL,&stddev); double psnr=20*log10(255/stddev.val[0]); printf("SUM =%lf\n",sum.val[0]); printf("Mean =%lf\n",mean.val[0]); printf("STDDEV =%lf\n",stddev.val[0]); printf("PSNR =%lf\n",psnr); printf("\n"); /////////////////////////////////////////////////////////////// ///另一种方法:不使用opencv库函数,实现PSNR的计算: int height=img->height; int width=img->width; int step=img->widthStep; uchar *data=(uchar *)img->imageData; int i,j; double _sum=0; for(i=0;i<height;i++) { for(j=0;j<width;j++){ _sum+=data[i*step+j]; } } double _mean=_sum/(width*height); double _mse=0; for(i=0;i<height;i++) { for(j=0;j<width;j++) { _mse+=(data[i*step+j]-_mean)*(data[i*step+j]-_mean); } } _mse=_mse/(width*height); double _psnr=10*log10(255*255/_mse); printf("SUM =%lf\n",_sum); printf("Mean =%lf\n",_mean); printf("Mse =%lf\n",_mse); printf("PSNR =%lf\n",_psnr); ///////////////////////////////////////////////////////////// cvNamedWindow("Test", CV_WINDOW_AUTOSIZE); cvShowImage("Test", img ); cvWaitKey(0); cvDestroyWindow("Test"); cvReleaseImage(&img ); return 0; }测试结果如下所示:
关于Image Engineering & Computer Vision的更多讨论与交流,敬请关注本博客和新浪微博songzi_tea.