OpenCV与EmguCV中的空间滤波

2024-08-30 14:18
文章标签 opencv 空间 滤波 emgucv

本文主要是介绍OpenCV与EmguCV中的空间滤波,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://blog.csdn.net/u013162930/article/details/51760258
图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接响到后续图像处理和分析的有效性和可靠性。(滤波就是要去除没用的信息,保留有用的信息,可能是低频,也可能是高频)
滤波一词借用于频域处理。本意是指信号有各种频率的成分,滤掉不想要的成分,即为滤掉常说的噪声,留下想要的成分,这既是滤波的过程,也是滤波的目的。
滤波分为两种:
空间滤波与频域滤波。
空间滤波是将输入图像与滤波器模板相卷积,将最终计算结果之和作为输出的像素值。
频率域滤波是将图像从空间域转换到频率域,再利用变换系数反映某些图像特征的性质进行图像滤波的方法。
这一节我们先来了解空间滤波。

空间滤波分类
空间滤波按滤波器是否线性,可分为线性空间滤波和非线性空间滤波。
按照用途来分,可分为平滑空间滤波器和锐化空间滤波器。

在OpenCV中提供了以下三种线性滤波器,方框滤波、均值滤波、高斯滤波。
非线性滤波主要提供了,中值滤波和双边滤波。

空间滤波机理

空间滤波是一种采用滤波处理的图像增强方法。其理论基础是空间卷积和空间相关。目的是改善图像质量。

空间滤波的模板被称为空间滤波器。

在图像中的任意一点(x,y),滤波器的响应g(x,y)是滤波器系数与该滤波器包围的图像像素的乘积之和。

一般来说,用大小为m * n的滤波器对大小为M * N的图像进行线性空间滤波,可由下式表示:

w是滤波器的系数,f是像素值。对于m * n的模板,我们假设m = 2a + 1,n = 2b + 1,a,b为正整数。

http://blog.csdn.net/u013162930/article/details/48244515

①方框滤波 box Filter
OpenCV中函数原型如下:
void boxFilter(InputArray src,OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), boolnormalize=true, int borderType=BORDER_DEFAULT )
  • 第一个参数,InputArray类型的src,输入图像,即源图像。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,int类型的ddepth,输出图像的深度,-1代表使用原图深度,即src.depth()。
  • 第四个参数,Size类型的ksize,内核的大小。一般这样写Size( w,h )来表示内核的大小( 其中,w 为像素宽度, h为像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表示5x5的核大小,也就是滤波器模板的大小。
  • 第五个参数,Point类型的anchor,表示锚点(即被平滑的那个点),默认值为Point(-1,-1)。如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。
  • 第六个参数,bool类型的normalize,默认值为true,一个标识符,表示内核是否被其区域归一化(normalized)了。
  • 第七个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,我们一般不去管它。

eg。
Mat srcImage = imread("M:/图像处理实验/boxFilter/src.bmp");
boxFilter(srcImage, srcImage, -1,Size(5, 5)); 
imwrite("M:/图像处理实验/boxFilter/dst.bmp", srcImage);

 

EmguCV中函数原型如下:
Public Shared Sub BoxFilter(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, ddepth As Emgu.CV.CvEnum.DepthType, ksize As System.Drawing.Size, anchor As System.Drawing.Point, Optional normalize As Boolean = True, Optional borderType As Emgu.CV.CvEnum.BorderType = Reflect101)
参数含义与openCV boxFilter函数的参数含义相同
eg。
Dim img As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)("M:\图像处理实验\boxFilter\src.bmp")
CvInvoke.BoxFilter(img, img, Emgu.CV.CvEnum.DepthType.Cv8U, New System.Drawing.Size(5, 5), New System.Drawing.Point(-1, -1), True, Emgu.CV.CvEnum.BorderType.Reflect101) 
img.Save("M:\图像处理实验\boxFilter\src-result.bmp")
运行结果与OpenCV中的运行结果相同。

boxFilter()函数所用的滤波器模板为:

当normalize=true的时候,方框滤波就变成了我们熟悉的均值滤波。也就是说,均值滤波是方框滤波归一化(normalized)后的特殊情况。其中,归一化就是把要处理的量都缩放到(0,1)内,以便统一处理和直观量化。
而非归一化(Unnormalized)的方框滤波用于计算每个像素邻域内的积分特性,比如密集光流算法(dense optical flow algorithms)中用到的图像倒数的协方差矩阵(covariance matrices of image derivatives)

②均值滤波 blur
OpenCV中函数原型如下:
void blur(InputArray src, OutputArraydst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )
  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。该函数对通道是独立处理的,且可以处理任意通道数的图片,但需要注意,待处理的图片深度应该为CV_8U, CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。比如可以用Mat::Clone,以源图片为模板,来初始化得到如假包换的目标图。
  • 第三个参数,Size类型(对Size类型稍后有讲解)的ksize,内核的大小。一般这样写Size( w,h )来表示内核的大小( 其中,w 为像素宽度, h为像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表示5x5的核大小
  • 第四个参数,Point类型的anchor,表示锚点(即被平滑的那个点),注意他有默认值Point(-1,-1)。如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。
  • 第五个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,我们一般不去管它。

eg。
Mat srcImage = imread("M:/图像处理实验/blur/src.bmp");
blur(srcImage, srcImage,Size(5, 5), Point(-1,-1)); 
imwrite("M:/图像处理实验/blur/dst.bmp", srcImage);

EmguCV中函数原型如下:
PublicSharedSubBlur ( srcAsIInputArray, dstAsIOutputArray, ksizeAsSize, anchorAsPoint, Optional borderTypeAsBorderType = BorderType.Reflect101 )
参数含义与openCV boxFilter函数的参数含义相同
eg。
Dim img As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)("M:\图像处理实验\blur\src.bmp")
CvInvoke.Blur(img, img, New System.Drawing.Size(5, 5), New System.Drawing.Point(-1, -1), Emgu.CV.CvEnum.BorderType.Reflect101)
img.Save("M:\图像处理实验\blur\src-result.bmp")

均值滤波,是最简单的一种滤波操作,输出图像的每一个像素是核窗口内输入图像对应像素的像素的平均值( 所有像素加权系数相等),它也是归一化后的方框滤波。
均值滤波是滤波器模板邻域内像素的简单平均值。可以刻把它归入低通滤波器。
http://blog.csdn.net/u013162930/article/details/48595763

下面这幅图中的是均值滤波器模板

邻域越大平滑的效果越好。但是邻域过大,平滑会使边缘信息损失的越大,从而使输出的图像变得模糊,因此需要合理的选择邻域的大小。

需要注意的是,与Matlab不同,OpenCV的滤波操作处理后的图像与输入图像的大小是相同的。为了达到这一效果,OpenCV在图像的边界之外创造了虚拟的像素,默认情况下通过对边缘的复制来实现。

模板的大小由那些即将融入背景中的物体R的尺寸来决定。

滤波后的图像中可能会有黑边。这是由于我们用0(黑色)填充原图像的边界,经滤波后,再去除填充区域的结果,某些黑的混入了滤波后的图像。对于使用较大滤波器平滑的图像,这就成了问题。


③高斯滤波 GaussianBlur
OpenCV中函数原型如下:
void GaussianBlur(InputArray src,OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, intborderType=BORDER_DEFAULT )
  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。它可以是单独的任意通道数的图片,但需要注意,图片深度应该为CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。比如可以用Mat::Clone,以源图片为模板,来初始化得到如假包换的目标图。
  • 第三个参数,Size类型的ksize高斯内核的大小。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数。或者,它们可以是零的,它们都是由sigma计算而来。
  • 第四个参数,double类型的sigmaX,表示高斯核函数在X方向的的标准偏差。
  • 第五个参数,double类型的sigmaY,表示高斯核函数在Y方向的的标准偏差。若sigmaY为零,就将它设为sigmaX,如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来。
  • 为了结果的正确性着想,最好是把第三个参数Size,第四个参数sigmaX和第五个参数sigmaY全部指定到。
  • 第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,我们一般不去管它。
eg。
Mat srcImage = imread("M:/图像处理实验/GaussianBlur/src.bmp");
Mat dstImage;    
GaussianBlur(srcImage, dstImage, Size(5, 5), 0, 0); 
imwrite("M:/图像处理实验/GaussianBlur/dst.bmp", dstImage);

Emgu中函数原型如下:
Public Shared Sub GaussianBlur(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, ksize As System.Drawing.Size, sigmaX As Double, Optional sigmaY As Double = 0.0, Optional borderType As Emgu.CV.CvEnum.BorderType = Reflect101)
参数含义与openCV boxFilter函数的参数含义相同。
eg。
Dim img As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)("M:\图像处理实验\GaussianBlur\src.bmp")
CvInvoke.GaussianBlur(img, img, New System.Drawing.Size(5, 5), 0, 0)
img.Save("M:\图像处理实验\GaussianBlur\src-result.bmp")

高斯滤波是一种线性平滑滤波,适用于服从正太分布的噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

在图像处理中,高斯滤波一般有两种实现方式,一是用离散化窗口滑窗卷积,另一种通过傅里叶变换。最常见的就是第一种滑窗实现,只有当离散化的窗口非常大,用滑窗计算量非常大(即使用可分离滤波器的实现)的情况下,可能会考虑基于傅里叶变化的实现方法。

OpenCV的GaussianBlur就是基于离散化窗口卷积实现的。

大家常常说高斯滤波最有用的滤波操作,虽然它用起来,效率往往不是最高的。

高斯模糊技术生成的图像,其视觉效果就像是经过一个半透明屏幕在观察图像,这与镜头焦外成像效果散景以及普通照明阴影中的效果都明显不同。高斯平滑也用于计算机视觉算法中的预先处理阶段,以增强图像在不同比例大小下的图像效果(参见尺度空间表示以及尺度空间实现)。从数学的角度来看,图像的高斯模糊过程就是图像与正态分布做卷积。由于正态分布又叫作高斯分布,所以这项技术就叫作高斯模糊。

图像与圆形方框模糊做卷积将会生成更加精确的焦外成像效果。由于高斯函数的傅立叶变换是另外一个高斯函数,所以高斯模糊对于图像来说就是一个低通滤波操作。

所谓的加权平均是指,用不同的系数去乘以像素。即一些像素的重要性(权重)比另外一些像素的重要性更大。

系数越大,在计算中可以为该像素提供更大的权重。

这种加权重的策略的目的是,在平滑处理中,试图降低模糊。


④中值滤波 MedianBlur
OpenCV中函数原型如下:
void medianBlur(InputArray src,OutputArray dst, int ksize) 
  • 第一个参数,InputArray类型的src,函数的输入参数,填1、3或者4通道的Mat类型的图像;当ksize为3或者5的时候,图像深度需为CV_8U,CV_16U,或CV_32F其中之一,而对于较大孔径尺寸的图片,它只能是CV_8U。
  • 第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。
  • 第三个参数,int类型的ksize,孔径的线性尺寸(aperture linear size),注意这个参数必须是大于1的奇数
eg。
Mat srcImage=imread("M:/图像处理实验/MedianBlur/src.bmp");  
Mat dstImage;  
medianBlur( srcImage, out, 5); 
imwrite("M:/图像处理实验/MedianBlur/dst.bmp", dstImage);

EmguCV中的函数原型如下:
Public Shared Sub MedianBlur(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, ksize As Integer)
参数含义与OpenCV中相同
eg。
Dim img As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)("M:\图像处理实验\MedianBlur\src.bmp")        
CvInvoke.MedianBlur(img, img, 7)
img.Save("M:\图像处理实验\MedianBlur\src-result.bmp")

中值滤波器是一种统计排序滤波器,这种滤波器的响应以滤波器包围的图像的像素的排序为基础,然后用统计排序结果决定的值来代替中心像素的值。中值滤波器就是以像素邻域内的灰度值的中值代替该像素的值。

中值滤波器的使用非常的普遍,它对于一定类型的随机噪声提供了一种优秀的去噪能力。而且比同尺寸的线性平滑滤波器的模糊程度明显要低。不足之处就是中值滤波花费的时间是均值滤波的5倍以上。

中值滤波器对于处理脉冲噪声非常有效,这种噪声称为椒盐噪声,因为这种噪声是以黑白点的形式叠加在图像上的。

中值滤波器的主要功能是使拥有不同灰度的点看起来更接近于他们的相邻点。

http://blog.csdn.net/u013162930/article/details/48595763

⑤双边滤波 bilateralFilter
OpenCV中的函数原型如下:
void bilateralFilter(InputArray src, OutputArraydst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT)
  • 第一个参数,InputArray类型的src,输入图像,即源图像,需要为8位或者浮点型单通道、三通道的图像。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,int类型的d,表示在过滤过程中每个像素邻域的直径。如果这个值我们设其为非正数,那么OpenCV会从第五个参数sigmaSpace来计算出它来。
  • 第四个参数,double类型的sigmaColor,颜色空间滤波器的sigma值。这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
  • 第五个参数,double类型的sigmaSpace坐标空间中滤波器的sigma值,坐标空间的标注方差。他的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。
  • 第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。

eg。
Mat srcImage=imread("M:/图像处理实验/bilateralFilter/src.bmp");  
Mat dstImage;  
bilateralFilter( srcImage, dstImage, 25, 25*2, 25/2 ); 
imwrite("M:/图像处理实验/bilateralFilter/dst.bmp", dstImage);

EmguCV中的函数原型如下:
Public Shared Sub BilateralFilter(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, d As Integer, sigmaColor As Double, sigmaSpace As Double, Optional borderType As Emgu.CV.CvEnum.BorderType = Reflect101)
参数含义与OpenCV中相同
eg。
'对于彩色图像,像素值的接近与否不能使用RGB空间值,双边滤波的原始文献建议使用CIE颜色空间。
Dim img As Image(Of Gray, Byte) = New Image(Of Gray, Byte)("M:\图像处理实验\bilateralFilter\src.bmp")
CvInvoke.BilateralFilter(img, img, 7, 7 * 2, 7 / 2)
img.Save("M:\图像处理实验\bilateralFilter\src-result.bmp")
%%VB.net中Emgu的双边滤波运行时卡死,暂未实现。。

双边滤波是一种可以保边去噪的滤波器。 之所以可以达到此去噪效果,是因为滤波器是由两个函数构成。一个函数是由几何空间距离决定滤波器系数。另一个由像素差值决定滤波器系数。http://blog.csdn.net/abcjennifer/article/details/7616663
在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。

双边滤波输出像素的值依赖于邻域像素的值的加权组合

权重系数w(i,j,k,l)取决于定义域核


和值域核


的乘积


同时考虑了空间域与值域的差别,而Gaussian Filter和α均值滤波分别只考虑了空间域和值域差别。

本文中的OpenCv与EmguCV均用的是3.0以上的版本。






这篇关于OpenCV与EmguCV中的空间滤波的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1121052

相关文章

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

Open3D 基于法线的双边滤波

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 输入参数: 输出参数: 参数影响: 2.2完整代码 三、实现效果 3.1原始点云 3.2滤波后点云 Open3D点云算法汇总及实战案例汇总的目录地址: Open3D点云算法与点云深度学习案例汇总(长期更新)-CSDN博客 一、概述         基于法线的双边

opencv 滚动条

参数介绍:createTrackbar( trackbarname , "hello" , &alpha_slider ,alpha_max ,  on_trackbar )  ;在标签中显示的文字(提示滑动条的用途) TrackbarName创建的滑动条要放置窗体的名字 “hello”滑动条的取值范围从 0 到 alpha_max (最小值只能为 zero).滑动后的值存放在

6.4双边滤波

目录 实验原理 示例代码1 运行结果1 实验代码2 运行结果2 实验原理 双边滤波(Bilateral Filtering)是一种非线性滤波技术,用于图像处理中去除噪声,同时保留边缘和细节。这种滤波器结合了空间邻近性和像素值相似性的双重加权,从而能够在去噪(平滑图像)的同时保留图像的边缘细节。双边滤波器能够在的同时,保持边缘清晰,因此非常适合用于去除噪声和保持图像特征。在Op

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

树莓派5_opencv笔记27:Opencv录制视频(无声音)

今日继续学习树莓派5 8G:(Raspberry Pi,简称RPi或RasPi)  本人所用树莓派5 装载的系统与版本如下:  版本可用命令 (lsb_release -a) 查询: Opencv 与 python 版本如下: 今天就水一篇文章,用树莓派摄像头,Opencv录制一段视频保存在指定目录... 文章提供测试代码讲解,整体代码贴出、测试效果图 目录 阶段一:录制一段

Verybot之OpenCV应用三:色标跟踪

下面的这个应用主要完成的是Verybot跟踪色标的功能,识别部分还是居于OpenCV编写,色标跟踪一般需要将图像的颜色模式进行转换,将RGB转换为HSV,因为对HSV格式下的图像进行识别时受光线的影响比较小,但是也有采用RGB模式来进行识别的情况,这种情况一般光线条件比较固定,背景跟识别物在颜色上很容易区分出来。         下面这个程序的流程大致是这样的:

Verybot之OpenCV应用二:霍夫变换查找圆

其实我是想通过这个程序来测试一下,OpenCV在Verybot上跑得怎么样,霍夫变换的原理就不多说了,下面是程序: #include "cv.h"#include "highgui.h"#include "stdio.h"int main(int argc, char** argv){cvNamedWindow("vedio",0);CvCapture* capture;i

Verybot之OpenCV应用一:安装与图像采集测试

在Verybot上安装OpenCV是很简单的,只需要执行:         sudo apt-get update         sudo apt-get install libopencv-dev         sudo apt-get install python-opencv         下面就对安装好的OpenCV进行一下测试,编写一个通过USB摄像头采