利用OpenCV识别特定形状的算法研究外文翻译资料

 2022-09-18 05:09

Gradients and Sobel Derivatives

One of the most basic and important convolutions is the computation of derivatives (or

approximations to them). There are many ways to do this, but only a few are well suited

to a given situation.

In general, the most common operator used to represent differentiation is the Sobel derivative[Sobel68] operator (see Figures 6-3 and 6-4). Sobel operators exist for any order of derivative as well as for mixed partial derivatives (e.g., /xy).

Figure 6-3. The effect of the Sobel operator when used to approximate a first derivative in the x-dimension

Here, src and dst are your image input and output, and xorder and yorder are the orders

of the derivative. Typically yoursquo;ll use 0, 1, or at most 2; a 0 value indicates no derivative in that direction.* The aperture_size parameter should be odd and is the width (and the height) of the square filter. Currently, aperture_sizes of 1, 3, 5, and 7 are supported. If src is 8-bit then the dst must be of depth IPL_DEPTH_16S to avoid overflow.

Figure 6-4. The effect of the Sobel operator when used to approximate a first derivative in the y-dimension

Sobel derivatives have the nice property that they can be defined for kernels of any size, and those kernels can be constructed quickly and iteratively. The larger kernels give a better approximation to the derivative because the smaller kernels are very sensitive to noise.

To understand this more exactly, we must realize that a Sobel derivative is not really a

derivative at all. This is because the Sobel operator is defined on a discrete space. What

the Sobel operator actually represents is a fit to a polynomial. That is, the Sobel derivative of second order in the x-direction is not really a second derivative; it is a local fit to a parabolic function. This explains why one might want to use a larger kernel: that larger kernel is computing the fit over a larger number of pixels.

Scharr Filter

In fact, there are many ways to approximate a derivative in the case of a discrete grid. The downside of the approximation used for the Sobel operator is that it is less accurate

for small kernels. For large kernels, where more points are used in the approximation,

this problem is less significant. This inaccuracy does not show up directly for the X and

Y filters used in cvSobel(), because they are exactly aligned with the x- and y-axes. The

difficulty arises when you want to make image measurements that are approximations of directional derivatives (i.e., direction of the image gradient by using the arctangent of the y/x filter responses).

To put this in context, a concrete example of where you may want image measurements of this kind would be in the process of collecting shape information from an object by assembling a histogram of gradient angles around the object. Such a histogram is the basis on which many common shape classifiers are trained and operated. In this case, inaccurate measures of gradient angle will decrease the recognition performance of the classifier.

For a 3-by-3 Sobel filter, the inaccuracies are more apparent the further the gradient angle is from horizontal or vertical. OpenCV addresses this inaccuracy for small (but fast) 3-by-3 Sobel derivative filters by a somewhat obscure use of the special aperture_size

value CV_SCHARR in the cvSobel() function. The Scharr filter is just as fast but more accurate than the Sobel filter, so it should always be used if you want to make image measurements using a 3-by-3 filter. The filter coefficients for the Scharr filter are shown in Figure 6-5 [Scharr00].

Figure 6-5. Th e 3-by-3 Scharr filter using flag CV_SHARR

Laplace

The OpenCV Laplacian function (first used in vision by Marr [Marr82]) implements a

discrete analog of the Laplacian operator:*

Because the Laplacian operator can be defined in terms of second derivatives, you might

well suppose that the discrete implementation works something like the second-order

Sobel derivative. Indeed it does, and in fact the OpenCV implementation of the Laplacian

operator uses the Sobel operators directly in its computation.

The cvLaplace() function takes the usual source and destination images as arguments as

well as an aperture size. The source can be either an 8-bit (unsigned) image or a 32-bit

(floating-point) image. The destination must be a 16-bit (signed) image or a 32-bit (floating-point) image. This aperture is precisely the same as the aperture appearing in the

Sobel derivatives and, in effect, gives the size of the region over which the pixels are

sampled in the computation of the second derivatives.

The Laplace operator can be used in a variety of contexts. A common application is to

detect “blobs.” Recall that the form of the Laplacian operator is a sum of second derivatives along the x-axis and y-axis. This means that a single point or any small blob

(smaller than the aperture) that is surrounded by higher values will tend to maximize this function. Conversely, a point or small blob that is surrounded by lower values will tend to maximize the negative of this function.

With this in mind, the Laplace operator can also be used as a kind of edge detector. To see how this is done, consider the first derivative of a function, which will (of course) be large wherever the function is changing rapidly. Equally important, it will grow rapidly as we approach an edge-like discontinuity and shrink rapidly as we move past the

discontinuity. Hence the derivative will be at a local maximum somewhere within this

range. Therefore we can look to the 0s of the second derivative for locations of such

剩余内容已隐藏,支付完成后下载完整资料


梯度和Sobel导数

一个最重要并且最基本的卷积是导数的计算(或者是其近似值),有许多方法可以做到,但是只有少数方法适合于给定情况。

通常来说,勇于表达微分的最常用的操作是Sobel微分算子(见图6-3和图6-4)。Sobel算子包含任意阶的微分以及融合偏导(例如 /xy)。

图6-3:逼近x方向上一阶微分的Sobel算子的效果

这里,src和dst分别是输入图像和输出图像,xorder和yorder是求导的阶数。通常只可能用到0,1,最多2。值为0表明在这个方向上没有求导,aperture_size参数是方形滤波器的宽(或高)并且应该是奇数。目前,aperture_size支持1,3,5,7。如果源图像src是8位的,为避免溢出,目标图像的深度必须是IPL_DEPTH_16S。

Sobel导数有一个非常好的性质,即可以定义任意大小的核,并且这些核可以用快速且迭代方式构造。大核对导数有更好的逼近,因为小核对噪声更敏感。

为了更好地理解以上内容,我们必须认识到一点,即Sobel导数并不是真正的导数,因为Sobel算子定义于一个离散空间之上。Sobel算子真正表示的是多项式拟合,也就是说,x方向上的二阶Sobel导数并不是真正的二阶导数。它是对抛物线函数的局部拟合。这说明人们为什么想用较大的核,因为较大核是在更多像素上计算这种拟合。

图6-4:逼近y方向上一阶微分的Sobel算子的效果

Scharr滤波器

事实上,在离散网络的场合下有很多方法可以近似的计算出导数。对于小一点的核而言,这种使用于Sobel算子近似计算导数的缺点是精度比较低。对于大核,由于在估计时使用了更多的点,所以这个问题并不严重。这种不精确性并不会直接在cvSobel()中使用的X和Y滤波器中表现出来,因为它们完全沿x轴和y轴排列。当试图估计图像的方向导数(directional derivative,即,使用y/x滤波器响应的反正切得到的图像梯度的方向)时,难度就出现了。

为了承上启下,这里有一个这类图像度量的具体例子。这个例子为从一个物体收集形状信息的过程,而这个过程是通过求取目标周围梯度角度的直方图来实现的。这样的直方图是许多通用或常见分类器训练和工作的基础。在这种情况下,对梯度角不准确的度量将会降低分类器识别的性能。

对于一个33的Sobel滤波器,当梯度角度越接近水平或者垂直方向时,这样的不准确就更加明显。OPENCV通过在cvSobel()函数中一些特殊aperture_size值CV_SCHARR的隐形使用,以解决小(但是快)的33Sobel导数滤波器不准确的问题。Scharr滤波器和Sobel滤波器一样快,但是准确率更高,所以当你利用33滤波器实现图像度量的时候应该使用Scharr滤波器。Scharr滤波器的滤波系数如图6-5所示[Scharr00]。

图6-5:使用标记CV_SCHARR的33Scharr滤波器

拉普拉斯变换

OpenCV的拉普拉斯函数(第一次被Marr [Marr82]应用于视觉领域)实现了拉普拉斯算子的离散拟合。

因为拉普拉斯算子可以用二次导数的形式定义,可假设其离散实现类似于二阶Sobel导数。事实的确如此,OpenCV在计算拉普拉斯算子时直接使用Sobel算子。

cvLaplace()函数通常把源图像和目标图像以及中孔大小作为变量。源图像既可以是8位(无符号)图像,也可以是32位(浮点)图像。而目标图像必须是16位(有符号)或者32位(浮点)图像。这里的中孔与Sobel导数中出现的中孔完全一样,事实上主要给出区域大小,在二次求导的计算中,采样这个区域的像素。

拉普拉斯算子可用于各种情况。一个通常的应用是检测“团块”。联想到拉普拉斯算子的形式是沿着X轴和Y轴的二次导数的和,这就意味着周围是更高值的单点或者小块(比中孔小)会将使这个函数值最大化。反过来说,周围是更低值的点将会使函数的负值最大化。

基于这个思想。拉普拉斯算子也可以用作边缘检测。为达此目的,只需要考虑当函数快速变化时其一阶导数变大即可。同样重要的是,当我们逼近类似边缘的不连续地方时导数会快速增长,而穿过这些不连续地方时导数又会快速减小。所以导数会在此范围内有局部极值。这样我们可以期待局部最大值位于二阶导数为0的地方,明白了吗?原始图像的边缘位于拉普拉斯的值等于0的地方。不幸的是,在拉普拉斯算子中,所有实质性的和没有意义的边缘的检测都是0。但这并不是什么问题,因为我们可以过滤掉这些点,它们的一阶(Sobel)导数值也很大。图6-6显示对图像应用拉普拉斯和一次、二次导数以及它们的0交叉的例子。

图6-6:赛车图像的拉普拉斯变换(右上角)。放大轮胎(白圈)并且只考虑X方向,我们(定性)展示了具有代表性的亮度、一次和二次导数(下面三个子图),二次导数的0值对应着边,相对较大的一次导数的0对应的是较强的边缘

Canny算子

以上所描述的边缘检测的方法在1986年由J.Canny得到完善,也就是通常所称的Canny边缘检测法[Canny86]。Canny算法同6.4节提到的简单的基于拉普拉斯算法的不同点之一是在Canny算法中,首先在x和y方向求一阶导数,然后组合为4个方向的导数。这些方向导数达到局部最大值的点就是组成边缘的候选点。

然而,Canny算法最重要的一个新特点是其试图将独立边的候选像素拼装成轮廓。轮廓的形成是对这些像素运用滞后性阈值。这意味着有两个阈值,上限和下限。如果一个像素的梯度大于上限阈值,则被认定是边缘像素,如果低于下限阈值,则被抛弃,如果介于二者之间。只有当其与高于上限阈值的图像连接时才会被接受。Canny推荐的上下限阈值比为2:1到3:1之间。图6-7和图6-8分别显示了利用cvCanny()以及上下限阈值比为5:1和3:2的测试图案和图像的结果。

cvCanny()函数需要输入一幅灰度图,输出图也一定是灰度的(实际上是布尔图像)。接下来两个参数是下限阈值和上限阈值,最后一个参数是另一个中孔。通常,这个被Sobel算子用到的中孔是cvCanny()在内部使用的。

图6-7:上下限分别为50和10时用Canny算子对两幅不同图像进行边缘检测的结果

图6-8:上下限分别为150和100时用Canny算子对两幅不同图像进行边缘检测的结果

霍夫变换

霍夫变换是一种在图像中寻找直线、圆及其他简单形状的方法。原始的霍夫变换是一种直线变换,即在二值图像中寻找直线的一种相对快速方法。变换可以推广到其他普通的情况,而不仅仅是简单的直线。

霍夫线变换

霍夫直线变换的基本理论是二值图像中的任何点都可能是一些候选直线集合的一部分。如果要确定每条线进行参数化,例如一个斜率a和截距b原始图像中的一点会变换为(a,b)平面上的轨迹,轨迹上的点对应着所有过原始图像上点的直线(见图6-9)。如果我们将输入图像中所有非0像素转化成输出图像中的这些点集并且将其贡献相加,然后输入图像(例如(x,y)平面)出现的直线将会在输出图像(例如(a,b)平面)以局部最大值出现。因为我们将每个点的贡献相加,因此(a,b)平面通常被称为累加平面(accumu lator plane)。

图6-9:霍夫变换找到了图像中的许多线;其中一些是想要的,而另一些不是

你可能认为用斜率-截距的形式来代表所有通过的点并不是一种最好的方式(因为作为斜率函数,直线的密度有相当的差异,以及相关的事实是可能的斜率间隔的范围是从 -到 )。正是由于这个原因,在实际数值计算中使用的变换图像的参数化略微有些不同。首选的参数化方式是每一行代表极坐标(,)中的一个点,并且隐含的直线是通过象征点,垂直于远点到此点的半径。如图6-10所示,此直线的方程如下:

图6-10:a)显示图像平面的一个点(,),b)显示a)图像中参数 不同时的许多线,这些线隐含着在(,)平面内的点,放在一起就形成了一条特征曲线(c图)

OpenCV的霍夫变换算法并没有将这个算法显式地展现给用户。而是简单地返回(,)平面的局部最大值。然而,需要了解这个过程以便更好地理解OpenCV霍夫变换函数中的参数。

OpenCV支持两种不同形式的霍夫变换:标准霍夫变换(SHT)[Duda72]和累计概率霍夫变换(PPHT)。刚才所说的是SHT算法。PPHT是这种算法的一个变种,计算单独线段的方向以及范围(如图6-11所示)。之所以称PPHT为“概率”的,是因为并不将累加器平面内的所有可能点累加,而只累加其中的一部分。该想法是如果峰值将要足够高,只用一小部分时间去寻找它就足够了。这个猜想的结果可以实质性的减少计算时间。尽管有一些变量的含义是取决于用哪个算法,但可以使用OpenCV中的同一个函数来访问这两个算法。

图6-11:首先运行Canny边缘检测(lowTHRESH=50,lowTHRESH=150),结果以灰度图显示。然后运行累计概率的霍夫变换(param1=50,param2=10),结果被白色覆盖,可以看到由霍夫变换产生的粗线

第一个变量是输入图像,必须是8位的,但输入信息可以被看成是二值的(即所有非0像素被认为是相等的)。第二个参数是指向保存结果位置的指针,既可以是内存块(见第8章的CvMemoryStorage)也可以是N*1的矩阵数列(行数N将有助于限制直线的最大数量)。下一个参数method可以是CV_HOUGH_STANDARD,CV_HOUGH_PROBABILISTIC或者CV_HOUGH_MULTI_SCALE,分别对应SHT,PPTH或SHT的多尺度变种。

下面两个变量,rho和theta是用来设置直线所需要的分辨率(例如,累加平面所需要的分辨率)。Rho的单位是像素而theta的单位是弧度。因此,累加平面可以看成是由rho像素和theta弧度组成的二维直方图。Threshold是认定为一条直线时在累计平面中必须达到的值。最后一个参数在实际应用中有点棘手,它没有被归一化,所以应该将其根据SHT中的图像进行尺度化。请记住,这个变量实际上表示支持所返回的直线的(在边缘图像的)点的数量。

在SHT中没有用到param1和param2参数。对于PPHT,param1设置为将要返回的线段的最小长度,param2设置为一条直线上分离线段不能连成一条直线的分割像素点数。对于多尺度的HT(Hough Transform),这两个参数是用来指明应被计算的直线参数中较高的分辨率。多尺度的HT首先根据rho和theta参数准确计算直线的位置,然后分别通过param1和param2等比例继续细化结果(例如,rho中最终的分辨率是param1分割rho产生的,theta中最终的分辨率是param2分割theta产生的)。

函数的返回内容依赖于调用方式。如果line_storage是矩阵数组,最终的返回值为空。在这种情形下使用SHT或者多尺度的HT时,矩阵应该是cv_32FC2类型,当使用PPHT时,矩阵应为cv_32SC4类型。在头两种情况下,每一行中- 和-的值应在数组中的两个通道里。在PPHT情形下,四个通道保留的是返回线段开始点和结束点的x-和y-的值。在所有的情形下数组的行数将会被cvHoughLines2()更新以便正确反映返回直线的数量。

如果line_storage是指向内存块的一个指针,返回值将是一个指向CvSeq序列结构的指针。在这种情况下,可以用下面的类似命令从序列中得到每一条直线或者线段。

其中lines是从cvHoughLines2()中得到的返回值,i是所关心的线的索引。在这种情形下,line是指向这条直线数据的指针,对于SHT和MSHT,line[0]和line[1]是浮点类型的 和 ,对于PPHT,是线段终点的CvPoint结构。

霍夫圆变换

霍夫圆变换[Kimme75](如图6-12)与之前所描述的霍夫直线变换是大体上是类似的。说“大体上类似”的原因是——如果想要尝试完全类似——累加平面会被三维的累加容器所替代:在这三维中,一维是x,一维是y,另一维是圆的半径r。这就意味着需要大量的内存但速度却很慢。在OpenCV的应用中可以通过一个比较灵活的霍夫梯度法来解决圆变换的这一问题。

图6-12:霍夫圆变换可以在测试图案中找到圆但在照片中没有(正确)找到

霍夫梯度法的原理如下。首先对图像应用边缘检测(这里用cvCanny())。然后,对边缘图像中每一个非0点,考虑其局部梯度(通过cvSobel()函数计算x和y方向的Sobel一阶导数得到梯度)。利用得到的梯度,由斜率指定的直线上的每一个点都在累加器中被累加,这里斜率是从一个指定的最小值到指定的最大值的距离。同时,标记边缘图像中每一个非0像素的位置。然后从(二维)累加器中这些点中选择候选的中心,这些中心

剩余内容已隐藏,支付完成后下载完整资料


资料编号:[148498],资料为PDF文档或Word文档,PDF文档可免费转换为Word

您需要先支付 30元 才能查看全部内容!立即支付

课题毕业论文、开题报告、任务书、外文翻译、程序设计、图纸设计等资料可联系客服协助查找。