您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 其它文档 > 《学习OpenCV》第5章-图像处理
第5章图像处理本章各小节目录•综述•平滑处理•图像形态学•漫水填充算法•尺寸调整•图像金字塔•阈值化•练习综述到这里,我们已经掌握了关于图像处理的所有基础知识。我们了解了OpenCV库的结构,也知道了通常用来表示图像的基本数据结构。通过熟悉HighGUI接口,我们可以运行程序并将结果显示在屏幕上。掌握了这些用来控制图像结构的基本方法,我们就可以学习更复杂的图像处理方法了。现在,我们来继续学习高级的处理方法,即把图像以“图像”的方式来处理,而不是由颜色值(或灰度值)组成的数组。在提到“图像处理”时,它的意思是:使用图像结构中所定义的高层处理方法来完成特定任务,这些任务是图形和视觉范畴的任务。平滑处理“平滑处理”也称“模糊处理”(blurring),是一项简单且使用频率很高的图像处理方法。平滑处理的用途有很多,但最常见的是用来减少图像上的噪声或者失真。降低图像分辨率时,平滑处理是很重要的(在本章的“图像金字塔”部分会详细介绍这一点)。目前OpenCV可以提供五种不同的平滑操作方法,所有操作都由cvSmooth函数实现,该函数可以将用户所期望的平滑方式作为参数。voidcvSmooth(constCvArr*src,CvArr*dst,intsmoothtype=CV_GAUSSIAN,intparam1=3,intparam2=0,doubleparam3=0,doubleparam4=0);src和dst分别是平滑操作的输入图像和结果,cvSmooth()函数包含4个参数,param1,param2,param3和param4。这些参数的含义取决于smoothtype的值,这些值可能是表5.1中列出的任何一个。(请注意,有些操作不支持inplace方式的输入。inplace方式意味着输入图像与结果图像是同一个图像。)表5-1:平滑操作的各种类型平滑类型名称支持No输入类型输出类型简要介绍CV_BLUR简单模糊是1,38u,32f8u,32f对每个像素param1×param2邻域求和,并做缩放1/(param1param2)CV_BLUR_NO_SCALE简单无缩放变换的模糊否18u16s(占8u的资源)或32f(占32f的资源大小)对每个像素的param1×param2邻域求和CV_MEDIAN中值模糊否1,38u8u对图像进行核大小为parma1×param2的中值滤波CV_GAUSSIAN高斯模糊是1,38u,32f8u(占8u的资源)或32f(占32f的资源)对图像进行核大小为param1×param2的高斯卷积CV_BILATERAL双边滤波否1,38u8u应用双线性3×3滤波,颜色sigma=param1,空间sigma=param2图5.1CV_BLUR所例举的simpleblur是最简单的一项操作。输出图像的每一个像素是窗口中输入图像对应像素的简单平均值。simpleblur支持1~4个图像通道,可以处理8位图像或者32位的浮点图像。图5-1:简单图像平滑处理:左边为输入图像,右边为结果图像不是所有的模糊操作的输入和结果图像类型都相同,CV_BLUR_NO_SCALE(不缩放比例而进行模糊处理)与simpleblur本质上是相同的,但并没有计算其平均值的操作。因此,输入图像和结果图像必须有不同的数值精度,才能保证模糊操作不会导致错误溢出。不缩放比例的simpleblur支持8位的输入图像,结果图像的数据类型必须是IPL_DEPTH_16S(CV_16S)或IPL_DEPTH_32S(CV_32S)。同样的操作也可以在32位浮点图像上进行,结果图像也应该是32位浮点类型。简单无缩放变换的模糊不支持inplace方式:输入图像与结果图像必须不同。(在8位和16位情况下,很明显不能用inplace方式;用32位图像时,也保持这一规定。)用户选择不缩放比例的模糊操作是因为其比缩放比例的模糊操作要快一些。中值滤波器(CV_MEDIAN)[Bardyn84]将中心要素的正方形邻域内的每个像素值用中间像素值(不是平均像素值)替换,它可以用来处理单个通道、三个通道或者四个通道8位的图像,但不可以inplace操作。中值滤波的结果见图5-2。基于平均算法的simpleblur对噪声图像特别是有大的孤立点(有时被称为“镜头噪声”)的图像非常敏感,即使有极少数量点存在较大差异也会导致平均值的明显波动,因此中值滤波可以通过选择中间值避免这些点的影响。下一个平滑滤波器是Gaussianfilter(CV_GAUSSIAN),虽然它不是最快的,但它是最有用的滤波器。高斯滤波用卷积核与输入图像的每个点进行卷积,最终计算结果之和作为输出图像的像素值。对于高斯模糊(图5-3),前两个参数代表滤波器窗口的宽度和高度,可选择的第三个参数代表卷积核的sigma值(是最大宽度的四分之一)。如果第?个参数未指定,系统将会根据窗口尺寸通过下面的方程来自动确定高斯核的各个参数。图5-3:对一维像素数组进行高斯模糊参数1:滤波器宽度参数2:滤波器高度如果用户希望高斯核不对称,那么可以引入第四个参数。这样,第三个和第四个参数分别为水平方向和垂直方向的sigma值。如果第三个和第四个参数已经给出,但是前两个参数被设为0,那么窗口的尺寸会根据sigma值自动确定。高斯滤波的OpenCV的实现还为几个常见的核提供了更高的性能优化。具有标准sigma值的3×3,5×5和7×7比其他核具有更优的性能。高斯模糊支持单个通道或者三个通道的8位或32位的浮点格式图像,可以进行inplace方式操作。高斯模糊的效果见图5-4。OpenCV支持的第五个也是最后一个平滑操作被称作双边滤波(bilateralfiltering)[Tomasi98],举例见图5-5。双边滤波是“边缘保留滤波”的图像分析方法中的一种。将它与高斯平滑对比后会更容易理解。进行高斯滤波的????是真实在空间内的像素是缓慢变化的,因此临近点的像素变化不会太明显。但是随机??个点就可能形成很大的像素差(也就是说空间噪声点不是相互联系的)。正是??这一点,高斯滤波在保留信号的条件下减少噪声。遗憾的是,这种方法在接近??处就无效了,在那儿你不希望像素与相邻像素相关。因此,高斯滤波会磨平边??。而双边滤波能够提供一种不会将边缘的平滑掉的方法,但作为代价,需要更多??时间。与高斯滤波类似,双边滤波会依据每个像素及其邻域构造一个加权平均值,加权计算包括两个部分,其中第一部分加权方式与高斯平滑中的相同,第二部分也属于高斯加权,但不是基于中心像素点与其他像素点的空间距离之上的加权,而是基于其他像素与中心像素的亮度差值的加权。可以将双边滤波视为高斯平滑,对相似的像素赋予较高的权重,不相似的像素赋予较小的权重。这种滤波的典型??就是使处理过的图像看上去像是一幅源图的水彩画,可用于图像的分割。双边滤波含有两个参数。第一个参数代表空域中使用的高斯核的宽度,和高斯滤波的sigma参数类似。第二个参数代表颜色域内高斯核的宽度。第二个参数越大,表明待滤波的强度(或颜色)范围越大(因此不连续的程度越高,以便保留)。图像形态学OpenCV为进行图像的形态学变换[Serra83]提供了快速、方便的函数。基本的形态转换是膨胀与腐蚀,它们能实现多种功能:例如消除噪声、分割出独立的图像元素以及在图像中连接相邻的元素。形态学也常被用于寻找图像中的明显的极大值区域或极小值区域以及求出图像的梯度。膨胀和腐蚀膨胀是指将一些图像(或图像中的一部分区域,称之为A)与核(称之为B)进行卷积。核可以是任何的形状或大小,它拥有一个单独定义出来的参考点(anchorpoint)。多数情况下,核是一个小的中间带有参考点的实心正方形或圆盘。核可以视为模板或掩码,膨胀是求局部最大值的操作。核B与图像卷积,即计算核B覆盖的区域的像素点最大值,并把这个最大值赋值给参考点指定的像素。这样就会使图像中的高亮区域逐渐增长,如图5-6所示。这样的增长就是“膨胀操作”的初衷。图5-6:形态学膨胀:在核B下取最大像素值腐蚀是膨胀的反操作。腐蚀操作要计算核区域像素的最小值。腐蚀可以通过下面的算法生成一个新的图像:当核B与图像卷积时,计算被B覆盖区域的最小像素值,并把这个值放到参考点上。腐蚀后的图像如图5-7所示。一般来说,膨胀扩展了区域A,而腐蚀缩小了区域A。此图5-7:形态腐蚀:在核B之下取最小像素值外,膨胀可以填补凹洞,腐蚀能够消除细的凸起。当然,准确的效果将取决于核,但当使用凸核时前面的说法一般是对的。在OpenCV,我们利用cvErode()和cvDilate()函数实现上述变换。voidcvErode(IplImage*src,IplImage*dst,IplConvKernel*B=NULL,intiterations=1);voidcvDilate(IplImage*src,IplImage*dst,IplConvKernel*B=NULL,intiterations=1);cvErode()和cvDilate()都有源图像和目标图像参数,它们都支持“in-place”操作(源图像和目标图像是同一个图像)。第三个参数是核,默认值为NULL。当为空时,所使用的是参考点位于中心的3×3核(我们将简单讨论如何构造核)。最后,第四个参数是迭代的次数。如果未将它设置为默认值(1),将在一次函数的调用中执行多次操作。腐蚀操作的结果如图5-8所示,膨胀操作的结果如图5-9所示。腐蚀操作通常是用来消除图像中“斑点”噪声。腐蚀可以将斑点腐蚀掉,且能确保图像内的较大区域依然存在。在试图找到连通分支(即具有相似颜色或强度的像素点的大块的互相分离的区域)时通常使用膨胀操作。因为在大多数情况下一个大区域可能被噪声、阴影等类似的东西分割成多个部分,而一次轻微的膨胀又将使这些部分“融合”在一起。综上所述:当OpenCV执行cvErode()函数时,将某点p的像素值设为与p对应的核覆盖下所有点中的最小值,同样的,对于执行膨胀操作时,将取最小值换为取最大值:大家可能会想,既然之前的算法描述已经能解释清楚,为什么还需要引入一个复杂的公式呢?实际上,有些读者喜欢这样的公式,更重要的是,公式可以阐明一些定性描述表达不清楚的一般性问题。我们能够注意到,如果图像不是二值的,那么膨胀和腐蚀操作起到的作用不是很明显。再看一看图5-8和图5-9,分别展示了对两个图像进行腐蚀和膨胀操作的效果。图5-8:腐蚀的结果或者“最小化”操作,亮的区域被隔离并且缩小图5-9:膨胀的“最大化”操作:亮的区域得到了扩展和连接自定义核你不必局限于选择3×3方形的核。可以创建自定义的IplConvKernel核(即我们之前提到的“核B”)。这样的核由cvCreateStructuringElementEx()函数创建,由cvReleaseStructuringElement()函数释放。IplConvKernel*cvCreateStructuringElementEx(intcols,introws,intanchor_x,intanchor_y,intshape,int*values=NULL);voidcvReleaseStructuringElement(IplConvKernel**element);形态核与卷积核不同,不需要任何的数值填充核。当核在图像上移动时,核的元素只需简单标明应该在哪个范围里计算最大值或最小值。参考点指定核与源图像的位置关系,同时也锁定了计算结果在目标图像中的位置。当构造核时,行与列确定了所构造的矩形大小(矩形内含有结构元素),下两个参数anchor_x和anchor_y,是核的封闭矩形内参考点的横纵坐标(x,y)。第五个参数,形状shape可以取表5-2中所列的值。如果使用CV_SHAPE_CUSTOM,那么使用整数向量value在封闭矩形内定义核的形状。使用光栅扫描法读取向量,使每个元素代表封闭矩形中的不同像素。所有非零值指定在核中对应的各个像素点。如果值为空,通常会构造一个所有值为非空的矩形核。表5
本文标题:《学习OpenCV》第5章-图像处理
链接地址:https://www.777doc.com/doc-7490294 .html