本文主要是介绍OpenCV与EmguCV中的空间滤波,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
空间滤波是一种采用滤波处理的图像增强方法。其理论基础是空间卷积和空间相关。目的是改善图像质量。
空间滤波的模板被称为空间滤波器。
在图像中的任意一点(x,y),滤波器的响应g(x,y)是滤波器系数与该滤波器包围的图像像素的乘积之和。
一般来说,用大小为m * n的滤波器对大小为M * N的图像进行线性空间滤波,可由下式表示:
w是滤波器的系数,f是像素值。对于m * n的模板,我们假设m = 2a + 1,n = 2b + 1,a,b为正整数。
①方框滤波 box Filter
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,我们一般不去管它。
Mat srcImage = imread("M:/图像处理实验/boxFilter/src.bmp");
boxFilter(srcImage, srcImage, -1,Size(5, 5));
imwrite("M:/图像处理实验/boxFilter/dst.bmp", srcImage);
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)
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")
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,我们一般不去管它。
Mat srcImage = imread("M:/图像处理实验/blur/src.bmp");
blur(srcImage, srcImage,Size(5, 5), Point(-1,-1));
imwrite("M:/图像处理实验/blur/dst.bmp", srcImage);
PublicSharedSubBlur ( srcAsIInputArray, dstAsIOutputArray, ksizeAsSize, anchorAsPoint, Optional borderTypeAsBorderType = BorderType.Reflect101 )
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")
下面这幅图中的是均值滤波器模板
邻域越大平滑的效果越好。但是邻域过大,平滑会使边缘信息损失的越大,从而使输出的图像变得模糊,因此需要合理的选择邻域的大小。
需要注意的是,与Matlab不同,OpenCV的滤波操作处理后的图像与输入图像的大小是相同的。为了达到这一效果,OpenCV在图像的边界之外创造了虚拟的像素,默认情况下通过对边缘的复制来实现。
模板的大小由那些即将融入背景中的物体R的尺寸来决定。
滤波后的图像中可能会有黑边。这是由于我们用0(黑色)填充原图像的边界,经滤波后,再去除填充区域的结果,某些黑的混入了滤波后的图像。对于使用较大滤波器平滑的图像,这就成了问题。
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,我们一般不去管它。
Mat srcImage = imread("M:/图像处理实验/GaussianBlur/src.bmp");
Mat dstImage;
GaussianBlur(srcImage, dstImage, Size(5, 5), 0, 0);
imwrite("M:/图像处理实验/GaussianBlur/dst.bmp", dstImage);
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)
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就是基于离散化窗口卷积实现的。
大家常常说高斯滤波最有用的滤波操作,虽然它用起来,效率往往不是最高的。
高斯模糊技术生成的图像,其视觉效果就像是经过一个半透明屏幕在观察图像,这与镜头焦外成像效果散景以及普通照明阴影中的效果都明显不同。高斯平滑也用于计算机视觉算法中的预先处理阶段,以增强图像在不同比例大小下的图像效果(参见尺度空间表示以及尺度空间实现)。从数学的角度来看,图像的高斯模糊过程就是图像与正态分布做卷积。由于正态分布又叫作高斯分布,所以这项技术就叫作高斯模糊。
图像与圆形方框模糊做卷积将会生成更加精确的焦外成像效果。由于高斯函数的傅立叶变换是另外一个高斯函数,所以高斯模糊对于图像来说就是一个低通滤波操作。
所谓的加权平均是指,用不同的系数去乘以像素。即一些像素的重要性(权重)比另外一些像素的重要性更大。
系数越大,在计算中可以为该像素提供更大的权重。
这种加权重的策略的目的是,在平滑处理中,试图降低模糊。
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的奇数
Mat srcImage=imread("M:/图像处理实验/MedianBlur/src.bmp");
Mat dstImage;
medianBlur( srcImage, out, 5);
imwrite("M:/图像处理实验/MedianBlur/dst.bmp", dstImage);
Public Shared Sub MedianBlur(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, ksize As Integer)
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倍以上。
中值滤波器对于处理脉冲噪声非常有效,这种噪声称为椒盐噪声,因为这种噪声是以黑白点的形式叠加在图像上的。
中值滤波器的主要功能是使拥有不同灰度的点看起来更接近于他们的相邻点。
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。
Mat srcImage=imread("M:/图像处理实验/bilateralFilter/src.bmp");
Mat dstImage;
bilateralFilter( srcImage, dstImage, 25, 25*2, 25/2 );
imwrite("M:/图像处理实验/bilateralFilter/dst.bmp", dstImage);
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)
'对于彩色图像,像素值的接近与否不能使用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")
这篇关于OpenCV与EmguCV中的空间滤波的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!