Halcon算子学习:XLD几种边缘连接函数
1.union_cotangential_contours_xld
(Contours : UnionContours : FitClippingLength, FitLength, MaxTangAngle, MaxDist, MaxDistPerp, MaxOverlap, Mode : )
根据输入的轮廓的端点处的局部曲率,连接曲率满足一定条件的轮廓
输入:
-
contours (xld object)
-
FitClippingLengt 轮廓的一部分的长度小于这个值,则跳过计算切线
默认:0.0
一般设置范围:大于等于0 -
FitLength 轮廓的一部分大于这个值的,参与计算切线
默认:30
建议值:10.0, 20.0, 30.0,‘auto’
范围:大于等于0 -
MaxTangAngle 弧度制 两个轮廓的切线的最大角,大于该值的不合并
默认:0.78539816
范围:0.0 < MaxTangAngle<3.1415926 -
MaxDist 两个轮廓的端点之间的最大距离
默认:25.0
建议值:5.0, 10.0 , 25.0, 50.0
范围:大于等于0 -
MaxDistPerp:轮廓端点到另一轮廓切线垂直距离的最大值,大于该值的不合并
默认:10.0
建议值:2.0, 5.0, 10.0, 20.0
范围:大于等于0 -
MaxOverlap:两个轮廓的最大重叠值,大于该值的不参与合并
默认:2.0
建议值:2.0, 5.0, 10.0, 20.0 -
Mode:如何处理轮廓的属性值
默认:‘attr_forget’
可选值列表:‘attr_keep’,
输出:
- UnionContours (xld object)
函数工作原理:
1)对于输入的contours中的每个轮廓,首先确定其末端。
- FitClippingLength这个参数代表了一个轮廓的两个末端之间的欧氏长度。有了这个参数,可以忽略输入轮廓末端的假象。
2) - FitLength则表示了轮廓末端参与计算曲率的一小段的欧式长度。**在一个轮廓的末端,至少Fitlength长度的在轮廓末端上的点,参与计算。**这里可以使用‘auto’设置。然后算子将把轮廓分割为很多直线和圆弧段,然后将第一段和最后一段分割的结果作为末端。因为计算非常花时间,所以推荐尽可能赋予长度具体的数值。
3)算子尝试将每个末端来拟合一个圆。然后决定输入轮廓的端点,离这些圆最近的端点(用到拟合圆的rms距离)。这些点的切线相当于这些输入轮廓的端点处的局部曲率。
如果圆拟合失败,算子就尝试拟合回归线。则轮廓末端的局部曲率就由端点回归线的方向代替。
4)输入的轮廓根据其端点处的局部曲率来决定是否组合在一起。如果两个轮廓达到了几个阈值的要求,则组合成一个轮廓。 - MaxTangAngle表示了两个轮廓切线的最大角。
- MaxDist代表了两个轮廓的端点到对方的最大距离。
- MaxDistPerp表示了端点到切线垂直距离的最大值。这个距离是一个端点到另一个轮廓切线的垂直距离的最大值,反之一样。
- MaxOverlap。最后一个阈值考虑的是互相有重叠的轮廓,重叠的程度由一个端点到另一个轮廓的切线投影来决定,反之一样。端点之间的距离、端点投影的距离必须比MaxOverlap值短的才参与算子计算。不同于其他阈值,MaxOverlap可以为负。负值表示的是沿切线方向的端点到轮廓距离的最小值。(不太明白,正值不是沿切线投影方向吗?怎么负值就是沿切线方向了呢?)
如果满足以上条件的话,一个轮廓、或者多个轮廓可以由这个算子计算后合并成为闭合的轮廓。但注意,如果已经闭合的轮廓,则不参与算子计算。
如果所有的阈值都在轮廓线之间被满足,则计算一个评分值。角度和距离的计算值越接近于0,则得分值越高。然后按照分数值的顺序执行统一。因此,如果统一有多个候选项,则首先合并最佳拟合轮廓。 - Mode为标签设定,决定是否将输入轮廓的属性拷贝到输出轮廓去。
‘attr_keep’是拷贝属性,可能会对算子的性能产生不好的影像。’attr_forget’则告诉算子忽略已有属性。更多的属性设置说明,见算子union_adjacent_contours_xld中的解释。
小结:曲率是一个很好的方法,对于一个物体边缘的提取,在没有大拐弯的情况下,也就是说,在物体的一个较为平滑的边缘提取后,边缘断裂也就是不连续的时候,用这个算子可以将它们连接起来。但是对于拐角的断裂的边缘,以及不是太平滑也就是七拐八拐的断裂边缘,可能就不是那么有效了。
2.union_collinear_contours_xld
连接共线的轮廓
-
输入:
Contours XLD -
MaxDistAbs: 沿参考回归线方向轮廓端点的最大距离,大于该值不参与计算
默认:10.0
范围:大于等于0 -
MaxDistRel:轮廓端点距离相对于沿参考回归线方向相对于被延长的轮廓的长度的值(比值的意思?)
默认:1.0
范围:大于等于0 -
MaxShift:轮廓到参考回归线的最大距离(垂直距离)
默认:2.0
范围:大于等于0 -
MaxAngle: 两个轮廓的最大角度差,弧度制
默认:0.1
范围:0.0< MaxAngle<=0.78539816339 -
Mode: :对待轮廓属性处理的标签设置,字符
默认:‘attr_keep’
可选list:‘attr_keep’, ‘attr_forget’
输出:
- UnionContours
3.union_adjacent_contours_xld
(Contours : UnionContours : MaxDistAbs, MaxDistRel, Mode : )
连接端点相近的轮廓
输入:
- Contours
- MaxDistAbs:轮廓之间端点的最大距离
默认:10.0
范围:大于等于0 - MaxDistRel:端点之间距离相对于长的轮廓(到底是不是指距离与长轮廓长度之比?)
默认:1.0
范围:大于等于0 - Mode: :对待轮廓属性处理的标签设置,字符
默认:‘attr_keep’
可选list:‘attr_keep’, ‘attr_forget’
输出:
- UnionContours
描述:
- 这个算子连接所有端点相近的输入轮廓,是一个串联结果。统一轮廓由输入轮廓的轮廓点拼接而成。如果必要的话,这些输入轮廓上的点的顺序会发生翻转,所以这些轮廓的要被连接的端点位于直接邻域中(大致意思就是轮廓本来是从左到右的顺序存的点,因为连接需要,变成了从右到左的存储顺序。因为跟这个轮廓连接的另一个轮廓更长,所以以人家的方向为准)。重复此操作,直到不再有未连接的相邻轮廓,结果就是所有新连接的轮廓,以及输入轮廓中不满足连接条件而未发生变化的轮廓,都返回到输出UnionContours中。
参数:
1)参数MaxDistAbs和MaxDistRel用于定义两个轮廓的接近条件。原则上,这些参数的测量取决于每一对轮廓线的计算顺序,即其中的轮廓作为参考轮廓,并与第二个轮廓连接。为了避免这种依赖关系,在两个方向上对各自的测量值进行评估,并选择轮廓线的顺序,从而使这些测量值更小。注意,在下图中,左边的轮廓线始终作为参考轮廓线。参数模式控制输入轮廓属性的处理。
- 参数MaxDistAbs定义了两个轮廓之间可接受的最大绝对距离。距离是沿着参考轮廓的回归线测量的。因此,它是两个轮廓线之间的间隙投影到参考轮廓线的回归线上的长度。
- 参数MaxDistRel定义了两个轮廓之间可接受的最大相对距离。相对距离的计算方法是将距离a(参数MaxDistAbs的描述)除以参考轮廓的长度b
2) 如果两个轮廓的端点之间的距离不超过阈值MaxDistAbs,或者由长一些的轮廓的长度乘以相对阈值MaxDistRel,则连接。(也就是说maxDistRel是个比例值,长一些的轮廓的长度乘以这个值得到的值,去与两轮廓端点距离相比)。
3)连接临近轮廓的顺序主要取决于临近的端点的距离,有最小距离的轮廓最先连接。如果有两对轮廓有一样的距离,则第一对不含最短轮廓的将被连接。
参数Mode的意义和用法参见 union_collinear_contours_xld 中的相关说明。
小结:对连接临近的轮廓具有较好适应性,但是未考虑一些相似性,仅根据离的远近来决定是否连接,可能会产生错误连接,比如会不会产生一个轮廓在同一端连接多个?在去除了很多杂轮廓的前提下,这个方法还是非常值得一试的。
4.union_cocircular_contours_xld
连接位于同一圆上的轮廓片段。
这个适用性对圆形物体的提取比较有用,连接的差不多了,就可以进行下一步拟合。
5.union_straight_contours_xld
将临近的具有同方向的直线轮廓连接。
输入:
- Contours
- MaxDist:端点之间的最大距离
默认:5.0 - MaxDiff:方向差别的最大值
默认0.5 - Percent:上面两个参数之间的权值
默认:50% - Mode:平行的轮廓是否考虑
默认:‘noparallel’
可选值:‘noparallel’, ‘paralleltoo’, ‘every’ - Iterations:迭代的次数
默认:‘maximum‘
建议值:1,2,3,4,5,6,7,8,9,10,‘maximum’
范围1<= Iterations<= 500
最小步进:1
MaxDist两个轮廓的端点之间的距离。注意端点是轮廓第一个点和最后一个点在其回归线上的投影。回归线的方向要小于MaxDiff。
如果上述两个阈值只有一个满足的话,考虑权重参数Percent,可以决定一个满足要求,但另一个比阈值高。
例如,如果两个轮廓的端点距离是5.0,方向差是0.5,阈值设置的是MaxDist = 4.0,MaxDiff = 0.625,每个值都和阈值有25%的差距。如果Percent = 60%,则大的端点距离的权值比小的方向差值的权值高,因此这两个轮廓不被连接。相反,如果Percent = 40%,则两个轮廓就被连接。
如果设置Percent = 100%,则只有端点距离被考虑。当Percent = 0%,则只有方向差被考虑。如果Percent = 50%,则两个阈值的权重一样。
万一存在平行轮廓的情况,合并相邻的轮廓则具有风险。如果需要避免这种情况,则在Mode里设置‘noparallel’,否则使用Mode = ‘paralleltoo’就可以了。Mode = ‘every’则表示,每个轮廓都无条件连接,其他参数都无影响。
合并是只对两个轮廓,采用递归的方式。
PS:和collinear的区别在于,可以对非直线进行连接。可以在距离和方向中找到比较合适的平衡权重。但是不明白递归是有什么作用。
一点不明白的是方向差别,如果方向相反,即使夹角很小,但是显示的可能是钝角,会不会被滤除了呢?