我用兩種方法實現了灰度圖像的PSNR的計算,如下。代碼雖說是針對灰度圖像的,但能很容易擴展到多通道圖像的PSNR的計算。
代碼之一,完全靠自己的代碼實現PSNR的計算:
- #include <cv.h>
- #include <highgui.h>
- #include <math.h>
- #include <stdio.h>
- #pragma comment( lib, "cv.lib" )
- #pragma comment( lib, "cxcore.lib" )
- #pragma comment( lib, "highgui.lib" )
- int main()
- {
- IplImage* img = cvLoadImage("lena.jpg",0);
- 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=0;
- 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=0;
- psnr=10*log10(255*255/mse);
- printf("%lf/n",sum);
- printf("%lf/n",mean);
- printf("%lf/n",mse);
- printf("%lf/n",psnr);
- cvNamedWindow("Lena", CV_WINDOW_AUTOSIZE);
- cvShowImage("Lena", img );
- cvWaitKey(0);
- cvDestroyWindow("Lena");
- cvReleaseImage(&img );
- return 0;
- }
代碼之二,使用了許多OpenCV庫提供的函數,代碼要精煉一些:
- #include <cv.h>
- #include <highgui.h>
- #include <math.h>
- #include <stdio.h>
- #pragma comment( lib, "cv.lib" )
- #pragma comment( lib, "cxcore.lib" )
- #pragma comment( lib, "highgui.lib" )
- int main()
- {
- IplImage* img = cvLoadImage("lena.jpg",0);
-
- CvScalar sum=cvSum(img);
- CvScalar mean=cvAvg(img);
- CvScalar stddev;
- cvAvgSdv(img,NULL,&stddev);
- double psnr=20*log10(255/stddev.val[0]);
- printf("%lf/n",sum.val[0]);
- printf("%lf/n",mean.val[0]);
- printf("%lf/n",stddev.val[0]);
- printf("%lf/n",psnr);
- cvNamedWindow("Lena", CV_WINDOW_AUTOSIZE);
- cvShowImage("Lena", img );
- cvWaitKey(0);
- cvDestroyWindow("Lena");
- cvReleaseImage(&img );
- return 0;
- }
經lena圖檢驗,上面兩份代碼計算的結果是一樣的。
說明:上面的PSNR的定義參考了維基百科的相關條目。疏漏之處,歡迎拍磚!