函数原型
方框滤波 void boxFilter(InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor = Point(-1,-1), bool normalize = true, int borderType = BORDER_DEFAULT) 均值滤波 void blur(Input src, OutputArray dst, Size ksize, Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT) 高斯滤波 void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT) 中值滤波 void medianBlur(InputArray src, OutputArray dst, int ksize) 双边滤波 void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT)
具体参数解析
InputArray src: 输入图像(源图像),Mat类型对象,图像深度应该是CV_8U、CV_16U、CV_16S、CV_32F、CV_64F之一。 而对于中值滤波而言,如果ksize为3或者5时,图像深度必须是CV_8U、CV_16U、CV_32F之一,如果孔径较大,则只能是CV_8U。 OutputArray dst: 输出图像(目标图像),和源图像的尺寸和类型均一样。 int ddepth: 输出图像的深度,-1表示原图像深度(即src.depth())。 Size ksize: 内核大小,用Size(w,h)来表示,w和h分别表示宽和高。 Point anchor: 锚点,也就是被平滑的点,如果该点坐标为负值表示取核的中心,因此默认的(-1,-1)就表示锚点在核中心。 bool normalize: 标识符,为true时表示内核被其余区域归一化(normalized)了。 int borderType: 推断图像外部像素的某种边界模式。 double sigmaX: 表示高斯核函数在X方向的标准偏差。 double sigmaY: 表示高斯核函数在Y方向的标准偏差。 当sigmaY为0时,就将其设为sigmaX;如果两者均为0,则由ksize.with和ksize.height计算出来, 因此在高斯滤波函数中,ksize的w和h均必须是正数和奇数,或0,两者可以不同。 int ksize: 孔径的线性空间,必须是大于1的奇数。 int d: 过滤过程中每个像素邻域的直径,如果其值为非正数,则该值由sigmaSpace计算出来。 double sigmaColor: 颜色空间滤波器的sigma值,这个参数的值越大,就表明该像素邻域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域。 double sigmaSpace: 坐标空间中滤波器的sigma值,坐标空间的标注方差。它的数值越大,意味着越远的像素会相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。 当d>0时,d制定了邻域大小与sigmaSpace无关。否则,d正比于sigmaSpace。
代码如下:
#include <iostream> #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> using namespace std; using namespace cv; Mat g_srcImage; // 全局的源图像 // 分别对应全局的方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波的输出图像以及内核值/参数值 Mat g_dstImgBox, g_dstImgBlur, g_dstImgGaussian, g_dstImgMedian, g_dstImgBilateral; int g_BoxFilterVal = 5; int g_BlurVal = 12; int g_GaussianBlurVal = 5; int g_MedianBlurVal = 12; int g_BilateralFilterVal = 12; static void on_BoxFilter(int, void *); static void on_Blur(int, void *); static void on_GaussianBlur(int, void *); static void on_MedianBlur(int, void *); static void on_BilateralFilter(int, void*); int main() { // 读取图像到g_srcImage g_srcImage = imread("E:\\VS2015Opencv\\vs2015\\project\\picture\\06.jpg"); if (!g_srcImage.data) { printf("读取的图片不存在…… \n"); return false; } // 分别克隆原图到5中滤波所需的图像中,均为Mat类型 g_dstImgBox = g_srcImage.clone(); g_dstImgBlur = g_srcImage.clone(); g_dstImgGaussian = g_srcImage.clone(); g_dstImgMedian = g_srcImage.clone(); g_dstImgBilateral = g_srcImage.clone(); // 显示原图 namedWindow("【原图】", 1); imshow("【原图】", g_srcImage); // 方框滤波 namedWindow("【方框滤波】", 1); createTrackbar("内核值", "【方框滤波】", &g_BoxFilterVal, 30, on_BoxFilter); on_BoxFilter(g_BoxFilterVal, 0); namedWindow("【均值滤波】", 1); createTrackbar("内核值", "【均值滤波】", &g_BlurVal, 30, on_Blur); on_Blur(g_BlurVal, 0); namedWindow("【高斯滤波】", 1); createTrackbar("内核值", "【高斯滤波】", &g_GaussianBlurVal, 30, on_GaussianBlur); on_GaussianBlur(g_GaussianBlurVal, 0); namedWindow("【中值滤波】", 1); createTrackbar("内核值", "【中值滤波】", &g_MedianBlurVal, 30, on_MedianBlur); on_MedianBlur(g_MedianBlurVal, 0); namedWindow("【双边滤波】", 1); createTrackbar("内核值", "【双边滤波】", &g_BilateralFilterVal, 30, on_BilateralFilter); on_BilateralFilter(g_BilateralFilterVal, 0); cout << "按下“q”键时,程序退出……\n"; while (char(waitKey(1)) != 'q') {} return 0; } static void on_BoxFilter(int, void *) { boxFilter(g_srcImage, g_dstImgBox, -1, Size(g_BoxFilterVal + 1, g_BoxFilterVal + 1)); imshow("【方框滤波】", g_dstImgBox); } static void on_Blur(int, void *) { blur(g_srcImage, g_dstImgBlur, Size(g_BlurVal + 1, g_BlurVal + 1), Point(-1, -1)); imshow("【均值滤波】", g_dstImgBlur); } static void on_GaussianBlur(int, void *) { GaussianBlur(g_srcImage, g_dstImgGaussian, Size(g_GaussianBlurVal * 2 + 1, g_GaussianBlurVal * 2 + 1), 0, 0); imshow("【高斯滤波】", g_dstImgGaussian); } static void on_MedianBlur(int, void *) { medianBlur(g_srcImage, g_dstImgMedian, g_MedianBlurVal * 2 + 1); imshow("【中值滤波】", g_dstImgMedian); } static void on_BilateralFilter(int, void*) { bilateralFilter(g_srcImage, g_dstImgBilateral, g_BilateralFilterVal, g_BilateralFilterVal * 2, g_BilateralFilterVal / 2); imshow("【双边滤波】", g_dstImgBilateral); }
加入噪声
#include <iostream> #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> #include<ctime> using namespace std; using namespace cv; Mat g_srcImage; // 全局的源图像 // 分别对应全局的方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波的输出图像以及内核值/参数值 Mat g_dstImgBox, g_dstImgBlur, g_dstImgGaussian, g_dstImgMedian, g_dstImgBilateral; int g_BoxFilterVal = 5; int g_BlurVal = 12; int g_GaussianBlurVal = 5; int g_MedianBlurVal = 12; int g_BilateralFilterVal = 12; static void on_BoxFilter(int, void *); static void on_Blur(int, void *); static void on_GaussianBlur(int, void *); static void on_MedianBlur(int, void *); static void on_BilateralFilter(int, void*); //图像椒盐化 void salt(Mat &image, int num) { if (!image.data) return;//防止传入空图 int i, j; srand(time(NULL)); for (int x = 0; x < num; ++x) { i = rand() % image.rows; j = rand() % image.cols; image.at<Vec3b>(i, j)[0] = 255; image.at<Vec3b>(i, j)[1] = 255; image.at<Vec3b>(i, j)[2] = 255; } } int main() { // 读取图像到g_srcImage Mat image = imread("E:\\VS2015Opencv\\vs2015\\project\\picture\\06.jpg"); if (!image.data) { printf("读取的图片不存在…… \n"); return false; } image.copyTo(g_srcImage); salt(g_srcImage, 3000); // 分别克隆原图到5中滤波所需的图像中,均为Mat类型 g_dstImgBox = g_srcImage.clone(); g_dstImgBlur = g_srcImage.clone(); g_dstImgGaussian = g_srcImage.clone(); g_dstImgMedian = g_srcImage.clone(); g_dstImgBilateral = g_srcImage.clone(); // 显示原图 namedWindow("【原图】", 1); imshow("【原图】", g_srcImage); // 方框滤波 namedWindow("【方框滤波】", 1); createTrackbar("内核值", "【方框滤波】", &g_BoxFilterVal, 30, on_BoxFilter); on_BoxFilter(g_BoxFilterVal, 0); namedWindow("【均值滤波】", 1); createTrackbar("内核值", "【均值滤波】", &g_BlurVal, 30, on_Blur); on_Blur(g_BlurVal, 0); namedWindow("【高斯滤波】", 1); createTrackbar("内核值", "【高斯滤波】", &g_GaussianBlurVal, 30, on_GaussianBlur); on_GaussianBlur(g_GaussianBlurVal, 0); namedWindow("【中值滤波】", 1); createTrackbar("内核值", "【中值滤波】", &g_MedianBlurVal, 30, on_MedianBlur); on_MedianBlur(g_MedianBlurVal, 0); namedWindow("【双边滤波】", 1); createTrackbar("内核值", "【双边滤波】", &g_BilateralFilterVal, 30, on_BilateralFilter); on_BilateralFilter(g_BilateralFilterVal, 0); cout << "按下“q”键时,程序退出……\n"; while (char(waitKey(1)) != 'q') {} return 0; } static void on_BoxFilter(int, void *) { boxFilter(g_srcImage, g_dstImgBox, -1, Size(g_BoxFilterVal + 1, g_BoxFilterVal + 1)); imshow("【方框滤波】", g_dstImgBox); } static void on_Blur(int, void *) { blur(g_srcImage, g_dstImgBlur, Size(g_BlurVal + 1, g_BlurVal + 1), Point(-1, -1)); imshow("【均值滤波】", g_dstImgBlur); } static void on_GaussianBlur(int, void *) { GaussianBlur(g_srcImage, g_dstImgGaussian, Size(g_GaussianBlurVal * 2 + 1, g_GaussianBlurVal * 2 + 1), 0, 0); imshow("【高斯滤波】", g_dstImgGaussian); } static void on_MedianBlur(int, void *) { medianBlur(g_srcImage, g_dstImgMedian, g_MedianBlurVal * 2 + 1); imshow("【中值滤波】", g_dstImgMedian); } static void on_BilateralFilter(int, void*) { bilateralFilter(g_srcImage, g_dstImgBilateral, g_BilateralFilterVal, g_BilateralFilterVal * 2, g_BilateralFilterVal / 2); imshow("【双边滤波】", g_dstImgBilateral); }