第5章〓XLD XLD是eXtended Line Description的缩写,是HALCON中表示轮廓和多边形的数据结构。XLD是由直线连接起来的一系列二维控制点,与图像点和区域点用像素坐标表示的不一样,XLD中的二维点是以亚像素坐标表示的,亚像素坐标是一种将像素坐标细分从而得到更高分辨率的坐标,具有比像素坐标更高的精度,因此,XLD常被理解为亚像素轮廓,是HALCON中非常重要的数据结构之一。 本章主要介绍XLD的获取、XLD的特征和XLD的处理,涉及的知识点如下。  XLD的获取: 亚像素级边缘提取、亚像素阈值等。  XLD的特征: 基础特征、形状特征、点集特征、几何矩特征和特征筛选等。  XLD的处理: 创建、分割、合并、拟合等。 视频讲解 5.1XLD的获取 因为XLD具有亚像素精度,因此使用XLD来测量是实现高精度测量的有效方法,用于测量的XLD通常由测量图像通过边缘提取获取,HALCON支持像素级精度的边缘提取和亚像素级精度的边缘提取,如果像素级精度已经可以满足测量需求,则无须使用亚像素级精度的边缘提取,因为后者的运算需要消耗更多的时间。像素级的边缘提取不直接获取XLD,而是获取边缘的轮廓区域,该轮廓区域可以转换为XLD。亚像素级的边缘提取则可以直接获取XLD。 5.1.1亚像素级边缘提取 1. 边缘提取方法 亚像素级边缘提取最常用的算子是edges_sub_pix()。edges_sub_pix()是针对单通道灰度图像的算子,其内部实现了多种边缘提取算法,在边缘检测算法参数中选择需要的方法即可实现相应的边缘提取算法,实际使用时可以根据不同算法的测试效果选择合适的边缘提取算法,该算子的原型如下。 edges_sub_pix(Image : Edges : Filter, Alpha, Low, High :)  Image: 输入的单通道灰度图像。  Edges: 输出的XLD轮廓。  Filter: 边缘检测的算法。  Alpha: 边缘检测的平滑参数。  Low、High: 滞后阈值操作的低阈值和高阈值。 edges_sub_pix()实现的边缘检测方法都可以在参数Filter中选择,Filter包含使用递归实现的滤波器(根据Deriche、Lanser、Shen方法及其变体)和Canny提出的使用传统高斯导数的滤波器,默认值是canny。Alpha参数可以为边缘提取的滤波器设置平滑的程度(除了sobel相关的方法),对于使用递归实现的滤波器,Alpha越大平滑越小,而Canny滤波器方法则与之相反,Alpha越大平滑越大。平滑越大,滤波器的抗噪性越好,但是也降低了检测小细节的能力。edges_sub_pix()算子通过使用类似于滞后阈值操作的算法将边缘点链接到边缘,该操作通过参数Low和High设置实现,值低于Low的像素点则认为不是边缘,值高于High的像素点则认为是边缘,而介于Low和High之间的像素点则根据相邻像素点是否是边缘进行判断。 【例51】edges_sub_pix()实现亚像素级边缘提取示例。 *关闭窗口 dev_close_window() *读取图像 read_image(Image, 'rings_and_nuts') *打开适应图像大小的窗口 dev_open_window_fit_image(Image, 0, 0, -1, -1, WindowHandle) *对图像进行亚像素边缘提取 edges_sub_pix(Image, Edges, 'canny', 1, 20, 40) *显示 dev_display(Image) dev_display(Edges) 实例中使用默认的滤波器检测方法canny,其检测的边缘XLD效果如图5.1所示,图5.1(a)为检测原图,图5.1(b)为检测出来的边缘轮廓。 图5.1edges_sub_pix()边缘检测效果 亚像素边缘提取除了使用edges_sub_pix(),还有专门针对多通道彩色图像的edges_color_sub_pix()算子,该算子与edges_sub_pix()十分相似,此处不再详细解释。 2. 线条提取方法 除了边缘提取方法,HALCON还可以通过线条提取实现亚像素精度XLD获取,线条提取获取的是曲线结构的线条,其最常用的算子是lines_gauss()。lines_gauss()实现的也是单通道灰度图像的线条提取,与之对应的还有实现多通道彩色图像线条提取的算子lines_color()。lines_gauss()算子的原型如下。 * 单通道图像的亚像素线条提取 lines_gauss(Image : Lines : Sigma, Low, High, LightDark, ExtractWidth, LineModel, CompleteJunctions :)  Image: 输入的单通道灰度图像。  Lines: 提取的线条XLD。  Sigma: 要应用的高斯平滑量。  Low、High: 滞后阈值操作的低阈值和高阈值。  LightDark: 要提取暗的线条还是亮的线条。  ExtractWidth: 是否需要提取线宽。  LineModel: 用来调整线条位置的线条模型。  CompleteJunctions: 在线条不连续的地方是否添加连接。 lines_gauss()提取线条的方法是通过使用高斯平滑核的偏导数来确定图像中每个点在x和y方向上的二次多项式的参数来完成的,这是一个比较复杂的过程,相关参数选择可以做以下简单的参考: Sigma参数决定了平滑量的大小,值越大平滑越大,但是较大的平滑可能会导致线条的定位产生偏差。Low和High参数的原理类似于edges_sub_pix()中相同的参数,只不过对比的对象不是像素点,而是二阶偏导数,选择的Sigma越大,二阶偏导数就越小,因此应该选择相应较小的High和Low值。LineModel参数提供了三种不同的线条模型,用于调整线的位置和宽度,分别为条形线(LineModel='barshaped')、抛物线(LineModel='parabolic')和高斯线(LineModel='gaussian),条形线可以适用大多数情况,背光场景可以考虑另外两种线型,抛物线适用于线条比较清晰的情况,高斯线适用于线条不是特别清晰的情况。这些线条模型的选择只有在ExtractWidth为'true'时才有效。 【例52】lines_gauss()实现亚像素级线条提取的示例,效果如图5.2所示。 *关闭窗口 dev_close_window() *读取图像 read_image(Image, 'mreut4_3') *打开适应图像大小的窗口 dev_open_window_fit_image(Image, 0, 0, -1, -1, WindowHandle) *对图像进行亚像素线条提取 lines_gauss(Image, Lines, 1.5, 3, 8, 'light', 'true', 'bar-shaped', 'true') *显示 dev_display(Image) dev_display(Lines) 图5.2lines_gauss()线条提取效果 5.1.2亚像素阈值 HALCON提供了一个简单的通过阈值分割实现XLD提取的方法,该方法通过算子threshold_sub_pix()实现,该算子通过单个阈值,将图像的灰度值分割为高于阈值和低于阈值两部分,边界线即为提取的XLD,该算子适用于在照明条件稳定的情况下,作为快速边缘提取的替代方案,算子原型如下。 *单通道图像的亚像素阈值边界提取 threshold_sub_pix(Image : Border : Threshold :)  Image: 输入的单通道灰度图像。  Border: 提取的阈值边界XLD。  Threshold: 边界的阈值。 【例53】threshold_sub_pix()实现亚像素级阈值边界提取的示例,效果如图5.3所示。 *关闭窗口 dev_close_window() *读取图像 read_image(Image, 'pcb') *打开适应图像大小的窗口 dev_open_window_fit_image(Image, 0, 0, -1, -1, WindowHandle) *对图像进行亚像素阈值边界提取 threshold_sub_pix(Image, Border, 50) *显示 dev_display(Image) dev_display(Border) 图5.3threshold_sub_pix()边界提取效果 视频讲解 5.2XLD的特征 XLD的特征是XLD具有的基本内在属性,其包含基础特征、形状特征、点集特征和几何矩特征,可以计算这些特征值,作为测量结果输出,也可以根据这些特征值对XLD进行筛选,从而提取项目需要的XLD部分。 5.2.1特征类型 HALCON内置了检测XLD特征的工具,检测方法如图5.4中①~④步骤所示。第①步先选择一个XLD轮廓,单击选中该轮廓; 第②步单击图标所示的“打开特征检测”工具; 第③步在打开的特征检测工具中勾选xld选项,xld选项下有basic、shape、points和moments四组特征,分别对应基础特征、形状特征、点集特征和几何矩特征,所有勾选的特征项都会在特征检测工具右侧的数值栏中显示; 根据需要的特征,第④步可以右键单击数值栏中的特征项,选择“插入算子”项将代码插入程序中,便可在程序运行中获取需要的特征。但是这里需要注意,以这种方法插入特征算子获取的是整个XLD中所有轮廓的相应特征,而并非第①步选中的那个轮廓的特征,因此插入特征算子的方法仅适用于快速找到对应的特征检测算子,在这之前必须先通过特征筛选或排序等方式定位到需要检测的XLD轮廓。 图5.4XLD特征检测 1. 基础特征 XLD的基础特征包含轮廓面积、质心坐标、宽高及宽高比和轴向外接矩形,相应的特征计算算子如下。 *XLD面积和质心坐标的计算 area_center_xld(XLD : : : Area, Row, Column, PointOrder)  XLD: 输入的XLD。  Area: XLD闭合区域的面积。  Row、Column: XLD的质心坐标。  PointOrder: 沿边界的点顺序(正/负)。 *XLD宽高和宽高比的计算 height_width_ratio_xld(XLD : : : Height, Width, Ratio)  XLD: 输入的XLD。  Height、Width: XLD的高和宽。  Ratio: XLD的宽高比。 *XLD轴向外接矩形的计算,返回左上角和右下角的坐标 smallest_rectangle1_xld(XLD : : : Row1, Column1, Row2, Column2)  XLD: 输入的XLD。  Row1, Column1: XLD轴向外接矩形左上角的行列坐标。  Row2, Column2: XLD轴向外接矩形右下角的行列坐标。 2. 形状特征 XLD的形状特征包含轮廓圆度、紧密度、长度、凸度、矩形度、等效椭圆、等效椭圆特征、外接圆、最大点矩、方向、最小有向外接矩形,相应的特征计算算子如下: *XLD轮廓圆度的计算 circularity_xld(XLD : : : Circularity)  XLD: 输入的XLD。  Circularity: XLD的轮廓圆度。 *XLD紧密度的计算 compactness_xld(XLD : : : Compactness)  XLD: 输入的XLD。  Compactness: XLD的紧密度。 *XLD轮廓的长度计算 length_xld(XLD : : : Length)  XLD: 输入的XLD。  Length: XLD轮廓的长度。 *XLD凸度的计算 convexity_xld(XLD : : : Convexity)  XLD: 输入的XLD。  Convexity: XLD的凸度。 *XLD矩形度的计算 rectangularity_xld(XLD : : : Rectangularity)  XLD: 输入的XLD。  Rectangularity: XLD的矩形度。 *XLD等效椭圆的计算 elliptic_axis_xld(XLD : : : Ra, Rb, Phi)  XLD: 输入的XLD。  Ra、Rb: XLD等效椭圆的长半轴和短半轴。  Phi: 长半轴与短半轴的夹角。 *XLD等效椭圆特征的计算 eccentricity_xld(XLD : : : Anisometry, Bulkiness, StructureFactor)  XLD: 输入的XLD。  Anisometry: XLD等效椭圆的长半轴和短半轴之比。  Bulkiness: XLD等效椭圆面积与轮廓面积之比。  StructureFactor: XLD的结构因子,StructureFactor = Anisometry *Bulkiness - 1。 *XLD最小外接圆的计算 smallest_circle_xld(XLD : : : Row, Column, Radius)  XLD: 输入的XLD。  Row、Column: XLD最小外接圆的圆心坐标。  Radius: 最小外接圆的半径。 *XLD最大点距的计算 diameter_xld(XLD : : : Row1, Column1, Row2, Column2, Diameter)  XLD: 输入的XLD。  Row1、Column1: XLD第一个极值点坐标。  Row2、Column2: XLD第二个极值点坐标。  Diameter: 两个极值点的距离。 *XLD方向的计算 orientation_xld(XLD : : : Phi)  XLD: 输入的XLD。  Phi: XLD的弧度方向。 *XLD最小有向外接矩形的计算 smallest_rectangle2_xld(XLD : : : Row, Column, Phi, Length1, Length2)  XLD: 输入的XLD。  Row、Column: XLD最小有向外接矩形的中心坐标。  Phi: XLD最小有向外接矩形的方向。  Length1、Length2: XLD最小有向外接矩形的半长和半宽。 3. 点集特征 由于XLD是由直线连接起来的一系列二维控制点,因此这些点集也有相关的特征,XLD 的点集特征包含轮廓点集的面积及质心、等效椭圆及半轴比和方向,相应的特征计算算子如下。 *XLD中点集的面积及质心坐标的计算 area_center_points_xld(XLD : : : Area, Row, Column)  XLD: 输入的XLD。  Area: XLD中点集的面积,面积为点的数量。  Row、Column: XLD中点集的质心坐标。 *XLD中点集的等效椭圆的计算 elliptic_axis_points_xld(XLD : : : Ra, Rb, Phi)  XLD: 输入的XLD。  Ra、Rb: XLD中点集的等效椭圆的长半轴和短半轴。  Phi: XLD中的点集的等效椭圆的长半轴与短半轴的夹角。 *XLD中点集的等效椭圆的长短半轴之比计算 eccentricity_points_xld(XLD : : : Anisometry)  XLD: 输入的XLD。  Anisometry: XLD中点集的等效椭圆的长短半轴之比。 *XLD中点集的方向计算 orientation_points_xld(XLD : : : Phi)  XLD: 输入的XLD。  Phi: XLD中点集的方向。 4. 几何矩特征 XLD的几何矩包含两种类型,一种是XLD包围区域的几何矩,另一种是XLD点集的几何矩,相应的特征计算算子如下。 *XLD包围区域的几何矩计算 moments_xld(XLD : : : M11, M20, M02)  XLD: 输入的XLD。  M11、M20、M02: XLD包围区域的M11、M20、M02矩。  计算公式为Mij=∑(r,c)∈R(r0-r)i(c0-c)j,(r0,c0)为区域质心。 *XLD点集的几何矩计算 moments_points_xld(XLD : : : M11, M20, M02)  XLD: 输入的XLD。  M11、M20、M02: XLD点集的M11、M20、M02矩。  计算公式为Mpq=∑n-1i=0(ri-r-)p(ci-c-)q,(r-,c-)为点集质心。 5.2.2特征筛选 XLD的特征筛选是根据XLD的特征值,从XLD中提取出项目需要的那部分轮廓,HALCON提供了快捷的特征筛选工具特征直方图,其使用方法与区域的特征筛选方法一致,核心是使用算子select_shape_xld()进行筛选。下面以一个实例介绍XLD特征筛选的使用方法。 第一步: 读取检测图片,并提取检测图片的XLD轮廓,如图5.5所示,目标是通过特征筛选提取检测XLD中的圆孔。 图5.5检测图片及其XLD轮廓 第二步: 特征筛选。打开特征直方图,如图5.6中①图标位置的工具; 然后在②位置的特征中选择需要的XLD特征,这里需要提取圆孔,所以可以选择XLD的圆度特征; 接着在③的位置通过拖动限制范围的标线选择圆度的范围,可以根据图像中XLD的颜色变化观察是否选中需要的轮廓; 最后单击④处的“插入代码”按钮即可将筛选结果的代码插入自己的程序中。 图5.6XLD特征筛选 第三步: 进一步筛选结果。通过圆度筛选的结果如图5.7(a)所示,这时如果想进一步筛选其他轮廓,可以在第二步的图5.6的②位置添加一个特征属性,特征之间支持与、或两种运算; 也可以继续打开特征直方图对XLD进行筛选。本例继续提取环形排列的圆孔,环形排列的圆孔的面积基本一致,因此可以通过XLD的面积特征,将环形排列的圆孔轮廓提取出来,其效果如图5.7(b)所示。 图5.7特征筛选结果 【例54】XLD特征筛选示例。 *关闭窗口 dev_close_window() *读取图像 read_image(Image, 'tooth_rim') *打开适应图像大小的窗口 dev_open_window_fit_image(Image, 0, 0, -1, -1, WindowHandle) *对图像进行亚像素阈值提取 threshold_sub_pix(Image,Border,80) *用圆度特征筛选圆孔 select_shape_xld(Border, SelectedXLD, 'circularity', 'and', 0.68629, 0.99031) *用面积特征筛选环形排列的圆轮廓 select_shape_xld(SelectedXLD, SelectedXLD1, 'area', 'and', 260.8, 1661.7) *显示 dev_display(Image) dev_display(Border) dev_display(SelectedXLD) dev_display(SelectedXLD1) 视频讲解 5.3XLD的处理 使用XLD进行测量等任务通常需要对XLD进行一系列处理,才能得到需要的结果,这些处理过程通常包含创建、分割、合并和拟合等处理方法,根据测量需求的不同,这些处理方法应该灵活搭配使用才能获得理想的效果。 5.3.1创建 XLD处理的创建与5.1节XLD的获取内容有所不同,XLD的获取是通过提取图像的亚像素边缘得到XLD,而XLD处理的创建是通过已有的轮廓或多边形信息生成XLD,如给出圆心和半径就可以创建圆形轮廓的XLD,这种方式创建的XLD通常用于显示对比效果或为了方便程序的处理,以下是一些常用的创建XLD的算子。 *创建圆或者圆弧的XLD gen_circle_contour_xld(: ContCircle : Row, Column, Radius, StartPhi, EndPhi, PointOrder, Resolution :) *根据数组给出的多边形创建具有圆角的XLD gen_contour_polygon_rounded_xld(: Contour : Row, Col, Radius, SamplingInterval :) *根据数组给出的多边形创建XLD gen_contour_polygon_xld(: Contour : Row, Col :) *根据区域创建XLD gen_contour_region_xld(Regions : Contours : Mode :) *创建椭圆弧的XLD gen_ellipse_contour_xld(: ContEllipse : Row, Column, Phi, Radius1, Radius2, StartPhi, EndPhi, PointOrder, Resolution :) *根据多边形近似创建XLD gen_polygons_xld(Contours : Polygons : Type, Alpha :) *创建矩形的XLD gen_rectangle2_contour_xld(: Rectangle : Row, Column, Phi, Length1, Length2 :) *从骨架创建XLD gen_contours_skeleton_xld(Skeleton : Contours : Length, Mode :) 5.3.2分割 分割是实现提取既要轮廓的重要方法,HALCON提供了用于分割的算子segment_contours_xld(),该算子可以将已有的轮廓分割为线和线、线和圆、线和椭圆,算子原型如下。 *将XLD轮廓分割成线段和圆弧或椭圆弧 segment_contours_xld(Contours : ContoursSplit : Mode, SmoothCont, MaxLineDist1, MaxLineDist2 :)  Contours: 输入的XLD轮廓。  ContoursSplit: 被分割后的XLD轮廓。  Mode: 分割XLD轮廓的模型。  SmoothCont: 平滑轮廓的点数。  MaxLineDist1、MaxLineDist2: 轮廓与近似线之间第一次迭代和第二次迭代的最大距离。 以下是使用线和圆的模型对XLD分割的用法实例,分割之前XLD各段轮廓都是相连的,分割完之后轮廓被分割为线段和圆弧(彩色原图见文前彩插),效果如图5.8所示。 【例55】分割XLD示例。 *关闭窗口 dev_close_window() *读取图像 read_image(Image, 'circle_plate') *打开适应图像大小的窗口 dev_open_window_fit_image(Image, 0, 0, -1, -1, WindowHandle) *对图像进行亚像素阈值提取 threshold_sub_pix(Image,Border,80) *使用线和圆模型进行分割 segment_contours_xld(Border, ContoursSplit, 'lines_circles', 5, 4, 2) *显示 dev_display(Image) dev_display(Border) dev_display(ContoursSplit) 图5.8XLD分割示例(见彩插) 5.3.3合并 XLD处理中对于一些相近的或者同属一个形状,但是却断开的轮廓,HALCON提供了将它们合并起来的方法。常用的合并方法是合并相邻的XLD、合并共线的XLD和合并共圆的XLD,相关算子原型如下。 *合并相邻的XLD union_adjacent_contours_xld(Contours : UnionContours : MaxDistAbs, MaxDistRel, Mode :)  Contours: 输入的XLD轮廓。  UnionContours: 输出的XLD轮廓。  MaxDistAbs: XLD轮廓端点的最大距离。  MaxDistRel: XLD轮廓端点的最大距离与较长端轮廓线长度的比值。  Mode: 对轮廓附加属性的处理模型,是接收还是忽略。 *合并共线的XLD union_collinear_contours_xld(Contours : UnionContours : MaxDistAbs, MaxDistRel, MaxShift, MaxAngle, Mode :)  Contours: 输入的XLD轮廓。  UnionContours: 输出的XLD轮廓。  MaxDistAbs: XLD轮廓端点的最大距离。  MaxDistRel: XLD轮廓端点的最大距离与较长端轮廓线长度的比值。  MaxShift: 第二个轮廓到参考轮廓的回归线的最大距离。  MaxAngle: 两个轮廓的回归线之间的最大角度。  Mode: 对轮廓附加属性的处理模型,是接收还是忽略。 *合并共圆的XLD union_cocircular_contours_xld(Contours : UnionContours : MaxArcAngleDiff, MaxArcOverlap, MaxTangentAngle, MaxDist, MaxRadiusDiff, MaxCenterDist, MergeSmallContours, Iterations :)  Contours: 输入的XLD轮廓。  UnionContours: 输出的XLD轮廓。  MaxArcAngleDiff: 两个圆弧的最大角距。  MaxArcOverlap: 两个圆弧的最大重叠。  MaxTangentAngle: 连接线与圆弧切线之间的最大夹角。  MaxDist: 两个圆弧间距的最大长度。  MaxRadiusDiff: 两个圆弧对应的圆的最大半径差。  MaxCenterDist: 两个圆弧对应的圆的最大中心距离。  MergeSmallContours: 确定没有拟合圆的小轮廓是否也应该合并。  Iterations: 迭代的次数。 下面以5.3.2节分割的实例为基础,在分割后的XLD轮廓中,使用合并相邻XLD的方法,将分割后的XLD再次合并为相连的XLD(彩色原图见文前彩插),如图5.9(b)所示,详细合并过程如下。 【例56】合并XLD示例。 *关闭窗口 dev_close_window() *读取图像 read_image(Image, 'circle_plate') *打开适应图像大小的窗口 dev_open_window_fit_image(Image, 0, 0, -1, -1, WindowHandle) *对图像进行亚像素阈值提取 threshold_sub_pix(Image,Border,80) *使用线和圆模型进行分割 segment_contours_xld(Border, ContoursSplit, 'lines_circles', 5, 4, 2) *合并相邻XLD union_adjacent_contours_xld(ContoursSplit, UnionContours, 10, 1, 'attr_keep') *显示 dev_display(Image) dev_display(Border) dev_display(ContoursSplit) dev_display(UnionContours) 图5.9合并相邻XLD(见彩插) 5.3.4拟合 拟合是将不规则XLD转换为规则XLD的重要方法,HALCON对XLD拟合的方法主要提供了线拟合、圆拟合、椭圆拟合和矩形拟合,以下为主要拟合方法的算子原型。 *拟合直线XLD(直线方程为Y×Nr+C×Nc-Dist=0) fit_line_contour_xld(Contours : : Algorithm, MaxNumPoints, ClippingEndPoints, Iterations, ClippingFactor : RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)  Contours: 输入的XLD轮廓。  Algorithm: 直线拟合的算法。  MaxNumPoints: 用于计算的最大轮廓点数。  ClippingEndPoints: 在轮廓的开始和结尾处被忽略的点数。  Iterations: 最大迭代次数。  ClippingFactor: 用于消除异常值的剪切因子。  RowBegin、ColBegin: 输出的线段起始点的行列坐标。  RowEnd、ColEnd: 输出的线段结束点的行列坐标。  Nr、Nc: 输出的法向量的行列坐标。  Dist: 输出的直线到原点的距离。 *拟合圆XLD fit_circle_contour_xld(Contours : : Algorithm, MaxNumPoints, MaxClosureDist, ClippingEndPoints, Iterations, ClippingFactor : Row, Column, Radius, StartPhi, EndPhi, PointOrder)  Contours: 输入的XLD轮廓。  Algorithm: 拟合圆的算法。  MaxNumPoints: 用于计算的最大轮廓点数。  MaxClosureDist: 被认为是闭合轮廓的端点之间的最大距离。  ClippingEndPoints: 在轮廓的开始和结尾处被忽略的点数。  Iterations: 最大迭代次数。  ClippingFactor: 用于消除异常值的剪切因子。  Row、Column: 输出的圆心的行列坐标。  Radius: 输出的圆的半径。  StartPhi、EndPhi: 输出的起始点和终止点的角度。  PointOrder: 输出的沿边界的点顺序。 *拟合椭圆XLD fit_ellipse_contour_xld(Contours : : Algorithm, MaxNumPoints, MaxClosureDist, ClippingEndPoints, VossTabSize, Iterations, ClippingFactor : Row, Column, Phi, Radius1, Radius2, StartPhi, EndPhi, PointOrder)  Contours: 输入的XLD轮廓。  Algorithm: 拟合椭圆的算法。  MaxNumPoints: 用于计算的最大轮廓点数。  MaxClosureDist: 被认为是闭合轮廓的端点之间的最大距离。  ClippingEndPoints: 在轮廓的开始和结尾处被忽略的点数。  VossTabSize: 用于Voss方法的循环段的数量。  Iterations: 最大迭代次数。  ClippingFactor: 用于消除异常值的剪切因子。  Row、Column: 输出的椭圆圆心的行列坐标。  Phi: 输出的椭圆的主轴方向。  Radius1、Radius2: 输出的椭圆的长半轴和短半轴。  StartPhi、EndPhi: 输出的起始点和终止点的角度。  PointOrder: 输出的沿边界的点顺序。 *拟合矩形XLD fit_rectangle2_contour_xld(Contours : : Algorithm, MaxNumPoints, MaxClosureDist, ClippingEndPoints, Iterations, ClippingFactor : Row, Column, Phi, Length1, Length2, PointOrder)  Contours: 输入的XLD轮廓。  Algorithm: 拟合矩形的算法。  MaxNumPoints: 用于计算的最大轮廓点数。  MaxClosureDist: 被认为是闭合轮廓的端点之间的最大距离。  ClippingEndPoints: 在轮廓的开始和结尾处被忽略的点数。  Iterations: 最大迭代次数。  ClippingFactor: 用于消除异常值的剪切因子。  Row、Column: 输出的矩形中心的行列坐标。  Phi: 输出的矩形的主轴方向。  Length1、Length2: 输出的矩形的半长和半宽。  PointOrder: 输出的沿边界的点顺序。 继续以分割小节的实例为基础,在分割之后,通过特征筛选,将XLD中的所有圆弧提取出来,并将共圆的圆弧合并,之后再通过拟合圆的方法,实现所有圆的拟合并创建相应的圆,以完成本节的拟合示例(彩色图片见文前彩插),效果如图5.10所示,具体程序如下。 【例57】拟合XLD示例。 *关闭窗口 dev_close_window() *读取图像 read_image(Image, 'circle_plate') *打开适应图像大小的窗口 dev_open_window_fit_image(Image, 0, 0, -1, -1, WindowHandle) *对图像进行亚像素阈值提取 threshold_sub_pix(Image,Border,80) *用圆度特征筛选圆孔 segment_contours_xld(Border, ContoursSplit, 'lines_circles', 5, 4, 2) *特征筛选 select_shape_xld(ContoursSplit, SelectedXLD, ['circularity','contlength'], 'and', [0.0697,31.6], [1,2000]) *合并共圆 union_cocircular_contours_xld(SelectedXLD, UnionContours1, 0.5, 0.1, 0.2, 30, 10, 10, 'true', 1) *拟合圆 fit_circle_contour_xld(UnionContours1, 'algebraic', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder) *生成圆 gen_circle_contour_xld(ContCircle, Row, Column, Radius, 0, rad(360), 'positive', 1) *显示 dev_display(Border) dev_display(SelectedXLD) dev_display(UnionContours1) dev_display(ContCircle) 图5.10拟合示例XLD(见彩插) 5.3.5其他 XLD处理除了创建、分割、合并和拟合操作外,HALCON还提供了一些其他方面方便XLD使用的算子,有用于XLD轮廓集合运算的差集算子difference_closed_contours_xld()、交集算子intersection_closed_contours_xld()和并集算子union2_closed_contours_xld(); 有变换XLD形状的算子shape_trans_xld(),该算子可以将原有XLD形状变换为相应的凸包、椭圆、外接圆或外接矩形等形状; 有对XLD进行平滑的算子smooth_contours_xld(),使用该算子可以得到更光滑的曲线; 有对XLD进行排序的算子sort_contours_xld(),XLD排序之后使用循环配合select_obj()算子,有利于对感兴趣的轮廓进行逐个处理。 XLD处理算子的使用没有固定的模式,灵活搭配使用才能获得理想的效果。 在线测试 习题 5.1XLD获取的常见方法有哪些? 5.2XLD 的特征筛选包含哪些特征? 5.3XLD的分割、合并和拟合分别实现了什么功能?