圆识别的各种约束条件
Opencv中提供了SimpleBlobDetector的特征点检测方法,正如它的名称,该算法使用最简单的方式来检测斑点类的特征点。下面我们就来分析一下该算法。
首先通过一系列连续的阈值把输入的灰度图像转换为一个二值图像的集合,阈值范围为[T1,T2],步长为t,则所有阈值为:
T1,T1+t,T1+2t,T1+3t,……,T2 (1)
第二步是利用Suzuki提出的算法通过检测每一幅二值图像的边界的方式提取出每一幅二值图像的连通区域,我们可以认为由边界所围成的不同的连通区域就是该二值图像的斑点;
第三步是根据所有二值图像斑点的中心坐标对二值图像斑点进行分类,从而形成灰度图像的斑点,属于一类的那些二值图像斑点最终形成灰度图像的斑点,具体来说就是,灰度图像的斑点是由中心坐标间的距离小于阈值Tb的那些二值图像斑点所组成的,即这些二值图像斑点属于该灰度图像斑点;
最后就是确定灰度图像斑点的信息——位置和尺寸。位置是属于该灰度图像斑点的所有二值图像斑点中心坐标的加权和,即公式2,权值q等于该二值图像斑点的惯性率的平方,它的含义是二值图像的斑点的形状越接近圆形,越是我们所希望的斑点,因此对灰度图像斑点位置的贡献就越大。尺寸则是属于该灰度图像斑点的所有二值图像斑点中面积大小居中的半径长度。
(2)
在第二步中,并不是所有的二值图像的连通区域都可以认为是二值图像的斑点,我们往往通过一些限定条件来得到更准确的斑点。这些限定条件包括颜色,面积和形状,斑点的形状又可以用圆度,偏心率,或凸度来表示。
对于二值图像来说,只有两种斑点颜色——白色斑点和黑色斑点,我们只需要一种颜色的斑点,通过确定斑点的灰度值就可以区分出斑点的颜色。
连通区域的面积太大和太小都不是斑点,所以我们需要计算连通区域的面积,只有当该面积在我们所设定的最大面积和最小面积之间时,该连通区域才作为斑点被保留下来。
圆形的斑点是最理想的,任意形状的圆度C定义为:
(3)
其中,S和p分别表示该形状的面积和周长,当C为1时,表示该形状是一个完美的圆形,而当C为0时,表示该形状是一个逐渐拉长的多边形。
偏心率是指某一椭圆轨道与理想圆形的偏离程度,长椭圆轨道的偏心率高,而近于圆形的轨道的偏心率低。圆形的偏心率等于0,椭圆的偏心率介于0和1之间,而偏心率等于1表示的是抛物线。直接计算斑点的偏心率较为复杂,但利用图像矩的概念计算图形的惯性率,再由惯性率计算偏心率较为方便。偏心率E和惯性率I之间的关系为:
(4)
因此圆形的惯性率等于1,惯性率越接近1,圆形的程度越高。
最后一个表示斑点形状的量是凸度。在平面中,凸形图指的是图形的所有部分都在由该图形切线所围成的区域的内部。我们可以用凸度来表示斑点凹凸的程度,凸度V的定义为:
(5)
其中,H表示该斑点的凸壳面积
在计算斑点的面积,中心处的坐标,尤其是惯性率时,都可以应用图像矩的方法。
下面我们就介绍该方法。
矩在统计学中被用来反映随机变量的分布情况,推广到力学中,它被用来描述空间物体的质量分布。同样的道理,如果我们将图像的灰度值看作是一个二维的密度分布函数,那么矩方法即可用于图像处理领域。设f(x,y)是一幅数字图像,则它的矩Mij为:
(6)
对于二值图像的来说,零阶矩M00等于它的面积。图形的质心为:
(7)
图像的中心矩μpq定义为:
(8)
一阶中心矩称为静矩,二阶中心矩称为惯性矩。如果仅考虑二阶中心矩的话,则图像完全等同于一个具有确定的大小、方向和离心率,以图像质心为中心且具有恒定辐射度的椭圆。图像的协方差矩阵为:
(9)
该矩阵的两个特征值λ1和λ2对应于图像强度(即椭圆)的主轴和次轴:
(10)
(11)
而图像的方向角度θ为:
(12)
图像的惯性率I为:
(13)
下面给出SimpleBlobDetector的源码分析。我们先来看看SimpleBlobDetector类的默认参数的设置:
[cpp] view plain copy print?
- SimpleBlobDetector::Params::Params()
- {
- thresholdStep = 10; //二值化的阈值步长,即公式1的t
- minThreshold = 50; //二值化的起始阈值,即公式1的T1
- maxThreshold = 220; //二值化的终止阈值,即公式1的T2
- //重复的最小次数,只有属于灰度图像斑点的那些二值图像斑点数量大于该值时,该灰度图像斑点才被认为是特征点
- minRepeatability = 2;
- //最小的斑点距离,不同二值图像的斑点间距离小于该值时,被认为是同一个位置的斑点,否则是不同位置上的斑点
- minDistBetweenBlobs = 10;
- filterByColor = true; //斑点颜色的限制变量
- blobColor = 0; //表示只提取黑色斑点;如果该变量为255,表示只提取白色斑点
- filterByArea = true; //斑点面积的限制变量
- minArea = 25; //斑点的最小面积
- maxArea = 5000; //斑点的最大面积
- filterByCircularity = false; //斑点圆度的限制变量,默认是不限制
- minCircularity = 0.8f; //斑点的最小圆度
- //斑点的最大圆度,所能表示的float类型的最大值
- maxCircularity = std::numeric_limits<float>::max();
- filterByInertia = true; //斑点惯性率的限制变量
- //minInertiaRatio = 0.6;
- minInertiaRatio = 0.1f; //斑点的最小惯性率
- maxInertiaRatio = std::numeric_limits<float>::max(); //斑点的最大惯性率
- filterByConvexity = true; //斑点凸度的限制变量
- //minConvexity = 0.8;
- minConvexity = 0.95f; //斑点的最小凸度
- maxConvexity = std::numeric_limits<float>::max(); //斑点的最大凸度
- }
本文深入解析了OpenCV中的SimpleBlobDetector算法,详细介绍了如何通过连续阈值处理、连通区域提取、斑点分类及信息确定等步骤进行斑点检测。文章探讨了颜色、面积、形状等约束条件,以及如何利用图像矩计算斑点特性。
9627

被折叠的 条评论
为什么被折叠?



