《学习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。

代码:

#include <opencv/highgui.h>
#include <opencv/cv.h>
#include <opencv_libs.h>
#include <math.h>

/*
 *《学习OpenCV》第五章第一题  
 * 完成时间:18:37 10/13 星期日 2013  
 * 作者:qdsclove@163.com
 */

/*
 * function: calculate MSE & PSNR of two GrayScale(8-bit depth & one channel) images.
 * param: img1 -- the first image.
 * param: img2 -- the second image.
 * param: dMSE -- the MSE of two images(output)
 * param: dPSNR -- the PSNR of two images(output)
 * return: 0 -- success;  others -- failed.
 */
int calculateGrayImgsPSNR(IplImage* img1, IplImage* img2, double& dMSE, double& dPSNR)
{
    if( !img1 || !img2 || 
        img1->nChannels != 1 ||
        img2->nChannels != 1 || 
        img1->depth != img2->depth ||
        img1->width != img2->width || 
        img1->height != img2->height )
    {
        return -1;
    }
    int width = img1->width;
    int height = img1->height;

    // calculate MSE of the two images
    double dSumOfSquares = 0;
    for(int i = 0; i < height; i++)
    {
        char* pdata1 = img1->imageData + i * img1->widthStep;
        char* pdata2 = img2->imageData + i *img2->widthStep;
        for(int j = 0; j < width; j++ )
        {
            uchar value1 = *(pdata1 + j);
            uchar value2 = *(pdata2 + j);

            double square = pow( (double)(value1 - value2), 2 );
            dSumOfSquares += square;
        }
    }

    dMSE = dSumOfSquares / (width * height);

    // this is means the two images are strictly same. 
    if(dMSE == 0)
    {
        dPSNR = -1;
        return 0;
    }
    int iDepth = img1->depth;
    int iMAX = pow( 2., iDepth) - 1;

    dPSNR = 20 * log10(iMAX / (sqrt(dMSE)));

    return 0;
}

int main()
{
    const char * FILE_PATH = "Fig0333(a)(test_pattern_blurring_orig).tif";

    IplImage* src = cvLoadImage(FILE_PATH, CV_LOAD_IMAGE_UNCHANGED);

    if(!src)
    {
        printf("Load image error.\n");
        return -1;
    }

    // Get the source image's size
    CvSize srcSize = cvGetSize(src);

    // 3 * 3
    IplImage* dst_three_gaussian = cvCreateImage(srcSize, src->depth, src->nChannels);
    // 5 * 5
    IplImage* dst_five_gaussian = cvCreateImage(srcSize, src->depth, src->nChannels);
    // 9 * 9
    IplImage* dst_nine_gaussian = cvCreateImage(srcSize, src->depth, src->nChannels);
    // 11 * 11
    IplImage* dst_eleven_gaussian = cvCreateImage(srcSize, src->depth, src->nChannels);
    // twice 5 * 5
    IplImage* dst_twice_five_gaussian = cvCreateImage( srcSize, src->depth, src->nChannels );


    if( !dst_three_gaussian || !dst_five_gaussian ||
        !dst_nine_gaussian || !dst_eleven_gaussian ||
        !dst_twice_five_gaussian )
    {
        printf("Create image error.\n");
        return -1;
    }

    cvSmooth(src, dst_three_gaussian, CV_GAUSSIAN, 3, 3);
    cvSmooth(src, dst_five_gaussian, CV_GAUSSIAN, 5, 5);
    cvSmooth(src, dst_nine_gaussian, CV_GAUSSIAN, 9, 9);
    cvSmooth(src, dst_eleven_gaussian, CV_GAUSSIAN, 11, 11);
    cvSmooth( dst_five_gaussian, dst_twice_five_gaussian, CV_GAUSSIAN, 5, 5 );

    cvShowImage("src", src);
    cvShowImage("src - GAUSSIAN 3*3", dst_three_gaussian);
    cvShowImage("src - GAUSSIAN 5*5", dst_five_gaussian);
    cvShowImage("src - GAUSSIAN 9*9", dst_nine_gaussian);
    cvShowImage("src - GAUSSIAN 11*11", dst_eleven_gaussian);
    cvShowImage("src - GAUSSIAN 5*5 Twice", dst_twice_five_gaussian );

    // calculate the MSE and PSNR of the two images.
    double dMSE, dPSNR;
    // part a:
    calculateGrayImgsPSNR(src, dst_three_gaussian, dMSE, dPSNR);
    printf("source image & 3*3 GAUSSIAN: MSE: %f\tPSNR: %f\n", dMSE, dPSNR);
    calculateGrayImgsPSNR(src, dst_five_gaussian, dMSE, dPSNR);
    printf("source image & 5*5 GAUSSIAN: MSE: %f\tPSNR: %f\n", dMSE, dPSNR);
    calculateGrayImgsPSNR(src, dst_nine_gaussian, dMSE, dPSNR);
    printf("source image & 9*9 GAUSSIAN: MSE: %f\tPSNR: %f\n", dMSE, dPSNR);
    calculateGrayImgsPSNR(src, dst_eleven_gaussian, dMSE, dPSNR);
    printf("source image & 11*11 GAUSSIAN: MSE: %f\tPSNR: %f\n", dMSE, dPSNR);

    // part b
    puts("---------------------------\n");
    calculateGrayImgsPSNR(src, dst_eleven_gaussian, dMSE, dPSNR);
    printf("source image & eleven: MSE: %f\tPSNR: %f\n", dMSE, dPSNR);
    calculateGrayImgsPSNR(src, dst_twice_five_gaussian, dMSE, dPSNR);
    printf("source image & twice five: MSE: %f\tPSNR: %f\n", dMSE, dPSNR);
    calculateGrayImgsPSNR(dst_eleven_gaussian, dst_twice_five_gaussian, dMSE, dPSNR);
    printf("eleven & twice five: MSE: %f\tPSNR: %f\n", dMSE, dPSNR);

    cvWaitKey(0);
    cvReleaseImage(&src);
    cvReleaseImage(&dst_three_gaussian);
    cvReleaseImage(&dst_five_gaussian);
    cvReleaseImage(&dst_nine_gaussian);
    cvReleaseImage(&dst_eleven_gaussian);
    cvReleaseImage(&dst_twice_five_gaussian);
    cvDestroyAllWindows();

    return 0;
}

运行结果:

a部分:

3*3:


5*5:


9*9:


11*11:


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


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

b部分:


两幅图像的PSNR与MSE:


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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值