《学习OpenCV》练习题第五章第一题ab

这道题是载入一幅带有有趣纹理的图像并用不同的模板(窗口,核)大小做高斯模糊(高斯平滑),然后比较用5*5大小的窗口平滑图像两次和用11*11大小的窗口平滑图像一次是否接近相同。

先说下我的做法,a部分我将每个不同的窗口大小模糊化后的图像生成后,还计算了每个模糊化后的图像与原始图像间的MSE值与PSNR值。(参见:http://zh.wikipedia.org/wiki/%E5%B3%B0%E5%80%BC%E4%BF%A1%E5%99%AA%E6%AF%94

b部分我计算了两次5*5窗口大小的高斯模糊后的图像与一次11*11窗口大小的高斯模糊图像之间的MSE与PSNR。

代码:

  1 #include <opencv/highgui.h>
  2 #include <opencv/cv.h>
  3 #include <opencv_libs.h>
  4 #include <math.h>
  5 
  6 /*
  7  *《学习OpenCV》第五章第一题  
  8  * 完成时间:18:37 10/13 星期日 2013  
  9  * 作者:qdsclove@163.com
 10  */
 11 
 12 /*
 13  * function: calculate MSE & PSNR of two GrayScale(8-bit depth & one channel) images.
 14  * param: img1 -- the first image.
 15  * param: img2 -- the second image.
 16  * param: dMSE -- the MSE of two images(output)
 17  * param: dPSNR -- the PSNR of two images(output)
 18  * return: 0 -- success;  others -- failed.
 19  */
 20 int calculateGrayImgsPSNR(IplImage* img1, IplImage* img2, double& dMSE, double& dPSNR)
 21 {
 22     if( !img1 || !img2 || 
 23         img1->nChannels != 1 ||
 24         img2->nChannels != 1 || 
 25         img1->depth != img2->depth ||
 26         img1->width != img2->width || 
 27         img1->height != img2->height )
 28     {
 29         return -1;
 30     }
 31     int width = img1->width;
 32     int height = img1->height;
 33 
 34     // calculate MSE of the two images
 35     double dSumOfSquares = 0;
 36     for(int i = 0; i < height; i++)
 37     {
 38         char* pdata1 = img1->imageData + i * img1->widthStep;
 39         char* pdata2 = img2->imageData + i *img2->widthStep;
 40         for(int j = 0; j < width; j++ )
 41         {
 42             uchar value1 = *(pdata1 + j);
 43             uchar value2 = *(pdata2 + j);
 44 
 45             double square = pow( (double)(value1 - value2), 2 );
 46             dSumOfSquares += square;
 47         }
 48     }
 49 
 50     dMSE = dSumOfSquares / (width * height);
 51 
 52     // this is means the two images are strictly same. 
 53     if(dMSE == 0)
 54     {
 55         dPSNR = -1;
 56         return 0;
 57     }
 58     int iDepth = img1->depth;
 59     int iMAX = pow( 2., iDepth) - 1;
 60 
 61     dPSNR = 20 * log10(iMAX / (sqrt(dMSE)));
 62 
 63     return 0;
 64 }
 65 
 66 int main()
 67 {
 68     const char * FILE_PATH = "Fig0333(a)(test_pattern_blurring_orig).tif";
 69 
 70     IplImage* src = cvLoadImage(FILE_PATH, CV_LOAD_IMAGE_UNCHANGED);
 71 
 72     if(!src)
 73     {
 74         printf("Load image error.
");
 75         return -1;
 76     }
 77 
 78     // Get the source image's size
 79     CvSize srcSize = cvGetSize(src);
 80 
 81     // 3 * 3
 82     IplImage* dst_three_gaussian = cvCreateImage(srcSize, src->depth, src->nChannels);
 83     // 5 * 5
 84     IplImage* dst_five_gaussian = cvCreateImage(srcSize, src->depth, src->nChannels);
 85     // 9 * 9
 86     IplImage* dst_nine_gaussian = cvCreateImage(srcSize, src->depth, src->nChannels);
 87     // 11 * 11
 88     IplImage* dst_eleven_gaussian = cvCreateImage(srcSize, src->depth, src->nChannels);
 89     // twice 5 * 5
 90     IplImage* dst_twice_five_gaussian = cvCreateImage( srcSize, src->depth, src->nChannels );
 91 
 92 
 93     if( !dst_three_gaussian || !dst_five_gaussian ||
 94         !dst_nine_gaussian || !dst_eleven_gaussian ||
 95         !dst_twice_five_gaussian )
 96     {
 97         printf("Create image error.
");
 98         return -1;
 99     }
100 
101     cvSmooth(src, dst_three_gaussian, CV_GAUSSIAN, 3, 3);
102     cvSmooth(src, dst_five_gaussian, CV_GAUSSIAN, 5, 5);
103     cvSmooth(src, dst_nine_gaussian, CV_GAUSSIAN, 9, 9);
104     cvSmooth(src, dst_eleven_gaussian, CV_GAUSSIAN, 11, 11);
105     cvSmooth( dst_five_gaussian, dst_twice_five_gaussian, CV_GAUSSIAN, 5, 5 );
106 
107     cvShowImage("src", src);
108     cvShowImage("src - GAUSSIAN 3*3", dst_three_gaussian);
109     cvShowImage("src - GAUSSIAN 5*5", dst_five_gaussian);
110     cvShowImage("src - GAUSSIAN 9*9", dst_nine_gaussian);
111     cvShowImage("src - GAUSSIAN 11*11", dst_eleven_gaussian);
112     cvShowImage("src - GAUSSIAN 5*5 Twice", dst_twice_five_gaussian );
113 
114     // calculate the MSE and PSNR of the two images.
115     double dMSE, dPSNR;
116     // part a:
117     calculateGrayImgsPSNR(src, dst_three_gaussian, dMSE, dPSNR);
118     printf("source image & 3*3 GAUSSIAN: MSE: %f	PSNR: %f
", dMSE, dPSNR);
119     calculateGrayImgsPSNR(src, dst_five_gaussian, dMSE, dPSNR);
120     printf("source image & 5*5 GAUSSIAN: MSE: %f	PSNR: %f
", dMSE, dPSNR);
121     calculateGrayImgsPSNR(src, dst_nine_gaussian, dMSE, dPSNR);
122     printf("source image & 9*9 GAUSSIAN: MSE: %f	PSNR: %f
", dMSE, dPSNR);
123     calculateGrayImgsPSNR(src, dst_eleven_gaussian, dMSE, dPSNR);
124     printf("source image & 11*11 GAUSSIAN: MSE: %f	PSNR: %f
", dMSE, dPSNR);
125 
126     // part b
127     puts("---------------------------
");
128     calculateGrayImgsPSNR(src, dst_eleven_gaussian, dMSE, dPSNR);
129     printf("source image & eleven: MSE: %f	PSNR: %f
", dMSE, dPSNR);
130     calculateGrayImgsPSNR(src, dst_twice_five_gaussian, dMSE, dPSNR);
131     printf("source image & twice five: MSE: %f	PSNR: %f
", dMSE, dPSNR);
132     calculateGrayImgsPSNR(dst_eleven_gaussian, dst_twice_five_gaussian, dMSE, dPSNR);
133     printf("eleven & twice five: MSE: %f	PSNR: %f
", dMSE, dPSNR);
134 
135     cvWaitKey(0);
136     cvReleaseImage(&src);
137     cvReleaseImage(&dst_three_gaussian);
138     cvReleaseImage(&dst_five_gaussian);
139     cvReleaseImage(&dst_nine_gaussian);
140     cvReleaseImage(&dst_eleven_gaussian);
141     cvReleaseImage(&dst_twice_five_gaussian);
142     cvDestroyAllWindows();
143 
144     return 0;
145 }

运行结果:

a部分:

3*3:

5*5:

9*9:

11*11:

同时各个不同的窗口大小模糊化后的图像与原始图像之间的MSE与PSNR:

从图中可以看出,当窗口大小越大时,MSE增大,PSNR减小。

b部分:

两幅图像的PSNR与MSE:

众所周知的是在图像压缩中典型的PSNR比值在30-40dB之间,而我们这两幅平滑之后的图像PSNR为31.976534,所以这两幅图像是比较接近的。

原文地址:https://www.cnblogs.com/qdsclove/p/3366907.html