代码:
1 #include <stdio.h> 2 #include <opencv/highgui.h> 3 #include <opencv/cv.h> 4 #include <opencv_libs.h> 5 6 7 /* 8 *《学习OpenCV》第五章第二题 9 * 完成时间:21:43 10/13 星期日 2013 10 * 作者:qdsclove@163.com 11 */ 12 13 /* Image Size */ 14 #define IMG_SIZE 100 15 16 /* 17 * Window Title 18 */ 19 #define WNDTITLE_IMAGE "source image" 20 #define WNDTITLE_FIVE "5*5 Gaussian" 21 #define WNDTITLE_NINE "9*9 Gaussian" 22 #define WNDTITLE_FIVE_TEICE "5*5 Gaussian Twice" 23 24 /* 25 * function: calculate MSE & PSNR of two GrayScale(8-bit depth & one channel) images. 26 * param: img1 -- the first image. 27 * param: img2 -- the second image. 28 * param: dMSE -- the MSE of two images(output) 29 * param: dPSNR -- the PSNR of two images(output) 30 * return: 0 -- success; others -- failed. 31 */ 32 int calculateGrayImgsPSNR(IplImage* img1, IplImage* img2, double& dMSE, double& dPSNR) 33 { 34 if( !img1 || !img2 || 35 img1->nChannels != 1 || 36 img2->nChannels != 1 || 37 img1->depth != img2->depth || 38 img1->width != img2->width || 39 img1->height != img2->height ) 40 { 41 return -1; 42 } 43 int width = img1->width; 44 int height = img1->height; 45 46 // calculate MSE of the two images 47 double dSumOfSquares = 0; 48 for(int i = 0; i < height; i++) 49 { 50 char* pdata1 = img1->imageData + i * img1->widthStep; 51 char* pdata2 = img2->imageData + i *img2->widthStep; 52 for(int j = 0; j < width; j++ ) 53 { 54 uchar value1 = *(pdata1 + j); 55 uchar value2 = *(pdata2 + j); 56 57 double square = pow( (double)(value1 - value2), 2 ); 58 dSumOfSquares += square; 59 } 60 } 61 62 dMSE = dSumOfSquares / (width * height); 63 64 // this is means the two images are strictly same. 65 if(dMSE == 0) 66 { 67 dPSNR = -1; 68 return 0; 69 } 70 int iDepth = img1->depth; 71 int iMAX = pow( 2., iDepth) - 1; 72 73 dPSNR = 20 * log10(iMAX / (sqrt(dMSE))); 74 75 return 0; 76 } 77 78 79 int main() 80 { 81 IplImage* image = cvCreateImage( cvSize(IMG_SIZE, IMG_SIZE), IPL_DEPTH_8U, 1 ); 82 IplImage* dst_five_gaussian = cvCreateImage( cvGetSize(image), image->depth, image->nChannels ); 83 IplImage* dst_nine_gaussian = cvCreateImage( cvGetSize(image), image->depth, image->nChannels ); 84 IplImage* dst_twice_five_gaussian = cvCreateImage( cvGetSize(image), image->depth, image->nChannels ); 85 86 // 全部像素置零 87 cvZero(image); 88 // 设置中心像素为255 89 cvSet2D(image, IMG_SIZE/2, IMG_SIZE/2, cvScalarAll(255)); 90 91 // 5*5 高斯滤波 92 cvSmooth(image, dst_five_gaussian, CV_GAUSSIAN, 5, 5); 93 // 9*9 高斯滤波 94 cvSmooth(image, dst_nine_gaussian, CV_GAUSSIAN, 9, 9); 95 // 5*5高斯滤波 第二次 96 cvSmooth(dst_five_gaussian, dst_twice_five_gaussian, 5, 5); 97 98 cvNamedWindow(WNDTITLE_IMAGE, CV_WINDOW_NORMAL); 99 cvNamedWindow(WNDTITLE_FIVE, CV_WINDOW_NORMAL); 100 cvNamedWindow(WNDTITLE_NINE, CV_WINDOW_NORMAL); 101 cvNamedWindow(WNDTITLE_FIVE_TEICE, CV_WINDOW_NORMAL); 102 103 cvShowImage(WNDTITLE_IMAGE, image); 104 cvShowImage(WNDTITLE_FIVE, dst_five_gaussian); 105 cvShowImage(WNDTITLE_NINE, dst_nine_gaussian); 106 cvShowImage(WNDTITLE_FIVE_TEICE, dst_twice_five_gaussian); 107 108 cvSaveImage("source.bmp", image); 109 cvSaveImage("5_5_gaussian.bmp", dst_five_gaussian); 110 cvSaveImage("9_9_gaussian.bmp", dst_nine_gaussian); 111 cvSaveImage("5_5_gaussian_twice.bmp", dst_twice_five_gaussian); 112 113 // c part 114 double dMSE = 0, dPSNR = 0; 115 calculateGrayImgsPSNR(dst_nine_gaussian, dst_twice_five_gaussian, dMSE, dPSNR); 116 printf("9*9 GAUSSIAN & 5*5 GAUSSIAN Twice: MSE: %f PSNR: %f ", dMSE, dPSNR); 117 118 cvWaitKey(0); 119 120 cvReleaseImage(&image); 121 cvReleaseImage(&dst_five_gaussian); 122 cvReleaseImage(&dst_nine_gaussian); 123 cvDestroyAllWindows(); 124 125 return 0; 126 }
结果分析,这里的截图都是结果图像放大之后的结果:
原图 & 5*5高斯滤波后的图像:
原图 & 5*5高斯滤波后的图像 & 9*9高斯滤波后的图像:
c部分:
原图 & 5*5高斯滤波后的图像 & 9*9高斯滤波后的图像 & 两次5*5高斯滤波后的图像:
9*9平滑一次与5*5平滑两次的MSE与PSNR:
从上一篇博文(http://www.cnblogs.com/qdsclove/p/3366907.html)可知这两幅图像的相似度很高。