【练习5.1】使用cvSmooth实现不同平滑处理方法的效果以及不同的平滑窗口对处理效果的影响

《学习OpenCV》中文版第5章第1题

提纲
题目要求
a程序代码
b程序代码
a结果图片
b结果图片 
c优势对比

 

 

 

 

 

 

题目要求:

注:相对书中的要求有扩充、调整

载入一个带有有趣纹理的图像。

a、使用cvSmooth函数以多种方法平滑图像

b、用5×5高斯滤波器平滑图像两次和用两个11×11平滑器平滑一次的输出结果是接近相同的吗?为什么?

c、对比不同平滑方法的处理效果,并查阅资料,找出处理效果的不同及各自的优势

 

a程序代码:

 

  1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点。
  2 //
  3 //D:\\Work\\Work_Programming\\Source\\Image\\lena.jpg
  4 
  5 
  6 #include "stdafx.h"
  7 #include <cv.h>
  8 #include <highgui.h>
  9 #include <iostream>
 10 using namespace cv;
 11 using namespace std;
 12 //函数声明-->--->-->--->-->--->-->--->//
 13 
 14  
 15 
 16 //<--<--<--<--<--<--<--<--<--函数声明//
 17 
 18 int _tmain(int argc, _TCHAR* argv[])
 19 {
 20     const char * fileName = "D:\\Work\\Work_Programming\\Source\\Image\\纹理\\纹理_灰度.jpg";    
 21 
 22     IplImage * img = cvLoadImage(fileName, CV_LOAD_IMAGE_UNCHANGED);    
 23     assert(img);
 24     
 25     IplImage * dst = cvCloneImage(img);
 26     //dst->origin = img->origin;
 27     cvZero(dst); 
 28 
 29     cvNamedWindow("ExerciseWindow", 0);    
 30     cvNamedWindow("简单模糊", 0);
 31     cvNamedWindow("简单无缩放模糊", 0);
 32     cvNamedWindow("中值滤波器模糊", 0);
 33     cvNamedWindow("高斯模糊", 0);
 34     cvNamedWindow("双边滤波", 0);
 35 
 36     cvShowImage("ExerciseWindow", img);
 37 
 38     //---------------------------简单模糊:开始--------------------------------//
 39     
 40     cvSmooth(img, dst, CV_BLUR, 5);
 41 
 42     /*int i = 0;
 43     while (i<5)
 44     {
 45         cvSmooth(dst, dst, CV_BLUR, 5);
 46         i++;
 47     }*/
 48     cvShowImage("简单模糊", dst);
 49 
 50 
 51     //---------------------------简单模糊:结束--------------------------------//        
 52      
 53     //---------------------------简单无缩放模糊:开始--------------------------------//
 54 
 55     //注意:使用CV_BLUR_NO_SCALE平滑类型,输入图像和输出图像必须有不同的数据精度
 56     IplImage * blur_NO_Scale = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_16S, img->nChannels);
 57     blur_NO_Scale->origin = img->origin;
 58     cvZero(blur_NO_Scale); 
 59 
 60     cvSmooth(img, blur_NO_Scale, CV_BLUR_NO_SCALE, 5);
 61  
 62     cvShowImage("简单无缩放模糊", blur_NO_Scale);
 63 
 64     //---------------------------简单无缩放模糊:结束--------------------------------//    
 65 
 66     //---------------------------中值滤波器:开始--------------------------------//
 67 
 68     //注意:CV_MEDIAN平滑类型不支持in place方式
 69     IplImage * image_Median = cvCloneImage(img);
 70     cvZero(image_Median);
 71 
 72     cvSmooth(img, image_Median, CV_MEDIAN, 5);
 73 
 74     cvShowImage("中值滤波器模糊", image_Median);
 75 
 76     //---------------------------中值滤波器:结束--------------------------------//    
 77 
 78     //---------------------------高斯模糊:开始--------------------------------//
 79 
 80     IplImage * image_Gauss = cvCloneImage(img);
 81     cvZero(image_Gauss);
 82 
 83     cvSmooth(img, image_Gauss, CV_GAUSSIAN, 5,5,3,3);
 84 
 85     cvShowImage("高斯模糊", image_Gauss);
 86 
 87     //---------------------------高斯模糊:结束--------------------------------//    
 88 
 89     //---------------------------双边滤波:开始--------------------------------//
 90 
 91     //特别注意:CV_BILATERAL平滑类型的输入和输出图像必须是8u,也就是灰度图
 92     //因该平滑类型不支持in place方式,故多次平滑时注意增加临时图像
 93 
 94     /*IplImage * img_Gray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
 95     IplImage * image_BIL = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
 96     cvCvtColor(img, img_Gray, CV_BGR2GRAY);*/
 97     IplImage * image_BIL = cvCloneImage(img);
 98 
 99     IplImage * temp_image = cvCloneImage(img);
100     cvZero(temp_image);
101      
102     cvSmooth(img, temp_image, CV_BILATERAL, 3, 3, 11, 11);
103 
104     int j = 0;
105     while (j<100)
106     {
107         //注意:使用CV_BILATERAL平滑类型时cvSmooth参数中的最后两个11
108         cvSmooth(temp_image, image_BIL, CV_BILATERAL, 7, 7, 11, 11);
109         //cvSmooth(temp_image, image_BIL, CV_BILATERAL, 3, 3);
110 
111         cvCopyImage(image_BIL, temp_image);
112         j++;
113     }
114 
115     //cvSmooth(img, image_BIL, CV_BILATERAL, 3, 3,11,11);
116 
117     cvShowImage("双边滤波", image_BIL);
118 
119     //---------------------------双边滤波:结束--------------------------------//    
120 
121     cvWaitKey(0);
122 
123     cvReleaseImage(&img);
124     cvReleaseImage(&dst);
125     cvReleaseImage(&blur_NO_Scale);
126     cvReleaseImage(&image_Median);
127     cvReleaseImage(&image_Gauss);
128     cvReleaseImage(&image_BIL);
129 
130     cvDestroyWindow("ExerciseWindow");     
131     cvDestroyWindow("简单模糊"); 
132     cvDestroyWindow("简单无缩放模糊");
133     cvDestroyWindow("中值滤波器模糊");
134     cvDestroyWindow("高斯模糊");
135     cvDestroyWindow("双边滤波");
136 
137     return 0;
138 }
139  

 

a结果图片

 

b程序代码:

 1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点。
 2 //
 3 //D:\\Work\\Work_Programming\\Source\\Image\\lena.jpg
 4 
 5 
 6 #include "stdafx.h"
 7 #include <cv.h>
 8 #include <highgui.h>
 9 #include <iostream>
10 using namespace cv;
11 using namespace std;
12 //函数声明-->--->-->--->-->--->-->--->//
13 
14  
15 
16 //<--<--<--<--<--<--<--<--<--函数声明//
17 
18 int _tmain(int argc, _TCHAR* argv[])
19 {
20     const char * fileName = "D:\\Work\\Work_Programming\\Source\\Image\\纹理\\纹理_灰度.jpg";    
21     //const char * fileName = "D:\\Work\\Work_Programming\\Source\\Image\\Photoshop\\样图.jpg";    
22 
23     IplImage * img = cvLoadImage(fileName, CV_LOAD_IMAGE_UNCHANGED);    
24     assert(img);
25      
26     cvNamedWindow("ExerciseWindow", 0);    
27     cvNamedWindow("高斯模糊5×5两次", 0);
28     cvNamedWindow("高斯模糊11×11", 0);
29 
30     cvShowImage("ExerciseWindow", img);
31     
32      
33     //---------------------------简单无缩放模糊:开始--------------------------------//
34 
35     IplImage * image_Gauss = cvCloneImage(img);
36     cvZero(image_Gauss);
37 
38     cvSmooth(img, image_Gauss, CV_GAUSSIAN, 5, 5);
39     cvSmooth(image_Gauss, image_Gauss, CV_GAUSSIAN, 5, 5);
40 
41     cvShowImage("高斯模糊5×5两次", image_Gauss);
42 
43     //---------------------------简单无缩放模糊:结束--------------------------------//    
44 
45 
46     //---------------------------双边滤波:开始--------------------------------//
47 
48     IplImage * image_Gauss_11 = cvCloneImage(img);
49     cvZero(image_Gauss_11);
50 
51     cvSmooth(img, image_Gauss_11, CV_GAUSSIAN, 11, 11);
52 
53     cvShowImage("高斯模糊11×11", image_Gauss_11);
54 
55     //---------------------------双边滤波:结束--------------------------------//    
56 
57     cvWaitKey(0);
58 
59     cvReleaseImage(&img);
60     cvReleaseImage(&image_Gauss);
61     cvReleaseImage(&image_Gauss_11);
62 
63 
64     cvDestroyWindow("ExerciseWindow");     
65     cvDestroyWindow("高斯模糊5×5两次");
66     cvDestroyWindow("高斯模糊11×11");
67 
68     return 0;
69 }
70  

 

b结果图片

二者效果接近,原理待究

c优势对比: 

高斯滤波:

适合对象:真实图像在空间内的像素是缓慢变化的,因此临近点的像素编号不会很明显。但是随即的两个点就可能形成很大的像素差(也就是说空间上噪声点不是相互联系的)

优点:高斯滤波在保留信号的条件下减少噪声

缺点:这种方法在接近边缘就无效了,在那儿你不希望像素与相邻像素相关。因此高斯滤波会磨平边缘。

 

双边滤波:

优点:双边滤波能够提供一种不会将边缘平滑掉的方法。但作为代价,需要更多的处理时间。测试过程中,双边滤波耗时比其他方法明显多。

原理简记:可以将双边滤波视为高斯平滑,对相似的像素赋予较高的权重,不相似的像素赋予较小的权重。

适用对象:可用于图像分割

注意事项:仅适用于8u类型

其它:从上面双边滤波对原始图像处理100次的效果来看,高斯滤波对于孤立的小的噪声点去噪明显,当然这有待理论支持

 

简单无缩放模糊

注意事项:输入图像和结果图像必须有不同的数值精度

 

中值滤波

原理简记:中值滤波器将中心像素的正方形邻域内的每个像素值用中间像素值(不是平均像素值)替换。

优点:基于平均算法的simple blur对噪声图像特别是大的孤立点(有时被称为"镜头噪声")的图像非常敏感,即使有极少数量点存在较大差异也会导致平均值的明显波动,中值滤波可以通过选择中间值避免这些点的影响。

其它:从处理效果看,中值滤波器对消除纹理效果明显。有待理论支持

posted on 2015-04-14 22:18  毋忆典藏  阅读(951)  评论(0编辑  收藏  举报