理解Halcon中的几个概念
Halcon中的Image的像素类型
资料来源:https://wenku.baidu.com/view/f21f3b8908a1284ac9504312.html
- byte 标准的灰度图像编码之一
- complex 用频率描述图像
- cyclic 每种颜色分配一个灰度值
- direction 边缘梯度方向
- int1
- int2
- int4 2D直方图,两帧图像灰度值出现的频率统计图
- real 边缘提取和特殊的灰灰度值配置
- uint2 标准的灰度图像编码之一
- vector_field 描述两帧连续的图像间的光流
XLD(eXtended Line Description) 亚像素级别的,扩展的线性描述。
可以用来描述点,线,多边形,与Region有相似的特征,一个不同点在于XLD可以是不封闭的,可以采用一些相关的算子将xld连接起来
读例程 union_contours_xld例程,了解几个xld相关的算子
*
* This example program demonstrates the use of union_collinear_contours_xld for connecting
* collinear line segments. This is the new and recommended operator for this task.
* In addition, the program shows how to use the old operator union_straight_contours_xld for
* connecting contours that are not collinear but have neighboring end points.
*
dev_close_window ()
read_image (Image, 'pads')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_set_colored (12)
dev_set_draw ('margin')
dev_display (Image)
*
* Remove border
*
Border := 35
rectangle1_domain (Image, ImageReduced, Border, Border, 576 - Border, 768 - Border)
*
* Extract edges in the image and detect straight line segments
* Unify collinear line segments and keep only the long ones
*
* edges_sub_pix (ImageReduced, Edges, 'lanser2', 0.16, 3, 5)
* 找到亚像素边缘
edges_sub_pix (ImageReduced, Edges, 'canny', 5, 3, 5)
* 分割出满足条件的xld
segment_contours_xld (Edges, ContoursSplit, 'lines', 5, 4, 2)
* 选择出我们想要的xld,这里选择了轮廓长度大于20,小于图像长度的一半的轮廓。此处最后两个参数不起作用。
select_contours_xld (ContoursSplit, SelectedContours, 'contour_length', 20, Width / 2, -0.5, 0.5)
* 连接在一条直线上的xld
union_collinear_contours_xld (SelectedContours, UnionContours, 10, 1, 8, 0.4, 'attr_keep')
* 再根据轮廓总长度做一次选择
select_contours_xld (UnionContours, SelectedContours1, 'contour_length', 50, 10000, -0.5, 0.5)
*
dev_display (Image)
dev_display (SelectedContours1)
stop ()
*
* Further processing (1): connect neighboring contours and get the surrounding box
*
* 将非常靠近的轮廓连接起来
union_adjacent_contours_xld (SelectedContours1, UnionContours1, 20, 1, 'attr_keep')
* 拟合出最相近的矩形,除了第一个参数是输入,其他参数都是输出,表现了这个矩形的一些特性
smallest_rectangle2_xld (UnionContours1, Row, Column, Phi, Length1, Length2)
* 将这个拟合出来的矩形创建出来
gen_rectangle2 (Rectangle, Row, Column, Phi, Length1, Length2)
stop ()
*
*
* Further processing (2): fit lines into the collinear contours
*
dev_display (Image)
* 轮廓拟合成直线
fit_line_contour_xld (SelectedContours1, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
for i := 0 to |RowBegin| - 1 by 1
* 从一个多边形生成一个xld,其实就是根据上面拟合出来的线段特征把线段创建出来
gen_contour_polygon_xld (Contour, [RowBegin[i],RowEnd[i]], [ColBegin[i],ColEnd[i]])
dev_display (Contour)
endfor
上面这个例子用到的方法主要就是提取亚像素边缘,按照一定的条件分割轮廓,再按照一定的条件筛选组合轮廓,最后拟合出大概的形状。
这个例子可以用来做定位吧?
算子
- segment_contours_xld(Contours, 输入值
ContoursSplit, 输出值
Mode, 分割模式,lines:分成直线;lines_circles/lines_ellipses:分成直线和曲线
SmoothCont, 光滑轮廓用到的点的数量,见下面的解释
MaxLineDist1, 使用拉莫算法的阈值
MaxLineDist2) 第二次使用拉莫算法的阈值,在比上一个阈值小的时候起作用
将轮廓按照一定的条件分割成xld:
下面翻译算子说明加了点理解
先将轮廓近似地用多边形分割,这样在弯曲弧形的轮廓会被过度分割。之后,临近的线条如果可以更好的用弧形来拟合的话,依次的用圆弧之类的来替换。
如果SmoothCont参数是一个大于1的值,那么会优先做光滑处理,(使用smooth_contours_xld(Contours, SmoothedContours, NumRegrPoints)算子,将轮廓上的点拟合到一条最小二乘法拟合出来的直线上,拟合直线用到的点的数量是NumRegrPoints,建议取值大于3),这能够减少非常细小的分割,而获得一个更加合适的用弧形的拟合,因为光滑操作消灭了一些在边缘上的外围的点(我的理解是游离于边缘之外的一些孤立点)。
多边形近似的初始化是通过拉莫-道格拉斯-普克算法来做的。(算子gen_polyfons_xld(Contours, Polygons, type, Alpha),MaxLineDist1就是这里的Alpha,这个算法将折线近似的表示成一些点的连线,并使点尽量的少,用来简化轮廓,只需要知道一个大概的走势。实现步骤:
对于图上的曲线, - 在点a-f之间画一条直线,求其他点到这条直线的距离,最远的那个点的距离为d,如果d<Alpha,则两边的点全部舍去,,否则线段两边所有点暂时保留,上图假设是点e最远且距离大于阈值;
- 在点a-e之间和e-f之间分别画一条直线,用上面同样的方法,发现点b到直线ae的距离最远且大于阈值;
- 连接ab,be,ef,假设c点和d点到线段be的距离已经全都小于阈值,则这两个点全部舍去,到此为止,已经不存在一条线段两边还有点存在,结束。)
最终得出的轮廓至少有三个像素长度,6个点。所有小于3个像素的轮廓或者小于6个点的轮廓都会被直接输出不做改变。 - select_contours_xld(Contours, SelectedContours, Feature, Min1, Max1, Min2, Max2) 通过多种特征选择出Xld轮廓
Feature的取值有很多种,参考官方文档进行选择。某些情况下Min2和Max2不起作用。 - union_collinear_contours_xld(Contours, 输入
UnionContours, 输出值
MaxDistAbs,
MaxDistRel,
MaxShift,
MaxAngle,
Mode) 是否保留轮廓的特征:attr_keep, attr_forget
将满足在同一直线上的条件的轮廓线段连接起来,这里怎样的情况算是在同一直线由后面四个参数决定。下面的图描述了这四个特征,图片来源于halcon帮助文档:
在图像左边的轮廓总是会被当做是参照物,来决定右边的轮廓是否和他在一条直线上。 - union_adjacent_contours_xld(Contours, UnionContours,MaxDistAbs, MaxDistRel, Mode)
将临近的轮廓连接起来,什么样的轮廓是临近的,由后面两个参数决定,这两个参数和上面那个算子的涵义是一样的。Mode也同上。 - fit_line_contour_xld (Contours, 输入值,轮廓
Algorithm, 输入值,最小二乘法拟合时,基于某一种算法来忽略离群点
MaxNumPoints, 拟合时使用的点的数量的最大值,-1表示所有点都使用
ClipingEndPoints, 拟合时忽略的开头和结尾的点的个数
Iterations, 迭代的最大次数
ClippingFactor, 消除离群值的削波系数,通常算法为huber或drop时给1.0,tukey时给2.0
RowBegin, 下面的参数都是输出,表示拟合出的直线的一些特征
ColBegin,
RowEnd,
ColEnd,
Nr,
Nc,
Dist)
轮廓拟合成直线