(OpenCV+Python)图像腐蚀膨胀 开闭运算 线性滤波 非线性滤波.docx

上传人:李司机 文档编号:6789403 上传时间:2024-02-21 格式:DOCX 页数:22 大小:467.68KB
返回 下载 相关 举报
(OpenCV+Python)图像腐蚀膨胀 开闭运算 线性滤波 非线性滤波.docx_第1页
第1页 / 共22页
(OpenCV+Python)图像腐蚀膨胀 开闭运算 线性滤波 非线性滤波.docx_第2页
第2页 / 共22页
(OpenCV+Python)图像腐蚀膨胀 开闭运算 线性滤波 非线性滤波.docx_第3页
第3页 / 共22页
(OpenCV+Python)图像腐蚀膨胀 开闭运算 线性滤波 非线性滤波.docx_第4页
第4页 / 共22页
(OpenCV+Python)图像腐蚀膨胀 开闭运算 线性滤波 非线性滤波.docx_第5页
第5页 / 共22页
点击查看更多>>
资源描述

《(OpenCV+Python)图像腐蚀膨胀 开闭运算 线性滤波 非线性滤波.docx》由会员分享,可在线阅读,更多相关《(OpenCV+Python)图像腐蚀膨胀 开闭运算 线性滤波 非线性滤波.docx(22页珍藏版)》请在三一办公上搜索。

1、图像腐蚀与膨胀我们在前两次教程中概述了OPenCV对于图像的滤波,通常对于一个实战项目而言,滤波之后的下一步操作就是图像的形态学处理了,从本次教程开始,我们正式步入了OPenCV图像形态学处理的部分。形态学(morphology)一词通常表示生物学的一个分支,该分支主要研究动植物的形态和结构。而我们图像处理中指的形态学,往往表示的是数学形态学。下面一起来了解数学形态学的概念。数学形态学是一门建立在格论和拓扑学基础之上的图像分析学科,是数学形态学图像处理的基本理论。其基本的运算包括:二值腐蚀和膨胀、二值开闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、ToP-hat变换、颗粒分析、流域变

2、换、灰值腐蚀和膨胀、灰值开闭运算、灰值形态学梯度等。简单来讲,形态学操作就是基于形状的一系列图像处理操作。OPenCV为进行图像的形态学变换提供了快捷、方便的函数。最基本的形态学操作有二种,他们是:膨胀与腐蚀(DiIatiOn与Erosion)o膨胀与腐蚀能实现多种多样的功能,主要如下消除噪声。分割出独立的图像元素,在图像中连接相邻的元素。寻找图像中的明显的极大值区域或极小值区域。求出图像的梯度。腐蚀和膨胀是对白色部分(高亮部分)而言的,不是黑色部分。膨胀就是图像中的高亮部分进行膨胀,“领域扩张”,效果图拥有比原图更大的高亮区域。腐蚀就是原图中的高亮部分被腐蚀,“领域被蚕食”,效果图拥有比原图

3、更小的高亮区域。膨胀其实,膨胀就是求局部最大值的操作。按数学方面来说,膨胀或者腐蚀操作就是将图像(或图像的一部分区域,我们称之为A)与核(我们称之为B)进行卷积。核可以是任何的形状和大小,它拥有一个单独定义出来的参考点,我们称其为锚点。多数情况下,核是一个小的中间带有参考点和实心正方形或者圆盘,其实,我们可以把核视为模板或者掩码。而膨胀就是求局部最大值的操作,核B与图形卷积,即计算核B覆盖的区域的像素点的最大值,并把这个最大值赋值给参考点指定的像素。这样就会使图像中的高亮区域逐渐增长。如下图所示,这就是膨胀操作:我们来看一下函数原型:cv2.dilate(img,kernel,iteratio

4、ns)-dst第一个参数:img指需要膨胀的图。第二个参数:kernel指膨胀操作的内核,默认是一个简单的3X3矩阵,我们也可以利用getStructuringElement()函数指明它的形状。第三个参数:iterations指的是膨胀次数,省略是默认为1。dst则为返回的图像。定义卷积核需要用到Numpy中的函数,它可以定义一个矩形的卷积核结构元素,我们来看一下代码:importcv2importnumpyasnpimg=cv2.imread(01.jpg,O)kernel=np.ones(5,5),np.uint8)dict=cv2.dilate(img,kernel,iteration

5、s=I)cv2.imshow(org,img)cv2.imshow(,result,dict)cv2.waitKey(0)cv2.destroyA11Windows()我们定义了一个5*5的矩形卷积核,效果:事实上,在某些情况下,我们可能需要椭圆形/圆形的内核。因此,为此,C)PenCV具有一个函数CkgetStructuringElement()。我们只需传递内核的形状和大小,即可获得所需的内核,函数原型:retval=cv.getStructuringElement(shape,ksize,anchor)这个函数的第一个参数表示内核的形状,有三种形状可以选择。矩形:MORPH_RECT交叉

6、形:MORPH_CROSS椭圆形:MORPH_ELLIPSE1111111111111111111111111OOlO0111111111111111001000010000100ii0010000100理形结构结构十字形结构第二和第三个参数分别是内核的尺寸以及锚点的位置。一般在调用erode以及dilate函数之前,先定义一个变量来获得。getStructuringElement函数的返回值:对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心点。element形状唯一依赖锚点位置,其他情况下,锚点只是影响了形态学运算结果的偏移。我们看一下代码:importcv2importn

7、umpyasnpimg=cv2.imread(,01.jpg,O)kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)dict=cv2.dilate(img,kernel,iterations=I)cv2.imshow(org,img)cv2.imshow(result,dict)cv2.waitKey(0)cv2.destroyAllWindows()至于卷积核的形状我在这里选择了椭圆形,大家可以自己选择其他形状进行实验:Jorg-Iresult-X1.沁X/JhlX腐蚀再来看一下腐蚀,膨胀和腐蚀是一对好友,是相反的一对操作,所以腐

8、蚀就是求局部最小值的操作。我们一般都会把腐蚀和膨胀对应起来理解和学习。下文就可以看到,两者的函数原型也是基本上一样的。我们来看一下函数原型:cv2.erode(img,kernel,iterations)-dst第一个参数:img指需要腐蚀的图。第二个参数:kernel指腐蚀操作的内核,默认是一个简单的3X3矩阵,我们也可以利用getStructuringElement()函数指明它的形状。第三个参数:iterations指的是腐蚀次数,省略是默认为1。代码:importcv2importnumpyasnpimg=cv2.imread(01.jpg,O)kernel=cv2.getStruct

9、uringElement(cv2.MORPH_ELLIPSE,(5,5)erode=cv2.erode(img,kernel,iterations=1)cv2.imshow(org,img)cv2.imshow(result,erode)cv2.waitKey(0)cv2.destroyAHWindows()效果:腐蚀与膨胀是形态学处理中的基础操作,它们有着很重要的作用,也是后面开操作与闭操作的基础,所以必须熟练运用。开运算与闭运算图像的腐蚀与膨胀是本次教程的核心一一开运算与闭运算的基础,如果结构元素为圆形,则膨胀操作可填充图像中比结构元素小的孔洞以及图像边缘处小的凹陷部分。而腐蚀可以消除图像

10、中的毛刺及细小连接成分,并将图像缩小,从而使其补集扩大。但是,膨胀和腐蚀并非互为逆运算,所以它们可以结合使用。在腐蚀和膨胀两个基本运算的基础上,可以构造出形态学运算簇,它由膨胀和腐蚀两个运算的复合与集合操作(并、交、补等)组合成的所有运算构成。例如,可使用同一结构元素,先对图像进行腐蚀然后膨胀其结果,该运算称为开运算;或先对图像进行膨胀然后腐蚀其结果,称其为闭运算。开运算和闭运算是形态学运算族中两种最为重要的运算。对于图像X及结构元素s,用符号X。S表示S对图像X作开运算,用符号XS表示S对图像X作闭运算,它们的定义为:XQS=(XS)SX-S=(XS)S首先需要来了解一个函数:cv2.mor

11、phologyEx(src,op,kernel)SrC传入的图片。OP进行变化的方式。kernel表示定义的卷积核的大小以及形状。op=cv2.M0RPH_0PEN进行开运算,指的是先进行腐蚀操作,再进行膨胀操作。op=cv2.MORPH_CLOSE进行闭运算,指的是先进行膨胀操作,再进行腐蚀操作。开运算开运算指的就是对图像先进行腐蚀操作,然后再进行膨胀操作,而通常情况下,它是对图像的明亮的区域进行操作,可以消除图像中的白噪声,现在我们来看例子,先看一幅图像:现在我们想要消除图像中的黑色的毛刺,但是如果直接对图像进行开运算是不行的,因为开运算是对图像的明亮区域进行操作,看一下直接进行开运算会有

12、什么效果:importcv2importnumpyasnpimg=cv2.imread(open.jpg,0)kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)open=cv2.morphologyEx(img,cv2.MORPH_OPEN,kemel)cv2.imshow(img,img)cv2.imshow(,result,open)cv2.waitKey(0)cv2.destroyAHWindows()可以看到,图像的毛刺没有被去除,现在我们需要将原图进行阈值化翻转,也就是黑白颠倒,这样才方便进行形态学的处理,我们在前面阈值部分讲过

13、,这里就不再讲述了,直接看代码:importcv2importnumpyasnpimg=cv2.imread(open.jpg,0)threshold=cv2.threshold(img,0,255,cv2.THRESH_BINARYNVlCV2.THRESH_OTSU)川cv2.imshow(nimg,img)cv2.imshow(thresu,threshold)cv2.waitKey(0)cv2.destroyAHWindows()现在图像已经被黑白颠倒了过来,现在我们可以开始进行开运算了,当然首先也是需要定义一个卷积核的,这在上个教程中已经谈到,在这里我们定义一个3*3的矩形卷积核:i

14、mportcv2importnumpyasnpimg=cv2.imread(open.jpg,0)threshold=cv2.threshold(img,0,255,cv2.THRESH_BINARYNVlCV2.THRESH_0TSU)11kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)open=cv2.morphologyEx(threshold,cv2.MORPH-OPEN,kernel)cv2.imshow(,img,img)cv2.imshow(thres,threshold)cv2.imshow(resultu,open)c

15、v2.waitKey(0)cv2.destroyA11Windows()这样效果就显而易见了,如果我们将卷积核改成5*5的呢:importcv2importnumpyasnpimg=cv2.imread(open.jpg,0)threshold=cv2.threshold(img,0,255,cv2.THRESH_BINARYNVlCV2.THRESH_OTSU)1kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)open=cv2.morphologyEx(threshold,cv2.MORPH-OPEN,kernel)cv2.imsho

16、w(thres,threshold)cv2.imshow(,result,open)cv2.waitKey(0)cv2.destroyA11Windows()这就说明操作过度了,所以对于形态学处理卷积核的适当选取是非常重要的,现在我们对处理之后的图像进行还原:importcv2importnumpyasnpimg=cv2.imread(open.jpg,0)threshold=cv2.threshold(img,0,255,cv2.THRESH_BINARYNVleV2.THRESH_OTSU)1kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(

17、3,3)open=cv2.morphologyEx(threshold,cv2.MORPH_OPEN,kernel)result=cv2.threshold(open,0,255,cv2.THRESH_BINARYNVlCV2.THRESHJDTSU)Icv2.imshow(img,img)cv2.imshow(thres,threshold)cv2.imshow(open,open)cv2.imshow(result,result)cv2.waitKey(0)cv2.destroyAllWindows()看一下最终还原的结果:事实上,卷积核的灵活运用将会极大的方便图像的形态学处理,我们来进行

18、一个实战,比如现在给出一幅图像:我们将用开运算分别提炼出横线和竖线,我们使用13*1的卷积核进行实验:importcv2importnumpyasnpimg=cv2.imread(hengshu.jpg,0)kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(l3,l)open=cv2.morphologyEx(img,cv2.MORPH-OPEN,kernel)cv2.imshow(img,img)cv2.imshow(uopen,open)cv2.waitKey(0)cv2.destroyA11Windows()是不是很神奇,现在我们使用1*1

19、3的卷积核进行实验:importcv2importnumpyasnpimg=cv2.imread(hengshu.jpg,0)kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(1,13)open=cv2.morphologyEx(img,cv2.MORPH-OPEN,kemel)cv2.imshow(img,img)cv2.imshow(open,open)cv2.waitKey(0)cv2.destroyA11Windows()竖线也被完美的提取出来了,在以后的项目实战中,我们将会用到这些知识,合理的过滤掉图像中多余的信息,事实上,我们还发现,

20、处理之后的图像偏暗,没有原图那么明亮,这在下次教程中的顶帽一一黑帽操作中可以进行处理。闭运算我们折腾了半天的开运算,现在我们来玩玩闭运算,闭运算跟开运算相反,是先膨胀再腐蚀,它通常被用来去除图像明亮区域内部的噪声。我们来看一幅图像:现在我们将要用闭运算去除图像明亮区域内部的黑点,定义一个7*7的卷积核,我们看代码:importcv2importnumpyasnpimg=cv2.imread(close.jpg,0)kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(7,7)open=cv2.morphologyEx(img,cv2.MORPH-CL

21、OSE,kemel)cv2.imshow(,img,img)cv2.imshow(open,open)cv2.waitKey(0)cv2.destroyAllWindowsO可以看到,效果很好,现在我们来进行另一个具有实战意义的实验,先看图片:人夕为,我廛为车,行动法幔,可泳曾见就忘必Lb步.我们需要将这些字轮廓提炼出来,并且用方框标定出来,每一行字用一个方框标定出来,当然,这个涉及到以后将要讲解的轮廓提取以及轮廓近似,但是在这里我们先进行一个实验,如果我们想将每一行字用一个方框标定出来,那么首先需要满足的条件就是每行的字必须连在一块,形成一个整体,这样的话才可以用OPenCV提取他们整体的轮

22、廓,进而标定出来,但现在我们看到这些字都是独立的,它们并没有连在一起,这个时候我们就可以采用闭运算了。我们来看代码:importcv2importnumpyasnpimg=cv2.imread(textl.jpg,O)kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(2l,5)open=cv2.morphologyEx(img,cv2.MORPH-CLOSE,kemel)cv2.imshow(,img,img)cv2.imshow(open,open)cv2.waitKey(0)cv2.destroyA11Windows()44为接9我圆为卒,行

23、讪也横,可论曾见我忘士一夕.这样的话所有的字体连在一起,这也方便了后期的轮廓提取。我在这里给出综合代码,大家可以玩玩:importcv2importnumpyasnpimg=cv2.imread(,textl.jpg,)test=img.copy()gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(19,5)close=cv2.morphologyEx(gray,cv2.MORPH_CLOSE,kernel)contour,_=cv2.findContours(cl

24、ose,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cv2.drawContours(test,contour,-1,(0,0,255),2)fbrcincontour:x,y,w,h=cv2.boundingRect(c)cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)cv2.imshow(,result,img)cv2.imshow(test,test)cv2.imshow(nclose,close)cv2.waitKey(0)cv2.destroyA11Windows()人夕为丹hI人夕为攫9我廛为4,我

25、图.为卒可语曾见我日士一畛.可泳曾见我向It一畛.第一个图是对图像的轮廓进行提取,第二个则是提取轮廓的外接矩形,是不是很有意思,这在以后都会慢慢讲述。闭运算一般则被用于处理内部噪声情况,开运算处理外部噪声情况,所以合理的运用它们是非常重要的。(OPenCV+Python)线性滤波&非线性滤波线性滤波本次教程将介绍几种OPeneV常用的滤波器,将介绍它们详细的原理,图像滤波对于OPenCV图像处理来说是至关重要的一环,它在整个OPenCV中的分量是举足轻重的,我们必须完完全全的掌握它。图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好

26、坏将直接影响到后续图像处理和分析的有效性和可靠性。消除图像中的噪声成分叫作图像的平滑化或滤波操作。信号或图像的能量大部分集中在幅度谱的低频和中频段是很常见的,而在较高频段,感兴趣的信息经常被噪声淹没。因此一个能降低高频成分幅度的滤波器就能够减弱噪声的影响。图像滤波的目的有两个:一是抽出对象的特征作为图像识别的特征模式。另一个是为适应图像处理的要求,消除图像数字化时所混入的噪声。而对滤波处理的要求也有两条:一是不能损坏图像的轮廓及边缘等重要信息。二是使图像清晰视觉效果好。平滑滤波是低频增强的空间域滤波技术。它的目的有两类:一类是模糊。一类是消除噪音。空间域的平滑滤波一般采用简单平均法进行,就是求

27、邻近像元点的平均亮度值。邻域的大小与平滑的效果直接相关,邻域越大平滑的效果越好,但邻域过大,平滑会使边缘信息损失的越大,从而使输出的图像变得模糊,因此需合理选择邻域的大小。关于滤波器,一种形象的比喻法是:我们可以把滤波器想象成一个包含加权系数的窗口,当使用这个滤波器平滑处理图像时,就把这个窗口放到图像之上,透过这个窗口来看我们得到的图像。原理邻域算子(局部算子)是利用给定像素周围的像素值的决定此像素的最终输出值的一种算子。而线性邻域滤波是一种常用的邻域算子,像素的输出值取决于输入像素的加权和,具体过程如下图:左边图像与中间图像的卷积产生右边图像。目标图像中蓝色标记的像素是利用原图像中红色标记的

28、像素计算得到的。邻域算子除了用于局部色调调整以外,还可以用于图像滤波,实现图像的平滑和锐化,图像边缘增强或者图像噪声的去除。本篇文章,我们介绍的主角是线性邻域滤波算子,即用不同的权重去结合一个小邻域内的像素,来得到应有的处理效果。线性滤波处理的输出像素值是输入像素值的加权和:其中的加权和我们称其为“核”,滤波器的加权系数,即滤波器的“滤波系数二上面的式子可以简单写作:其中f表示输入像素值,h表示加权系数“核“,g表示输出像素值在新版本的OPenCV中,提供了如下三种常用的线性滤波操作,他们分别被封装在单独的函数中,使用起来非常方便:均值滤波一一blur函数方框滤波boxblur函数高斯滤波Ga

29、ussianBlur函数均值滤波器均值滤波器是一种低通滤波器,也是线性滤波器。对于一幅图像,我们都知道其像素值在0-255,通常来讲,滤波器所用的一个滤波模板都为奇数,这里我们以3*3为例:INPUTIMAGE18M5123924418855121757895883524204113109221315410423525BO152532251597823368851802142450中间黄色部分即为滤波器的模板(卷积核),其将用于与图像进行卷积进而滤波,对于均值滤波器,顾名思义,其像素点为中间九个像素值的均值,从而将整个图像的像素用这个均值像素代替:函数原型:dst=cv.blur(src,ks

30、ize,dst,anchor,borderTypeJ)其中第一个参数为输入的图像,第二个参数为卷积核的大小,后面的我们都采用默认值就可以。给出示例代码:importcv2importmatplotlib.pyplotaspitimportnumpyasnpimg=cv2.imread(cat.jpg)blur=cv2.blur(img,(5,5)cv2.imshow(org,img)cv2.imshow(result,blur)cv2.waitKey(0)cv2.destroyAllWindowsO缺陷:均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细

31、节部分,从而使图像变得模糊,不能很好地去除噪声点。特别是椒盐噪声。方框滤波器事实上,方框滤波器与均值滤波器是基本上一样的,我们直接看源码:importcv2importmatplotlib.pyplotaspitimportnumpyasnpimg=cv2.imread(shu.jpg)blur=cv2.boxFilter(imgrl,(3,3),normalize=False)cv2.imshow(,org,img)cv2.imshow(result,blur)cv2.waitKey(0)cv2.destroyAllWindows()boxFilter则为i方框滤波函数,当normalize

32、=True它就完全相当于是一个均值滤波器,滤波像素值计算方法也是均值计算,如图:但是当normalize=False其并非均值,而是卷积核中所有的像素值相加,不除9,那么对于大于255的值,它会全取255进行代替,如图:高斯滤波高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值先来了解一下高斯函数,高斯分布函数指的

33、就是概率论中的正态分布的概率密度函数,均值=0时的一维形式和二维形式如下。其中。为正态分布的标准偏差,其值决定了函数的衰减快慢。X2G(%)=y-e2。2.21Gay) 二x2+y2 e 22从这两个公式不难看出,二维公式其实等于两个一维函数相乘。从概率论角度看,因为随机变量X,Y是相互独立的,那么他们的联合概率密度就等于边缘概率密度之积。这个特性是非常重要的,现在让我们先看一下高斯函数的图像分布与二维高斯卷积核的样子:50116321652863652321图像上,靠近原点的位置地势高,距离原点越远则地势越低。相应地,卷积核也是中心数值最大,并向四周减小,减小的幅度并不是随意的,而是要求整个

34、卷积核近似高斯函数的图像。由于高斯滤波实质是一种加权平均滤波,为了实现平均,核还带有一个系数,例如上图中的十六分之一、八十四分之一,这些系数等于矩阵中所有数值之和的倒数。可能有人看不太懂,我简单解释一下高斯滤波的原理,以下面那个数字图为例:INPUTIMAGE18M5123924418855121757895883524204113109221315410423525130152532251597823368&51802142450假设中间的204为中心点,高斯滤波的原理就是距离中心点最近其权重系数越大,就类似这样一个图:”P1/H/GJ5球0/J那么距离204越近则其权重系数越大,它跟均值滤

35、波还是有很大不同的,均值滤波对于204周围的75和24这两个较小值非常的不友好,会导致误差较大。但是高斯滤波表示,离我近的,吃嘛嘛香,离我远的,说话分量就没有那么重了,不管你值有多大或者多小。我们看一下函数原型:GaussianBlur(src,ksize,sigmaX,dstfSigmaY,borderTypeJ)-dstsrc输入图像;图像可以具有任意数量的通道,这些通道可以独立处理,但深度应为CV_8U,CV_16U,CV_16S,CV_32F或CV_64F。dst输出图像的大小和类型与SrC相同。ksize高斯内核大小。ksize.width和ksize.height可以不同,但它们都

36、必须为正数和奇数,也可以为零,然后根据Sigma计算得出。sigmaXX方向上的高斯核标准偏差。SigmaYY方向上的高斯核标准差;如果SigmaY为零,则将其设置为等于sigmaX;如果两个SigmaS为零,则分别从ksize.width和ksize.height计算得出;为了完全控制结果,而不管将来可能对所有这些语义进行的修改,建议指定所有ksize,sigmaX和SigmaYo我们来看代码:importcv2importmatplotlib.pyplotaspitimportnumpyasnpimg=cv2.imread(shu.jpg)blur=cv2.GaussianBlur(img

37、,(3,3),0)cv2.imshow(,org,img)cv2.imshow(,result,blur)cv2.waitKey(0)cv2.destroyA11Windows()I-我们可以看到,三种线性滤波器都无法很好的去除图片中的椒盐噪声,而要想去除椒盐噪声,我们需要用非线性滤波器,这将在下次介绍。现在我们来总结一下这三种滤波器:对“不是解Z,e*改RMUL. SHB8灯能多足行啊1第同盟, r 分均Wt疫使删M内络学Rl代.*HlUyW一刑EJWi*i手漕时.BS不同0屐W非线性滤波我们在上个教程中谈到了线性滤波,相比较而言,线性滤波中的高斯滤波最为受欢迎,但是我们也遗留了一个问题,线

38、性滤波对于椒盐噪声的过滤并不是很好,由此我们本次将谈到OPenCV中的非线性滤波。之前我们说的线性滤波,即两个信号之和的响应和他们各自响应之和相等。换句话说,每个像素的输出值是一些输入像素的加权和,线性滤波器易于构造,并且易于从频率响应角度来进行分析。其实在很多情况下,使用邻域像素的非线性滤波也许会得到更好的效果。比如在噪声是散粒噪声而不是高斯噪声,即图像偶尔会出现很大的值的时候。在这种情况下,用高斯滤波器对图像进行模糊的话,噪声像素是不会被去除的,它们只是转换为更为柔和但仍然可见的散粒。这就到了中值滤波登场的时候了。中值滤波中值滤波是一种典型的非线性滤波技术,基本思想是用像素点邻域灰度值的中

39、值来代替该像素点的灰度值,该方法在去除脉冲噪声、椒盐噪声的同时又能保留图像边缘细节。中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,其基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点,对于斑点噪声和椒盐噪声来说尤其有用,因为它不依赖于邻域内那些与典型值差别很大的值。中值滤波器在处理连续图像窗函数时与线性滤波器的工作方式类似,但滤波过程却不再是加权运算。中值滤波在一定的条件下可以克服常见线性滤波器如最小均方滤波、方框滤波器、均值滤波等带来的图像细节模糊,而且对滤除脉冲干扰及图像扫描噪声非常有效,也常用

40、于保护边缘信息,保存边缘的特性使它在不希望出现边缘模糊的场合也很有用,是非常经典的平滑噪声处理方法。顾名思义,中值滤波选择每个像素的邻域像素中的中值作为输出,或者说中值滤波将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。通俗的来讲,就找中位数嘛,仍然以那个图为例:INPUTIMAGE18545123924418855121757895883524204113109221315410423525BO152532251597823368&51802142450我们将值从小到大排列一下:247578104113121154204235那么中间值就是113了。一般采用奇数点的邻域来

41、计算中值,但如果像素点数为偶数时,中值就取排序像素中间两点的平均值。中值滤波对于去除椒盐噪声特别的有效,我们先来看一下椒盐噪声的定义:椒盐噪声是由图像传感器,传输信道,解码处理等产生的黑白相间的亮暗点噪声。椒盐噪声是指两种噪声,一种是盐噪声(SaItnOiSe)盐=白色Q55),另一种是胡椒噪声(peppernoise),椒=黑色(0)。前者是高灰度噪声,后者属于低灰度噪声。一般两种噪声同时出现,呈现在图像上就是黑白杂点。对于彩色图像,则表现为在单个像素BGR三个通道随机出现的255与0,而中值滤波的取值恰恰是中间值,所以会将这些极端值过滤掉,我们来看函数原型:dst=cv.medianBlu

42、r(src,ksize,dst)dst为输出的图像SrC为输入的图像ksize为卷积核的大小,它必须为奇数且大于1代码如下:mportcv2importmatplotlib.pyplotaspitimportnumpyasnpimg=cv2.imread(shu.jpg,)blur=cv2.medianBlur(img,3)cv2.imshow(org,img)cv2.imshow(,result,blur)cv2.waitKey(0)cv2.destroyAHWindows()如图:可以看到去除椒盐噪声的效果十分明显,我们来总结一下中值滤波的优缺点。中值滤波器与均值滤波器比较的优势:在均值滤

43、波器中,由于噪声成分被放入平均计算中,所以输出受到了噪声的影响,但是在中值滤波器中,由于噪声成分很难选上,所以几乎不会影响到输出。因此同样用3x3区域进行处理,中值滤波消除的噪声能力更胜一筹。中值滤波无论是在消除噪声还是保存边缘方面都是一个不错的方法。中值滤波器与均值滤波器比较的劣势:中值滤波花费的时间是均值滤波的5倍以上。双边滤波双边滤波是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。双边滤波器的好处是可以做边缘保存,一般过去用的高斯滤波去降噪,都会较明显地模糊边缘,对于高频细节的保护

44、效果并不明显。双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。它的原理大致如图:为了理解双边滤波的距离和像素差两个影响因素,先说明下面两个概念帮助理解:空间距离:当前点距离滤波模板中心点的欧式距离。(Xi-XC)2+3i-c)2e22灰度距离:当前点距离滤波模板中心点的灰度的差值的绝对值。SrayaiyCWc)2e22双边滤波的核函数是空间域

45、核与像素范围域核的综合结果:1)在图像的平坦区域,像素值变化很小,那么像素差值接近于0,对应的像素范围域权重接近于1,此时空间域权重起主要作用,相当于进行高斯模糊;2)在图像的边缘区域,像素值变化很大,那么像素差值大,对应的像素范围域权重变大,即使距离远空间域权重小,加上像素域权重总的系数也较大,从而保护了边缘的信息。我们来看一下函数原型:cv2.bilateralFilter(src,d,sigmaColor,sigmaSpace,dst,borderTypeJ)fdstsrc:输入图像d:过滤时周围每个像素领域的直径sigmaColor:在COIorSPaCe中过滤Sigma。参数越大,临

46、近像素将会在越远的地方mixsigmaSpace:在CoOrdinateSPaCe中过滤Sigma。参数越大,那些颜色足够相近的的颜色的影响越大来看代码:importcv2importmatplotlib.pyplotaspitimportnumpyasnpimg=cv2.imread(example.png)blur=cv2.bilateralFilter(img,21,55,55)cv2.imshow(,org,img)cv2.imshow(resultu,blur)cv2.waitKey(0)cv2.destroyA11Windows()先看原图:再看一下处理之后的图像:是不是看到了一种美颜的效果,双边滤波本身就是加强对边缘

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号