利用OpenCV计算灰度图像的峰值信噪比(PSNR)


我用两种方法实现了灰度图像的PSNR的计算,如下。代码虽说是针对灰度图像的,但能很容易扩展到多通道图像的PSNR的计算。

代码之一,完全靠自己的代码实现PSNR的计算:

  1. #include <cv.h>  
  2. #include <highgui.h>  
  3. #include <math.h>  
  4. #include <stdio.h>  
  5. #pragma comment( lib, "cv.lib" )  
  6. #pragma comment( lib, "cxcore.lib" )  
  7. #pragma comment( lib, "highgui.lib" )   
  8. int main()  
  9. {  
  10.     IplImage* img = cvLoadImage("lena.jpg",0);  
  11.     int height=img->height;  
  12.     int width=img->width;  
  13.     int step=img->widthStep;  
  14.     uchar *data=(uchar *)img->imageData;  
  15.     int i,j;  
  16.     double sum=0;  
  17.     for(i=0;i<height;i++)   
  18.     {  
  19.         for(j=0;j<width;j++)   
  20.         {  
  21.             sum+=data[i*step+j];  
  22.         }  
  23.     }  
  24.     double mean=0;  
  25.     mean=sum/(width*height);  
  26.     double mse=0;  
  27.     for(i=0;i<height;i++)   
  28.     {  
  29.         for(j=0;j<width;j++)   
  30.         {  
  31.             mse+=(data[i*step+j]-mean)*(data[i*step+j]-mean);  
  32.         }  
  33.     }  
  34.     mse=mse/(width*height);  
  35.     double psnr=0;  
  36.     psnr=10*log10(255*255/mse);  
  37.     printf("%lf/n",sum);  
  38.     printf("%lf/n",mean);  
  39.     printf("%lf/n",mse);  
  40.     printf("%lf/n",psnr);  
  41.     cvNamedWindow("Lena", CV_WINDOW_AUTOSIZE);   
  42.     cvShowImage("Lena", img );    
  43.     cvWaitKey(0);  
  44.     cvDestroyWindow("Lena");  
  45.     cvReleaseImage(&img );  
  46.     return 0;  
  47. }  

代码之二,使用了许多OpenCV库提供的函数,代码要精炼一些:

  1. #include <cv.h>  
  2. #include <highgui.h>  
  3. #include <math.h>  
  4. #include <stdio.h>  
  5. #pragma comment( lib, "cv.lib" )  
  6. #pragma comment( lib, "cxcore.lib" )  
  7. #pragma comment( lib, "highgui.lib" )   
  8. int main()  
  9. {  
  10.     IplImage* img = cvLoadImage("lena.jpg",0);  
  11.       
  12.     CvScalar sum=cvSum(img);  
  13.     CvScalar mean=cvAvg(img);  
  14.     CvScalar stddev;  
  15.     cvAvgSdv(img,NULL,&stddev);  
  16.     double psnr=20*log10(255/stddev.val[0]);  
  17.     printf("%lf/n",sum.val[0]);  
  18.     printf("%lf/n",mean.val[0]);  
  19.     printf("%lf/n",stddev.val[0]);  
  20.     printf("%lf/n",psnr);  
  21.     cvNamedWindow("Lena", CV_WINDOW_AUTOSIZE);   
  22.     cvShowImage("Lena", img );    
  23.     cvWaitKey(0);  
  24.     cvDestroyWindow("Lena");  
  25.     cvReleaseImage(&img );  
  26.     return 0;  
  27. }  

经lena图检验,上面两份代码计算的结果是一样的。

说明:上面的PSNR的定义参考了维基百科的相关条目。疏漏之处,欢迎拍砖!

相关内容