当前位置:   article > 正文

Halcon 3D相关案例分享

halcon 3d


本文是工作和学习过程中整理的3D相关案例,内容包括但不限于: 预处理、检测、量测以及配准… 具体展开可见如下思维导图。

在这里插入图片描述

一、预处理

1、平滑滤波

平滑滤波用到的主要算子是:smooth_object_model_3d

算子说明

操作符smooth_object_model_3d使用方法指定的方法对ObjectModel3D中的3D点进行平滑处理。得到的平滑点在SmoothObjectModel3D中返回。目前,移动最小二乘法(Method=’ MLS ')是唯一支持的平滑方法。

对于每个点P, MLS平滑算法将一个平面或一个高阶多项式曲面与其k邻域(k个最近点)相匹配。曲面拟合实质上是对平面或多项式曲面参数分别进行加权最小二乘参数估计的一种标准方法。P的最近邻的贡献比其他点的贡献大,这是由下面带参数σ(sigma) 的加权函数控制的:

在这里插入图片描述

然后将点投射到表面上。对所有点重复这个过程,得到一个平滑的点集。(它们可以很容易地从表面参数计算出来)。因此,这些点被相应的法线作为平滑的副作用加以扩大。
通过将GenParamName设置为以下值之一,可以用GenParamValue设置额外的MLS特定参数:

  • “mls_kNN”:
    指定用于将MLS曲面与每个点匹配的最近邻k的数量。
    建议值:40、60(默认值)、80、100、400
  • “mls_order”:
    指定MLS多项式曲面的顺序。对于’mls_order’=1,表面是一个平面。
    建议值:1、2(默认值)、3
  • “mls_abs_sigma”:
    将加权参数指定为以米为单位的固定绝对值。要选择的值取决于点数据的规模。根据经验,可以选择P点与其k/2相邻点之间的典型距离。注意,对于不同密度的点数据设置一个绝对加权参数,可能会导致位于不同密度点数据部分的点的平滑结果不同。
    这个问题可以通过使用’mls_relative_sigma’来避免,它是与比例无关的,这也使它成为指定邻域加权的一种更方便的方法。注意,如果传递了’mls_abs_sigma’,则忽略’mls_relative_sigma’中的任何值。
    建议值:0.0001,0.001,0.01,0.1,1.0
  • “mls_relative_sigma”:
    指定一个乘法因子,用于计算点P的公式:
    注意,与所有点的全局参数不同,它是为每个点P计算的,因此使权重函数适应于它的邻域。这避免了在试图将全局参数(‘mls_abs_sigma’)设置为具有高度变化的点密度的点数据时可能出现的问题。但是请注意,如果设置了’mls_abs_sigma’,则忽略’mls_relative_sigma’。
    建议值:0.1、0.5、1.0(默认值)、1.5、2.0
  • “mls_force_inwards”:
    如果这个参数设置为“真”,所有的表面法线都指向“原点的方向”。用数学方法表示,可以保证法向量和从各自的曲面点到原点的向量的标量积是正的。如果生成的SmoothObjectModel3D用于基于表面的匹配,可能需要这样做,无论是作为create_surface_model中的模型,还是作为find_surface_model中的3D场景,因为在这里,法线的一致方向对于匹配过程非常重要。如果’mls_force_inwards’设置为’false’,则法向量的方向是任意的。
    可能的值:‘true’, ‘false’(默认值)
平滑效果图

在这里插入图片描述

二、检测

1、外观缺陷检测

基于3d算法开发的检测压伤、划伤等有深度信息的缺陷,主要算子:convex_hull_object_model_3d

算子说明

计算 ObjectModel3D 中给出的 3D 对象模型的凸包。 该运算符将凸包作为 3D 对象模型返回,其句柄为 ObjectModel3DConvexHull

如果输入点的某一维度完全没有偏差,则结果将由直线而不是三角形组成。

请注意,如果不再需要或应替换3D 对象模型,则必须首先通过调用运算符clear_object_model_3d 释放内存。

缺陷检测效果图

在这里插入图片描述

2、点云边界框

边界框用到的主要算子是:smallest_bounding_box_object_model_3d

算子说明

smallest_bounding_box_object_model_3d 计算 3D 对象模型点周围的最小边界框。 生成的边界框使用其坐标系 (Pose) 进行描述,该坐标系的方向使得框的最长边与 x 轴对齐,第二长边与 y 轴对齐,最小边与 z 轴对齐 。 边的长度以 Length1Length2Length3 的形式返回,按降序排列。 盒子可以是轴对齐的,也可以是定向的,可以通过类型来选择。 “定向”算法的计算成本明显高于“axis_aligned”算法,并且仅返回定向边界框的近似值。 请注意,定向边界框的算法是随机的,并且可以为每次调用返回不同的框。

为了检索“axis_aligned”框的角点,可以将运算符 get_object_model_3d_params 与参数“bounding_box1”一起使用。

边界框效果图

在这里插入图片描述

3、平面度检测

平面度检测用到的主要算子是:distance_object_model_3d

算子说明

操作符distance_object_model_3d计算三维对象模型ObjectModel3DFrom中的点到三维对象模型ObjectModel3DTo中的点、三角形、多边形或原语的距离。在3D对象模型ObjectModel3DFrom中,距离被存储为一个名为“&distance”的扩展属性。随后可以使用get_object_model_3d_params``查询该属性,或者使用select_points_object_model_3d或其他使用扩展属性的操作符处理该属性。

目标数据(点、三角形、多边形或原语)是根据ObjectModel3DTo中包含的属性选择的。它是根据以下优先级中数据的存在而选择的:原语、三角形、多边形和点。作为这种自动目标数据选择的替代方法,还可以使用通用参数’distance_to’设置目标数据类型(参见下面)。在计算到最终三角形的距离之前,操作符在内部对一般的非三角形多边形进行三角化。因此,用三角形对象调用操作符比用具有不同多边形面的对象调用它要快。

可以选择使用参数MaxDistance设置阈值。超过此阈值的距离设置为MaxDistance的值,即,值被剪切。设置MaxDistance可以显著加快该操作符的执行速度。如果MaxDistance设置为0,则不使用阈值。

如果Pose是非空元组,那么在计算距离之前,它必须包含一个应用于ObjectModel3DFrom中的点的Pose。可以使用通用参数‘invert_pose’(见下面)来反转这个位姿。

根据目标数据类型(点、三角形或原语),有几种计算距离的方法。其中一些方法在ObjectModel3DTo的元素上计算数据结构,以加速距离计算。可以使用操作符prepare_object_model_3d预先计算这些数据结构。这允许对distance_object_model_3d的多个调用来重用数据结构,从而节省了为每个调用重新计算数据结构的时间。对于具有非三角形多边形面的对象,操作符prepare_object_model_3d可以额外执行三角剖分并将其保存到对象中,以进一步加速distance_object_model_3d操作符。只有在将通用参数’distance_to’设置为’triangle '时才会执行这种三角测量。注意,与操作符triangulate_object_model_3d相反,这种三角划分并不清除polygons属性。

当计算到点或三角形的距离时,操作符可以选择返回ObjectModel3DFrom中每个点的最近点或三角形的索引,方法是将通用参数‘store_closest_index’设置为‘true’(参见下面)。索引在3D对象模型ObjectModel3DFrom中存储为扩展属性’&closest_index’。注意,在使用“体素”方法时,不能计算最近的索引。如果点到最近元素的距离超过MaxDistance中设置的最大距离,则最近的索引设置为-1。

可以选择计算到点、三角形或原语的带符号距离。因此,必须将通用参数’signed_distance ‘设置为’true’。注意,当使用“体素”方法结合点到点距离时,不能计算符号距离。

下面将介绍不同的目标类型和方法,并描述它们的优缺点。注意,操作符根据目标数据类型自动选择默认方法。可以使用通用参数’method’覆盖此方法。

计算点到点的距离有以下几种方法:

  • Linear search 线性搜索:

对于ObjectModel3DFrom中的每个点,计算到ObjectModel3DTo中的所有点的距离,并使用最小的距离。这种方法不需要预先计算数据结构,并且对于ObjectModel3DTo中的少量点来说是最快的。

  • KD-Tree:

ObjectModel3DTo中的点被组织在一个kd树中,这加快了对最近点的搜索。树的构造非常高效。搜索时间与ObjectModel3DTo中的点数近似为对数。但是,搜索时间不是恒定的,并且根据查询点在ObjectModel3DFrom中的位置可能会发生显著变化。

  • Voxel 体素:

ObjectModel3DTo中的点组织在一个体素结构中。这种体素结构允许在几乎恒定的时间内进行搜索。,独立于查询点在ObjectModel3DFrom中的位置和在ObjectModel3DTo中的点的数量。但是,准备这个数据结构需要几秒钟或几分钟。它特别适合使用prepare_object_model_3d进行预计算。

平面度效果图

在这里插入图片描述

三、量测

1、高度测量

高度测量用到的主要算子是:get_object_model_3d_params

算子说明

get_object_model_3d_params 允许访问给定 3D 对象模型的属性和元数据。 请求的属性或元数据的名称在通用参数GenParamName中传递,相应的值在 GenParamValue 中返回。 如果请求的属性或元数据不可用,则会引发异常。

get_object_model_3d_params 支持同时访问多个 3D 对象模型和多个属性。 请注意,属性或元数据可以具有不同的长度。 一些标准属性具有定义的长度,如下面的属性描述中所述。 其他属性的长度取决于实际的3D对象模型,可以通过将参数GenParamName设置为“num_points”、“num_triangles”、“num_polygons”或“num_lines”来查询。 因此,要获取标准属性“point_coord_x”的长度,请将 GenParamName 设置为“num_points”。

测量效果图

在这里插入图片描述

2、体积测量

体积测量用到的主要算子是:volume_object_model_3d_relative_to_plane

算子说明

Volume_object_model_3d_relative_to_plane 计算 3D 对象模型面下相对于平面的体积。 该平面由 Plane 中给出的姿势的 x-y 平面定义。

对于 ObjectModel3D,三角剖分或多边形列表必须可用。 使用默认设置,如果网格是有序的,则将计算 3D 对象模型的实际体积。 为了还涵盖网格未闭合或面排序不一致的情况,可以使用参数 ModeUseFaceOrientation 影响体积的计算。

体积的计算方法:

1)首先,计算通过将每个面投影到平面上而构造的棱柱的体积。

棱柱的各个体积可以是正值或负值,具体取决于面的方向(远离或朝向平面)或面的位置(在平面上方或下方)。 这可以通过参数 UseFaceOrientation 进行控制。

2)然后,根据参数模式将棱镜的体积相加。

Volume 中返回的体积是计算总和的绝对值。

测量效果图

在这里插入图片描述

四、配准

1、根据模型配准

模型配准用到的主要算子有:create_surface_modelfind_surface_modeldistance_object_model_3d

算子说明

1)create_surface_model

运算符 create_surface_model为 3D 对象模型 ObjectModel3D 创建基于表面的匹配模型。 例如,3D 对象模型可以先前使用 read_object_model_3d 从文件中读取,或者使用 xyz_to_object_model_3d 创建。 创建的表面模型在SurfaceModelID中返回。

创建模型后,可以使用 set_surface_model_param 设置表面模型的其他参数。

表面模型的创建要求3D对象模型包含点和法线。 可能有以下组合:

  • 点和点法线;
  • 点和三角形或多边形网格,例如来自 CAD 文件;
  • 点和 2D 映射,例如使用 xyz_to_object_model_3d 转换的 XYZ 图像三元组。

请注意,模型法线的方向和方位(向内或向外)对于匹配非常重要。 对于边缘支持的基于表面的匹配,法线需要指向内,并且模型必须包含三角形或多边形网格(见下文)。

表面模型是通过以一定距离对3D物体模型进行采样来创建的。 采样距离必须在参数 RelSamplingDistance 中指定,并相对于 3D 对象模型的轴平行边界框的直径进行参数化。 例如,如果 RelSamplingDistance 设置为 0.05 并且 ObjectModel3D 的直径为“10 厘米”,则从对象表面采样的点将相距大约“5 毫米”。 采样点用于算子 find_surface_model 中的近似匹配(见下文)。 采样点可以通过运算符 get_surface_model_param 使用值“sampled_model”获得。 请注意,应避免对象模型中的异常点,因为它们会破坏直径。 减少 RelSamplingDistance 会导致更多的点,进而导致更稳定但更慢的匹配。 增加 RelSamplingDistance 会导致点数减少,进而导致匹配稳定性降低但速度更快。

在这里插入图片描述

2)find_surface_model

算子 find_surface_model 在 3D 场景 ObjectModel3D 中找到表面模型 SurfaceModelID 的最佳匹配,并在 Pose 中返回它们的姿态。

匹配分为三步:

  • 近似匹配
  • 稀疏姿态细化
  • 稠密姿态细化

3)distance_object_model_3d

运算符 distance_object_model_3d 计算 3D 对象模型 ObjectModel3DFrom 中的点到 3D 对象模型 ObjectModel3DTo 中的点、三角形、多边形或图元的距离。 距离作为名为“&distance”的扩展属性存储在 3D 对象模型 ObjectModel3DFrom 中。 随后可以使用 get_object_model_3d_params查询该属性,或者使用 select_points_object_model_3d 或其他使用扩展属性的运算符进行处理。

目标数据(点、三角形、多边形或图元)是根据 ObjectModel3DTo 中包含的属性选择的。 它是根据数据的存在情况来选择的,按以下优先顺序:基本体、三角形、多边形和点。 作为自动目标数据选择的替代方案,还可以使用通用参数“distance_to”设置目标数据类型(见下文)。 在计算到结果三角形的距离之前,操作员对通用非三角形多边形进行内部三角剖分。 因此,使用三角化对象调用运算符比使用具有不同多边形面的对象调用运算符要快。

MaxDistance 可用于限制要计算的距离值的范围。 如果 MaxDistance 设置为 0,则计算所有距离。 如果将 MaxDistance 设置为其他值,则不会处理距离超过 MaxDistance 的点并将其设置为 MaxDistance。 因此,将 MaxDistance 设置为非 0 的值可以显着加快该运算符的执行速度。

如果 Pose 是非空元组,则它必须包含在计算距离之前应用于 ObjectModel3DFrom 中的点的姿势。 可以使用通用参数“invert_pose”反转姿态(见下文)。

根据目标数据类型(点、三角形或图元),可以使用多种计算距离的方法。 其中一些方法计算 ObjectModel3DTo 元素的数据结构,以加速距离计算。 这些数据结构可以使用操作符prepare_object_model_3d来预先计算。 这允许对 distance_object_model_3d 进行多次调用以重用数据结构,从而节省每次调用重新计算的时间。 对于具有非三角形多边形面的对象,算子prepare_object_model_3d还可以执行三角测量并将其保存到对象中,以进一步加速distance_object_model_3d算子。 仅当通用参数“distance_to”设置为“triangles”时,才会执行此三角测量。 请注意,此三角剖分与运算符 triangulate_object_model_3d 的三角剖分相反,不会清除多边形属性。

计算到点或三角形的距离时,可以选择通过将通用参数“store_closest_index”设置为“true”(见下文),返回 ObjectModel3DFrom 中每个点的最近点或三角形的索引。 该索引作为名为“&closest_index”的扩展属性存储在 3D 对象模型 ObjectModel3DFrom 中。 请注意,使用“体素”方法时无法计算最接近的索引。 如果点到其最近元素的距离超过 MaxDistance 中设置的最大距离,则最近索引将设置为 -1。

可选地,可以计算到点、三角形或基元的有符号距离。 因此,通用参数“signed_distances”必须设置为“true”。 请注意,将“体素”方法与点到点距离结合使用时,无法计算有符号距离。

下表列出了不同的目标数据类型、方法及其属性。 搜索时间是 ObjectModel3DFrom 中每个点的近似时间。 N 是 ObjectModel3DTo中目标元素的数量。

在这里插入图片描述

配准效果图

在这里插入图片描述

【备注】对源码有需求的,订阅专栏后在后台私信我~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/691988
推荐阅读
相关标签
  

闽ICP备14008679号