专栏首页程序员OpenCV线性滤波(均值滤波,方框滤波,高斯滤波)

OpenCV线性滤波(均值滤波,方框滤波,高斯滤波)

OpenCV中提供了三种常用的线性滤波函数,它们分别是方框滤波,均值滤波和高斯滤波。

均值滤波

均值滤波从频域来看,它是一种低通滤波器,高频信号会被滤掉。均值滤波可以帮助消除图像尖锐噪声,实现图像平滑,模糊等功能。理想的均值滤波是用每个像素和它周围像素计算出来的平均值替换图像中每个像素。

均值滤波器一般是使用下面的模板和图像做卷积来实现。

即以当前像素点为中心,求窗口内所有灰度值的和,以其平均值作为中心像素新的灰度值。

均值滤波有平均均值滤波和加权均值滤波。分别如下所示:

左边是平均均值滤波 右边是加权均值滤波

均值滤波可以模糊图像从而得到图像的大致描述。

方框滤波

方框滤波和均值滤波的原理是类似的,因为均值滤波是方框滤波的归一化表现。在OpenCV中,方框滤波使用的模板如下:

从方框滤波的模板可以看到,如果α = 1,那么就是方框滤波,不进行归一化;如果α != 1那么就进行归一化操作。

以5*5的卷积核为例,如果normalize == true,那么就是均值滤波,模板如下:

如果normalize != true,那么就是计算邻域像素和,不平均,卷积核如下:

高斯滤波

百度百科是这样介绍高斯滤波的,很清晰明了。

高斯滤波是一种线性平滑滤波,适用于消除高斯噪声(高斯噪声是指它的概率密度函数服从高斯分布(即正态分布)的一类噪声)。高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

一维高斯分布

通常我们在使用的时候都取标准正态分布。这时候

以3*3的模板为例,给出高斯滤波的卷积核

从卷积核可以看到,每一个像素点的权值不是全部相同的。更突出了中心点在像素平滑后的权重,相比于均值滤波而言,有着更好的平滑效果。

介绍完了方框滤波,均值滤波和高斯滤波的原理之后,我们来看看OpenCV提供的实现滤波的API。

filter2D函数

首先介绍filter2D函数,这个函数需要给出卷积核即可实现各种滤波操作。

//filter2D函数原型
void filter2D( InputArray src, OutputArray dst, int ddepth,
                            InputArray kernel, Point anchor = Point(-1,-1),
                            double delta = 0, int borderType = BORDER_DEFAULT );

参数1:输入图像

参数2:输出图像

参数3:图像深度(指存储每个像素所用的位数),如果没写将生成与原图像深度相同的图像。当ddepth输入值为-1时,目标图像和原图像深度保持一致。

参数4:卷积核

参数5:卷积基准点(默认值为Point(-1,-1)表示取卷积中心即锚点)。

参数6:在储存目标图像前可选的添加到像素的值,默认值为0。一般不用

参数7: 像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。

boxFilter函数

//boxFilter函数原型
void boxFilter( InputArray src, OutputArray dst, int ddepth,
                             Size ksize, Point anchor = Point(-1,-1),
                             bool normalize = true,
                             int borderType = BORDER_DEFAULT );

参数1:输入图像;

参数2:输出图像;

参数3:图像深度(指存储每个像素所用的位数),如果没写将生成与原图像深度相同的图像。当ddepth输入值为-1时,目标图像和原图像深度保持一致。

参数4:Size类型的ksize,卷积核的大小。一般这样写Size( w,h )来表示卷积核的大小( 其中,w 为像素宽度, h为像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表示5x5的核大小;

参数5:卷积基准点(默认值为Point(-1,-1)表示取卷积中心即锚点)。

参数6:默认值为true,根据上面讲述的原理,也就是默认归一化。

参数7: 像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。

blur函数

//blur函数原型
void blur( InputArray src, OutputArray dst,
                        Size ksize, Point anchor = Point(-1,-1),
                        int borderType = BORDER_DEFAULT );

参数1:输入图像;

参数2:输出图像;

参数3:卷积核的大小;

参数4:卷积基准点(默认值为Point(-1,-1)表示取卷积中心即锚点)。

参数5: 像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。

GaussianBlur函数

//GaussianBlur函数原型
void GaussianBlur( InputArray src, OutputArray dst, Size ksize,
                                double sigmaX, double sigmaY = 0,
                                int borderType = BORDER_DEFAULT );

参数1:输入图像;

参数2:输出图像;

参数3:卷积核的大小;

参数4:表示高斯核函数在X方向的的标准偏差;

参数5:表示高斯核函数在Y方向的的标准偏差;如果sigmaY为零,则将其设置为等于sigmaX;如果两个都为零,则分别从ksize.width和ksize.height计算得出sigmaX和sigmaY;

参数6:像素向外逼近的方法,默认值是BORDER_DEFAULT,即对全部边界进行计算。

到此为止,需要用到的函数以及全部介绍完毕了。下面来看看实际的代码使用情况。

#include<opencv2/opencv.hpp>

using namespace cv;

int main()
{
	//使用boxFilter函数实现方框滤波
	Mat src1 = imread("C:/Users/zhou_/Desktop/1.jpg");
	Mat dst1(src1.size(), src1.type());
	if (!src1.data)
	{
		perror("load failed:");
		exit(-1);
	}
	imshow("src1", src1);

	boxFilter(src1, dst1, -1, Size(3, 3), Point(-1, -1));

	imshow("方框滤波", dst1);

	//同时,我们使用filter2D函数来实现模板是3*3的均值滤波
	Mat dst11;
	Mat kernel = (Mat_<double>(3, 3) << \
		1, 1, 1, \
		1, 1, 1, \
		1, 1, 1);

	kernel /= 9;		//归一化变换核,保持图像亮度不变

	filter2D(src1, dst11, -1, kernel);
	imshow("使用filter2D实现均值滤波", dst11);

	//均值滤波是方框滤波归一化后的特殊情形
	Mat blurresult;
	blur(src1, blurresult, Size(3, 3));

	imshow("使用blur实现均值滤波", blurresult);

	//高斯滤波
	Mat dst2;
	GaussianBlur(src1, dst2, Size(3, 3), 0, 0);

	imshow("使用GaussianBlur实现高斯滤波", dst2);

	Mat dst22;
	kernel = (Mat_<double>(3, 3) << \
		1, 2, 1, \
		2, 4, 2, \
		1, 2, 1);
	kernel /= 16;

	filter2D(src1, dst22, -1, kernel);
	imshow("使用filter2D实现高斯滤波", dst22);
	
	waitKey(0);
	return 0;
}

结果如下所示:

可以看到使用filter2D函数和Blur函数实现的效果是一样的。另外当方框滤波的卷积核大小和均值滤波一致并且归一化时,两者的效果也是一样的,所以上面三幅图像处理的效果时相同的。

使用filter2D和GaussianBlur的结果也是一样的。

另外,也可以看到均值滤波对于图像的模糊程度比高斯滤波要严重。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • OpenCV中值滤波

    在数字图像处理常见的变换核及其用途中,已经说明了线性滤波。线性滤波是算术运算,有固定的模板,即:变换核。

    zy010101
  • 数字图像处理中常见的变换核及其用途

    图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性...

    zy010101
  • OpenCV加载,修改,保存图片

    常见用法:namedWindow("Window Title",WINDOW_AUTOSIZE);

    zy010101
  • Side Window Filtering 论文解读和C++实现

    刚开始看到这篇论文的时候,我就很感兴趣想去复现一把看看效果。这篇论文是今年 CVPR oral 且不是深度学习方向的,其核心贡献点就是:不管原来的滤波器保不保边...

    Ldpe2G
  • Side Window Filtering 论文解读和C++实现 转

    不管原来的滤波器保不保边,运用了side-window思想之后,都可以让它变成保边滤波!

    Ldpe2G
  • 详解图像滤波原理及实现!

    图像的实质是一种二维信号,滤波是信号处理中的一个重要概念。在图像处理中,滤波是一常见的技术,它们的原理非常简单,但是其思想却十分值得借鉴,滤波是很多图像算法的前...

    Datawhale
  • opencv中滤波函数的介绍和应用

    滤波作用 图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪 声(包括高斯噪声、椒盐、噪声、随机噪声等)进行抑制,是图像预 处理中不可缺少的操作,其处理效...

    zls365
  • 【AI移动端算法优化】一,CVRR 2018 Side Window Filtering 论文解读和C++实现

    刚开始看到这篇论文的时候,我就很感兴趣想去复现一把看看效果。这篇论文是今年 CVPR oral 且不是深度学习方向的,其核心贡献点就是:不管原来的滤波器保不保边...

    BBuf
  • Math-Model算法综述

    数学建模主要模型不单独写,参考数学模型第四版教材即可,只给出编程中一些重要的算法目录,如果有方法漏写,请评论区指出,笔者添加,谢谢QAQ

    Pulsar-V
  • 【技术综述】一文道尽传统图像降噪方法

    图像预处理算法的好坏直接关系到后续图像处理的效果,如图像分割、目标识别、边缘提取等,为了获取高质量的数字图像,很多时候都需要对图像进行降噪处理,尽可能的保持原始...

    用户1508658

扫码关注云+社区

领取腾讯云代金券