现在的位置: 首页 > 综合 > 正文

实现灰度图像峰值信噪比计算

2014年02月12日 ⁄ 综合 ⁄ 共 2103字 ⁄ 字号 评论关闭

峰值信噪比(PSNR),一种评价图像的客观标准。它具有局限性,PSNR是“PeakSignaltoNoiseRatio”的缩写。peak的中文意思是顶点。而radio的意思是比率或比列的。整个意思就是到达噪音比率的顶点信号,psnr是一般是用于最大值信号和背景噪音之间的一个工程项目。通常在经过影像压缩之后,输出的影像通常都会有某种程度与原始影像不一样。为了衡量经过处理后的影像品质,我们通常会参考PSNR值来认定某个处理程序够不够令人满意。它是原图像与处理图像之间均方误差相对于(2^n-1)^2的对数值(信号最大值的平方,n是每个采样值的比特数),它的单位是dB。公式如下:

PSNR


其中,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.

抱歉!评论已关闭.