【练习5.1】使用cvSmooth实现不同平滑处理方法的效果以及不同的平滑窗口对处理效果的影响
《学习OpenCV》中文版第5章第1题
题目要求 |
a程序代码 |
b程序代码 |
a结果图片 |
b结果图片 |
c优势对比 |
注:相对书中的要求有扩充、调整
载入一个带有有趣纹理的图像。
a、使用cvSmooth函数以多种方法平滑图像
b、用5×5高斯滤波器平滑图像两次和用两个11×11平滑器平滑一次的输出结果是接近相同的吗?为什么?
c、对比不同平滑方法的处理效果,并查阅资料,找出处理效果的不同及各自的优势
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
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
二者效果接近,原理待究
高斯滤波:
适合对象:真实图像在空间内的像素是缓慢变化的,因此临近点的像素编号不会很明显。但是随即的两个点就可能形成很大的像素差(也就是说空间上噪声点不是相互联系的)
优点:高斯滤波在保留信号的条件下减少噪声
缺点:这种方法在接近边缘就无效了,在那儿你不希望像素与相邻像素相关。因此高斯滤波会磨平边缘。
双边滤波:
优点:双边滤波能够提供一种不会将边缘平滑掉的方法。但作为代价,需要更多的处理时间。测试过程中,双边滤波耗时比其他方法明显多。
原理简记:可以将双边滤波视为高斯平滑,对相似的像素赋予较高的权重,不相似的像素赋予较小的权重。
适用对象:可用于图像分割
注意事项:仅适用于8u类型
其它:从上面双边滤波对原始图像处理100次的效果来看,高斯滤波对于孤立的小的噪声点去噪明显,当然这有待理论支持
简单无缩放模糊
注意事项:输入图像和结果图像必须有不同的数值精度
中值滤波
原理简记:中值滤波器将中心像素的正方形邻域内的每个像素值用中间像素值(不是平均像素值)替换。
优点:基于平均算法的simple blur对噪声图像特别是大的孤立点(有时被称为"镜头噪声")的图像非常敏感,即使有极少数量点存在较大差异也会导致平均值的明显波动,中值滤波可以通过选择中间值避免这些点的影响。
其它:从处理效果看,中值滤波器对消除纹理效果明显。有待理论支持
‖==========钟于原创 乐于分享 宁静致远 毋忆典藏==========‖