计算机视觉基础-图像滤波

一、前言

说到滤波,第一时间想到在数字通信中的信号滤波,通常在频率域处理连续信号可以滤除特定波段的频率,比如,允许通过低频信号通过而限制高频的低通滤波器,允许高频信号通过而限制低频的高通滤波器。而在数字图像处理中,由于图像是二维离散数字矩阵,所以一方面它不具有连续性,另一方面它是一个二维矩阵,那么图像滤波是怎么实现的呢?下面做出一些自己的整理和理解!

二、图像滤波概念与解析

2.1图像滤波概念

百度词条定义为:

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

也就是说,图像滤波是在尽可能的保留图像自身的细节特征的情况下对图像的噪声进行抑制,也即是平滑处理
其目的是:

  • 消除数字图像中的噪声点
  • 特征提取,后续操作的预处理

图像滤波可以根据处理域不同分为空间域滤波和频率域滤波,而空间域滤波和频率域滤波存在一一对应的关系,本文主要讲解最常用的空间域滤波处理。

2.2空域滤波

  空域滤波是在图像空间域中利用模板对图像领域操作,滤波后图像每一个像素的取值都是根据模板对输入像素相应邻域内的像素值进行计算得到的。空域滤波根据模板分为线性滤波和非线性滤波两类。

  • 线性滤波像素点是通过领域像素与模板运算后线性(加权)求和得到的,如:均值滤波、方框滤波和高斯滤波。
  • 非线性滤波像素点是通过领域像素与模板之间的序列或逻辑关系得到的,如:中值滤波、双边滤波。

一般来说,线性滤波器的设计常基于对傅立叶变换的分析,而非线性空域滤波器则一般直接对邻域进行操作。空间域滤波基本步骤:

  1. 将模板在图中移动遍历每一个像素,并将模板中心与图中某个像素位置重合;
  2. 将模板上的系数与模板对应的像素进行运算;
  3. 将模板区域运算后得到的像素值相加(或其他操作);
  4. 将3中运算结果赋给图中与模板中心对应位置的像素。

对于尺寸为 m ∗ n m*n mn的模板,线性滤波在图像中像素 ( x , y ) (x,y) x,y处的相应输出 g ( x , y ) g(x,y) g(x,y)的一般表达式如下:
在这里插入图片描述
上式中, w ( s , t ) w(s,t) w(s,t) f ( x + s , y + t ) f(x+s,y+t) f(x+s,y+t)分别为模板系数和模板对应像素,其中,为了保证唯一坐标 s s s t t t是整数,要求 m m m n n n是奇数。在一般情况下,线性滤波选取尺寸为奇数的正方形模板,如3×3。

  另外滤波模板对图像边界运算时,会超出图像范围,比如尺寸为m*n大小的滤波模板,当把模板中心对准图像最左上角值时,模板的行列(宽高)分别超出图像(m-1)/2、(n-1)/2个像素点,此时,可以通过边界扩充的方式解决模板越界的问题,将图像边界宽高通过零填充、复制等方式分别向外扩展(m-1)/2、(n-1)/2个像素即可,那么滤波后图像尺寸和原图尺寸大小就一致了!OpenCV中边界扩充通过copyMakeBorder()函数实现。

2.3方框(盒状)滤波

方框滤波是一种线性空域滤波器,作用是使用box模板来模糊一张图像,原理是指定一个XY的矩阵大小,目标像素的周围XY矩阵内的像素全部相加作为目标像素的值,方框滤波所用到的核如下:
在这里插入图片描述
其中, α α α
在这里插入图片描述
n o r m a l i z e = t r u e normalize=true normalize=true时,方框滤波也就成了均值滤波。也就是说均值滤波是方框滤波归一化后的特殊情况。归一化就是将要处理的量缩放到一定范围,比如(0,1),以便统一处理和直观量化,而非归一化的方框滤波用于计算每个像素邻域内的积分特性(方差、协方差,平方和等),比如光流法中用到的图像倒数的协方差矩阵。如果要在可变窗口中计算像素总和,可以使用integral()函数,也叫积分图函数

积分图实现原理:将计算某个矩阵像素间的和值运算转换为求矩阵对应边角点的求和差值运算。初始化一个起始数组S,数组D的每个值是该像素邻域内的像素和值,在求解某矩形块中的像素和时,只需要索引对应区域的位置存放的和值就可以完成计算,积分图的计算类似动态规划,且计算过程只用到加法所以实现速度快,其在区域求和,如图像滤波、特征提取中都有较多的应用

在OpenCV中使用函数boxFilter() 来实现方框滤波操作,其函数模型如下:

void boxFilter( Mat InputArray src,   //原始图像
				Mat OutputArray dst,   //目标图像
                int ddepth,    //目标图像的深度,-1表示原图深度:src.depth()       
                Size ksize,  //滤波模板尺寸
                Point anchor = Point(-1,-1),  //锚点(此刻被滤波处理的点)默认为内核中心
                bool normalize = true, //是否对模板归一化处理,默认为True
                int borderType = BORDER_DEFAULT  //扩展边界的类型,默认值BORDER_DEFAULT
                );

2.4均值滤波

  均值滤波是一种典型的线性滤波方法,输出图像的每一个像素点都是模板核覆盖邻域内所有像素的加权平均(所有模板系数全为1),即用一个点邻域内像素的平均灰度值来代替这个点的灰度值,也是方框滤波归一化后的结果。
尺寸为3×3的均值模板如下图所示,权系数全为1,为了让权系数之和等于1,模板系数需要再乘以归一化因子1/9,
在这里插入图片描述
  均值滤波处理比较简单,因此计算速度比较快,但是有一些明显的缺陷:它在图像去噪的同时也破坏了图像的细节部分,而使图像变得模糊,不能很好地去除噪声点,特别是椒盐噪声。

在OpenCV中使用函数blur() 来实现均值滤波操作,其函数模型如下:

void cv::blur(Mat InputArray src,  //原始图像
              Mat OutputArray dst,  //目标图像
              Size 	ksize,  //滤波模板尺寸
              Point anchor = Point(-1,-1),  //锚点(此刻被滤波处理的点)默认为内核中心
              int borderType = BORDER_DEFAULT  //扩展边界的类型,默认值BORDER_DEFAULT
			  )	

可以看出,blur函数的定义和boxFilter函数十分类似,只是缺少了一个参数ddepth。

2.5高斯滤波

高斯滤波是一种线性平滑滤波器,每一个像素点都由其本身和邻域内的其他像素经过加权平均得到的,在数学角度来看,就是图像与正态分布做卷积的过程。 相对于均值滤波来说, 高斯滤波器能根据高斯函数的形状来选择权值系数,所以高斯滤波的平滑效果更加柔和,而且边缘保留的也更好。
具体操作:用一个模板(卷积/掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值代替模板中心点像素的值。
  高斯平滑滤波器对于抑制服从正态分布的噪声非常有效,我们知道图像采集过程中由于传感器、传输、延时抖动和自然光不均匀等都会产生高斯噪声,所以高斯滤波可以作为绝大部分自然图像处理的预处理操作
  尺寸为3×3、中心参数为4的高斯平滑模板如下图所示,中心像素的灰度值比周围图像像素的灰度值更重要,因此给模板中心对应的像素赋予最大的权系数,随着模板对应的像素到中心位置的距离增大而减小权系数(服从二维高斯分布)。
在这里插入图片描述

在OpenCV中使用函数GaussianBlur() 来实现高斯滤波操作,其函数模型如下:

void GaussianBlur(Mat InputArray src,  //原始图像
				  Mat OutputArray dst,  //目标图像
                  Size ksize,  //高斯核尺寸
                  double sigmaX,  //高斯核在X方向上的标准差
                  double sigmaY=0,  //高斯核在Y方向上的标准差
                  int borderType=BORDER_DEFAULT  //边界模式,默认值BORDER_DEFAULT       
                  )

2.6中值滤波

中值滤波是一种典型的非线性滤波技术,它是统计排序滤波的一种。它是将模板对应的邻域内像素的灰度值进行排序,然后将排序后的中值作为模板中心对应像素的输出值。除此之外,还有最大值滤波,最小值滤波,自适应中值滤波等等统计排序滤波方式。
中值滤波可以ongoing公式表述为:
在这里插入图片描述
上式中, S x y S_{xy} Sxy表示以像素 ( x , y ) (x,y) (x,y)为中心的邻域的集合, g ( x , y ) g(x,y) g(x,y)表示中值滤波在像素 ( x , y ) (x,y) (x,y)处的输出, m e d i a n ⋅ median{·} median表示中值查找。由此可知,对一幅图像进行中值滤波的一般步骤为:

  1. 将模板在图中移动遍历每一个像素,
  2. 将模板对应的邻域内像素的灰度值排序
  3. 查找中间值,将其赋于模板中心对应的像素

  中值滤波的平滑效果要优于线性滤波,线性平滑滤波在降噪的同时也会模糊图像的边缘细节,但是中值滤波不会改变信号中的阶跃变化,因此能够平滑信号中的噪声,同时又不会模糊信号的边缘信息。特别的,中值滤波的冲激响应为0,所以能够很好地过滤椒盐噪声

在OpenCV中使用函数medianBlur() 来实现中值滤波操作,其函数模型如下:

void medianBlur(Mat InputArray src,   //原始图像
			    Mat OutputArray dst,  //目标图像
			    int ksize   //滤波器尺寸
			    )

2.7双边滤波

双边滤波是一种非线性的滤波方法,是结合图像的空间邻近度像素相似度的的一种折中处理。它是一种边缘保存(Edge preserving) 的非迭代平滑滤波方法。
  另一方面,它它比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离得较远的像素不会对边缘上的像素值影响太多,这样也就保证了边缘附近像素值的保存。但是由于彩色图像里存在的高频噪声,双边滤波不能够干净地进行滤除,只能对低频信息进行较好的滤波
总体上来讲,在像素灰度过度缓和的区域,双边滤波有类似于高斯滤波的效果,而在图像边缘等梯度较大的地方,则有保持的效果。

OpenCV中使用bilateralFilter() 函数对图像进行双边滤波,函数的声明如下:

void bilateralFilter(Mat InputArray src,  //原始图像
				     Mat OutputArray dst,  //目标图像
				     int d,  //过滤过程中每个像素邻域的直径
				     double sigmaColor,  //颜色空间滤波器sigma的值
				     double sigmaSpace,  //坐标空间中滤波器sigma的值
				     int borderType=BORDER_DEFAULT  //边界类型,默认值BORDER_DEFAULT
				     )

【注】颜色空间滤波器sigma的值越大,也就表示该像素邻域内有越宽广的颜色会被混合到一起,会产生较大的半径相等颜色区域。坐标空间中滤波器sigma的值越大就表明越远的像素会互相影响,从而使更大的区域中足够相似的颜色获取相同的颜色。

2.8形态学滤波

基于形状的一系列图像处理操作。主要运算包括:二值腐蚀与膨胀,二值开闭运算,骨架抽取,极限腐蚀,黑帽顶帽变换等。

三、基于OpenCV的C++代码实现

OpenCV中通过相关函数实现:

  • 方框滤波——boxblur函数
  • 均值滤波——blur函数
  • 高斯滤波——GaussianBlur函数
  • 中值滤波——medianBlur函数
  • 双边滤波——bilateralFilter函数

C++实现代码如下:

#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
 
using namespace cv;
using namespace std;
 
int main()
{
	//Mat srcImage = imread("C:/Users/Administrator/Desktop/beauty.jpg");
    Mat srcImage = imread("C:/Users/Administrator/Desktop/beauty_GaussianNoise.jpg");
	if (!srcImage.data)
	{
		cout << "Load failture..."<< endl;
		return -1;
	}
    //Size dsize=Size(round(0.2*srcImage.cols),round(0.2*srcImage.rows));
    //resize(srcImage,srcImage,dsize,0,0);  //缩小图像尺寸

	//使用boxFilter实现方框滤波
	Mat dst_box(srcImage.size(), srcImage.type());  
	boxFilter(srcImage, dst_box, -1, Size(5, 5));  
	
    //使用blur实现均值滤波
	Mat dst_mean(srcImage.size(), srcImage.type());
	blur(srcImage, dst_mean, Size(5, 5), Point(-1, -1), 1);

    //使用GaussianBlur实现高斯滤波
	Mat dst_gauss(srcImage.size(), srcImage.type());
	GaussianBlur(srcImage, dst_gauss, Size(3, 3),0,0);

    //使用medianBlur实现中值滤波
	Mat dst_median;
	medianBlur(srcImage, dst_median, 7);
    
    //使用bilateralFilter实现双边滤波
	Mat dst_bilater(srcImage.size(), srcImage.type());
	bilateralFilter(srcImage, dst_bilater, 25, 25 * 2, 25 / 2);

    //显示效果
	imshow("srcImage", srcImage);
    imshow("boxFilter", dst_box);
    imshow("blur", dst_mean);
    imshow("GaussianBlur", dst_gauss);
    imshow("medianBlur", dst_median);
    imshow("bilateralFilter", dst_bilater);
	waitKey(0);
	return 0;
}

原图分家加载两幅图像(1)无噪声清晰源图像;(2)添加高斯噪声图像(均值mu=0,方差sigma=0.2)
(1)时,滤波结果为:
在这里插入图片描述
可以看出,均值滤波模糊效果和方框滤波效果一样,双边滤波对原图的保持效果最好,中值滤波对原图的模糊最为严重而且有渲染效果。

(2)时,滤波结果为:
在这里插入图片描述
中值滤波对原图的噪声点去除的最完全,但对原图产生的模糊严重;高斯滤波去噪效果较好,但右轻微模糊,而双边滤波同时完成了噪声去除和特征保持,效果最佳!

参考博客:
【1】数字图像处理(第三版)_冈萨雷斯
【2】OpenCV图像处理-十五、图像空域滤波(上)(2017.4)
【3】方框滤波、均值滤波、高斯滤波等滤波器详解

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值