《学习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对噪声图像特别是大的孤立点(有时被称为"镜头噪声")的图像非常敏感,即使有极少数量点存在较大差异也会导致平均值的明显波动,中值滤波可以通过选择中间值避免这些点的影响。
其它:从处理效果看,中值滤波器对消除纹理效果明显。有待理论支持