目录

3. 3D Object Models

3.1获取3D对象模型

3.1.1 从头创建3D对象模型

3.1.2 从计算机辅助设计(CAD)数据中获取3D对象模型

3.1.3 通过3D重建获得3D对象模型

3.2  3D对象模型的内容 

3.2.1 3D对象模型中所包含的信息种类

3.2.2 从特定3D对象模型查询信息 

 3.3 修改3D对象模型

3.3.1 为后续的3D位姿识别准备3D对象模型

3.3.2 向3D对象模型添加属性

3.3.3 从3D对象模型中删除属性 

3.3.4修改3D对象模型的点集

3.3.5 变换3D对象模型

3.3.6组合3D对象模型

3.4 三维物体模型的特征提取

3.4.1计算或访问3D对象模型的特征 

3.4.2 根据特征选择3D对象模型

3.5 3D对象模型的匹配

3.5.1 配准3D对象模型

3.5.2 应用示例:从一组3D图像导出曲面模型

3. 3D Object Models

        3D对象模型是描述3D对象的数据结构。3D对象模型可以通过多种方式获得,并且它们可以包含不同类型的数据。此外,使用3D对象模型的不同操作对模型的内容有不同的要求。因此,并不是每个操作都可以应用于每个3D对象模型。概述图:

3.1获取3D对象模型

获取3D对象模型的各种方法一般为:

  • 通过显式设置位于对象表面上的点的坐标或通过显式设置简单3D形状的参数来从头创建
  • 从计算机辅助设计(CAD)的数据中获取
  • 由可用的3D重建方法导出

3.1.1 从头创建3D对象模型

3D对象模型可以通过使用近似对象表面的给定点创建;或用3D基元,诸如长方体、球体、圆柱体或平面的简单3D形状的参数从头开始创建。算子如下:

  • gen_empty_object_model_3dEmptyObjectModel3D)创建一个空的3D对象模型。
  • gen_object_model_3d_from_pointsXYZ , ObjectModel3D)创建由点组成的3D对象模型
  • gen_box_object_model_3dPoseLengthXLengthYLengthZ ,ObjectModel3D)创建一个长方体
  • gen_sphere_object_model_3d(PoseRadius(半径), ObjectModel3D)创建表示球体的 3D 对象模型,球体位置由Pose和R确定
  • gen_sphere_object_model_3d_center(XYZRadius : ObjectModel3D)创建球体,球心为(X,Y,Z)
  • gen_cylinder_object_model_3dPoseRadiusMinExtentMaxExtent , ObjectModel3D)创建表示圆柱体的 3D 对象模型。Pose的原点位于圆柱体的旋转轴上,并且定向使 z 轴与圆柱体的主方向对齐。 MinExtent 和 MaxExtent 表示旋转轴上圆柱体的最低点和最高点的 z 坐标。
  • gen_plane_object_model_3d(  PoseXExtentYExtent , ObjectModel3D)创建表示平面的 3D 对象模型。

以下例子为创建一个点组成的3d对象:

* 创建一个空的3d对象.
gen_empty_object_model_3d (ObjectModel3D)
* 
* 使用附加值设置立方体的点坐标

PointCoordX := [0.5, 0, 1, 1, 0, 0, 1, 1, 0] - 0.5
PointCoordY := [0, 1, 1, 1, 1, 0, 0, 0, 0] - 0.5
PointCoordZ := [0.5, 0, 0, 1, 1, 0, 0, 1, 1] - 0.5
set_object_model_3d_attrib_mod (ObjectModel3D, ['point_coord_x', 'point_coord_y', 'point_coord_z'], [], [PointCoordX,PointCoordY,PointCoordZ])
* 
* 显示这9个点
visualize_object_model_3d (WindowHandle, ObjectModel3D, [], DisplayPose, 'disp_pose', 'true', 'Define a cube by point coordinates', [], Instructions, DisplayPose)
* 

以下例子为通过指定参数来创建不同的3D基本体:

create_pose (0.1, 1.5, 88, 106, 337, 224, 'Rp+T', 'gba', 'point', PoseIn)
*生成一个元,圆心在(200,200),半径为100个像素单位,起始角度为0弧度,终止角度近似为2π,轮廓为顺时针,插值数为120
gen_circle_contour_xld (ContCircle, 200, 200, 100, 0, 6.28318, 'positive', 120)
*获得行列坐标
get_contour_xld (ContCircle, Row, Column)
*归一化
X := 3 * Row / max([Row,Column]) - 2
Y := 3 * Column / max([Row,Column]) - 2
* 
* 创建一个无限的平面
gen_plane_object_model_3d ([0, 0, 0, 0, 0, 0, 0], [], [], ObjectModel3DPlane1)
* 创建一个有限 的平面
gen_plane_object_model_3d ([1, 1, 1, 0, 50, 30, 0], X, Y, ObjectModel3DPlane2)
* 使用姿势创建一个球体。
gen_sphere_object_model_3d ([0, 0, 3, 0, 0, 0, 0], 0.5, ObjectModel3DSphere1)
* 创建球体和位置.
gen_sphere_object_model_3d_center (-1, 0, 1, 1, ObjectModel3DSphere2)
* 创建圆柱体.
gen_cylinder_object_model_3d ([1, -1, 2, 0, 0, 60, 0], 0.5, -1, 1, ObjectModel3DCylinder)
* Create a box.
gen_box_object_model_3d ([-1, 2, 1, 0, 0, 90, 0], 1, 2, 1, ObjectModel3DBox)
* 

3.1.2 从计算机辅助设计(CAD)数据中获取3D对象模型

如果对象的3D模型已经作为计算机辅助设计(CAD)模型可用,例如,作为DXF或PLY文件,则可以简单地将该模型读取为具有操作符read_object_model_3d的3D对象模型。说白了就是打开3D模型文件。

3.1.3 通过3D重建获得3D对象模型

        所有(校准的)3D重建方法都适用于显式或隐式地导出3D对象模型。例如,使用多视点立体可以明确地获得3D对象模型,而使用普通3D传感器可以获得X、Y和Z图像以及深度图像。X、Y和Z图像隐式包含3D对象模型所需的信息。因此,您可以使用运算符xyz_to_object_model_3d从X、Y和Z图像派生3D对象模型。

  • Depth from focus (DFF) 通过计算图像所有像素的焦点来提取距离信息。使用小景深计算物体表面与相机的距离。
  • Sheet of light 意指通过重建物体上的投射光线来测量物体的高度轮廓。
  • DFF 特别适用于小型物体,sheet of light 则适用于没有纹理的物体。

例子如下:

ImagePath := 'time_of_flight/'

read_image (Image, ImagePath + 'engine_cover_xyz_01')*读取图像

scale_image (Image, Image, .001, .0)*缩放图像,倍数为 g' := g * Mult(.001) + Add(.0)

zoom_image_factor (Image, Image, 2, 2, 'constant')*宽度x2,长度x2,作用对象为常量
decompose3 (Image, X, Y, Z)*拆分为三个通道的图像

xyz_to_object_model_3d (X, Y, Z, ObjectModel3DID)*基于三个单通道的图像创建3d模型

运算符xyz_to_object_model_3d将包含 3D 点的 X、Y 和 Z 坐标的图像三元组转换为 3D 对象模型。仅使用所有三个图像的相交域中的点。创建的 3D 对象模型,句柄在ObjectModel3D 中返回。

        如果只有(校准的)深度图像,即“Z图像”可用,可以创建人造X和Y图像,如下所示:X和Y图像必须具有与Z图像相同的大小。通过将Z图像的列号分配给X图像的每一行来创建X图像,通过将Z图像的行号分配给Y图像的每一列来创建Y图像,如图2.28中的简单(像素精确)版本所示。然后,可以将这样创建的X、Y和Z图像再次变换成3D对象模型。注意,以这种方式生成的X和Y图像通常仍然需要乘以以Z值为单位分别反映在X和Y方向上相邻点之间的距离的适当系数。

3.2  3D对象模型的内容 

  • 哪些信息通常可以存储在3D对象模型中
  • 如何查询特定3D对象模型中包含的信息

3.2.1 3D对象模型中所包含的信息种类

        由于3D对象模型可以通过多种方式获得,因此包含在3D对象模型中的信息因模型而异。例如,如果使用运算符gen_Object_Model_3D_From_Points从给定点显式创建3D对象模型,则此模型中的基本信息是一组点坐标。相比之下,由3D基本体的参数显式创建的模型不包含任何点,而是包含相应简单3D形状的参数。

        通常,特定3D对象模型的内容取决于用于创建或派生该模型的特定过程。例如,如果3D对象模型是从(校准的)3D重建方法(如立体视觉stereo vision、激光三角测量sheet of light或对焦测距depth from focus)生成的,则它包含点。如果在这样的3D对象模型内应用了3D基元拟合,则所得到的3D基元的模型包含点以及基元的参数。也就是说,这种3D基元的3D对象模型包含的参数比由其参数显式创建的3D基元的3D对象模型更多。

        从X、Y和Z图像获得的3D对象模型通常包含3D点的坐标和对应的2D映射,即3D点到2D图像坐标的映射,而通过多视点立体获得的3D对象模型可以包含许多进一步的信息。例如,曲面可以由三角形或多边形近似。也可以使用运算符Triangulate_Object_Model_3D将三角剖分显式应用于包含点的3D对象模型。

下面列出了3D对象模型中可能包含的不同类型的数据:

  • Point:三维点基本信息的坐标

        Triangles三角形:表示三角形的3D点的索引

        Lines:表示折线的3D点的索引

        Faces:表示面的3D点的索引

        Normals:法线向量

        xyz Mapping:3D点到图像坐标的映射

  •  Primitive:原始信息

        Primitive Type:基元的类型(平面、球体、长方体、圆柱体)

        Primitive Pose:描述基元的位置和方向的姿势

        Primitive Rms:基本体参数的精度(仅当通过将基本体适配到点云中来确定它们时才可用)

  • Extended Attributes:扩展属性

        Attribute Names属性名称:为3D对象模型定义的扩展属性的名称

        Attribute Types属性类型:为3D对象模型定义的扩展属性的类型

  • Additional Attributes其他属性

        Shape Based Data基于形状的数据:指示3D对象模型是否已准备好进行基于形状的3D匹配的标志

        Distance Computation距离计算:指示3D对象模型是否已准备好进行距离计算的标志 

 内容以属性的形式表示,可以使用运算符get_object_model_3d_params访问。

3.2.2 从特定3D对象模型查询信息 

      可以应用运算符get_object_model_3d_params。使用该操作符,您可以查询模型中是否包含特定信息,即所谓的“属性”。例如,可以查询三维对象模型是否包含基本体数据、点、点法线、三角形、面或二维映射。如果模型中包含属性,则可以使用相同的运算符查询其显式值。

        另一种检查3D对象模型实际内容的方法是在HDeDevelopment中使用特殊的检查窗口。在此第6.22.8节中所述。

 3.3 修改3D对象模型

  • 为随后的3D位姿识别做准备(参见3.3.1节)
  • 将属性添加到其内容(参见.3.2节)
  • 将其内容减少为选定的属性(参见3.3.3节),
  • 更改其包含的点集,例如,通过减少点数或通过选择具有特定特性的点(参见3.3.4节)
  • 对它们进行变换(参见3.3.5节),
  • 将多个3D对象模型合并为单个3D对象模型(参见3.3.6节)

3.3.1 为后续的3D位姿识别准备3D对象模型

         一些三维位置识别方法需要输入三维物体模型。特别是基于形状的3D匹配(第4.2节)和在3D基元拟合中应用的分割(第4.5节)需要特定信息,这些信息可能仅隐式包含在 3D 对象模型中。为这些 3D 位置识别方法之一准备 3D 对象模型,即启用更快的内部访问此信息时,可以使用算子prepare_object_model_3d。在这之中,用于基于形状的 3D匹配参数 Purpose 必须设置为 'shape_based_matching_3d',而对于 3D 分割,必须将其设置为“segmentation”。然后,类似于基于形状的 3D 匹配参数 Purpose 的 prepare_object_model_3d必须设置为“shape_based_matching_3d”。

3.3.2 向3D对象模型添加属性

        在某些时候需要向3D对象模型添加特定的属性,这些属性隐式地包含在3D对象模型中。我们可以使用不同的算子来使隐式信息显现,或手动添加或修改特定属性,例如:

  • set_object_model_3d_attribset_object_model_3d_attrib_mod 可用于手动向3D对象模型添加属性或修改已包含的属性。这两个运算符之间的主要区别在于,set_object_model_3d_attrib返回新的3D对象模型,而set_object_model_3d_attrib_mod更改输入的3D对象模型。除了可以获得3D对象模型的标准属性之外,还可以设置所谓的“扩展”属性,可以由用户定义新类型的属性并将其附加到模型。这些属性必须在参数名称前加一个“&”。
  • surface_normals_object_model_3d 可用于将法线属性添加到3D对象模型。
  • triangulate_object_model_3d可用于将三角形属性添加到由点及其法线组成的3D对象模型。返回的 3D 对象模型包含一个三角形网格,该网格要么完全适合 3D 对象模型中包含的点集(贪心算法),要么近似点集(隐式算法)。
  • fit_primitives_object_model_3d可用于获取与 3D 基元相关的属性。它可用于添加最适合原始 3D 对象模型中给定的点集的 3D 基元的参数。此类 3D 基元拟合通常先进行分割,将 3D 对象模型转换为具有相似特征的不同 3D 对象模型,详情见第 4.5 节所述。

以下例子为用set_object_model_3d_attribset_object_model_3d_attrib_mod为3D对象添加属性:(例程位置%HALCONEXAMPLES%\hdevelop\3D-Object-Model\Creation\
set_object_model_3d_attrib.hdev.)

*设置14个三角形定点的索引,索引对象来自前面设定的点,
*如 T1 := [0, 8, 5]中的数字(0, 8, 5)是指向顶点坐标数组
*(即 PointCoordX、PointCoordY、PointCoordZ)中特定位置的索引。
T1 := [0, 8, 5]
T2 := [0, 7, 8]
T3 := [0, 6, 7]
T4 := [0, 5, 6]
T5 := [5, 6, 2]
T6 := [5, 2, 1]
T7 := [6, 7, 3]
T8 := [6, 3, 2]
T9 := [7, 3, 4]
T10 := [7, 4, 8]
T11 := [8, 4, 1]
T12 := [8, 1, 5]
T13 := [2, 3, 4]
T14 := [2, 4, 1]
*添加三角形属性
set_object_model_3d_attrib (ObjectModel3D, 'triangles', [], \
[T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14], ObjectModel3D2)
* 显示三角形.
visualize_object_model_3d (WindowHandle, [ObjectModel3D2,ObjectModel3D2],\
 [], DisplayPose, VisualParamNames, VisualParamValues, 'Connect points to triangles', [], Instructions, DisplayPose)

下面再手动修改3d模型的属性,以下例子为用set_object_model_3d_attrib_mod修改模型的点的属性:

* 这里的操作也是索引,把PointCoordY数组中第0个数据改为-1
PointCoordY[0] := [-1]
set_object_model_3d_attrib_mod (ObjectModel3D2, 'point_coord_y', [], PointCoordY)

3.3.3 从3D对象模型中删除属性 

        为了减少存储在3D对象模型中的数据量,如果不再需要3D对象模型的选定属性,则可以从模型中移除这些属性。具体地,操作符copy_object_model_3d可用于复制3D对象模型,从而仅将所选属性复制到新的3D对象模型。示例代码:

*分割ObjectModel3DID,有两组参数名称,ParSegmentation用于分割,ParFitting用于拟合
*ValSegmentation,ValFitting是与上面参数名称对应的参数值。
*ObjectModel3DOutID包含了分割后的所有子模型,可以遍历这个数组,对每个子模型执行进一步的操作

segment_object_model_3d (ObjectModel3DID, [ParSegmentation,ParFitting], \
[ValSegmentation,ValFitting], ObjectModel3DOutID)

*一个遍历循环
for Index := 0 to |ObjectModel3DOutID| - 1 by 1(Index:这是一个变量,用于在循环中跟踪当前的索引值;0 to |ObjectModel3DOutID| - 1:这指定了循环的起始和结束索引。从0开始,到ObjectModel3DOutID元组的长度减1结束;by 1:这表示每次循环时Index增加1)
copy_object_model_3d (ObjectModel3DOutID[Index], 'primitives_all', \
CopiedObjectModel3DID)
(primitives_all'此值指定复制具有基元参数的属性(包括空基元))
endfor

3.3.4修改3D对象模型的点集

以下算子可以修改3D对象模型的点集或将3D对象模型分割成不同部分:

  • set_object_model_3d_attrib_mod 用法如上面3.3.2的例子,可用于直接修改点坐标
  • select_points_object_model_3d 将阈值应用于选定的属性,可用于点集的筛选
  • reduce_object_model_3d_by_view 通过将 3D 对象模型投影到虚拟视图来从 3D 对象模型中删除点 并删除给定区域之外的所有点。可用于将点集减少为位于指定2D区域内的一组点,该指定2D区域是为3D对象模型的指定2D投影定义的。
  • sample_object_model_3d 对3D 对象模型进行采样。可用于规定好点与点的距离然后进行均匀采样。可用于降低模型的点密度。但根据点之间的指定距离,生成的3D对象模型的点密度甚至可能高于原始模型的点密度。
  • simplify_object_model_3d 简化三角化 3D 对象模型。可用于减少三角化的3D对象模型的点数,比如对于3D对象模型的平滑部分,我们不需要太高的点密度。这可以用来通过降低模型的复杂性来让后续的算子调用更高效。通常,简化的3D对象模型的点密度是不均匀的。对于需要更多点来表示对象几何体的部分,点密度较高,而对于较平滑的部分,点密度较低。这与Sample_Object_Model_3D的结果形成对比,在Sample_Object_Model_3D中实现了均匀的点密度。
  • smooth_object_model_3d 平滑3D对象模型的曲面。通常用于为曲面三角剖分准备3D对象模型或平滑3D对象模型中的噪点。
  • segment_object_model_3d 将一组 3D 点分割为具有相似特征的子集。比如法线方向相同或曲率相似。这样的分割可以应用于3D基元拟合。
  • connection_object_model_3d 连接3D组件。设置属性或距离函数及其对应的阈值来决定两个组件是否被视为相连的标准。

        另一种有效减少处理步骤的方法是使用点数据的2D映射。通过调用类型设置为‘cartesian_faces’的object_model_3d_to_xyz ,3D对象模型(需要包含多边形面或三角面)被转换为三个图像X、Y和Z。因此,这三个图像只包含有关模型的那些部分的信息,这些部分可以由具有指定姿势和参数的相机观察,而隐藏部分被省略(参见图2.34)。使用xyz_to_object_model_3d 可以执行反向变换并获得简化的3D对象模型,例程在%HALCONEXAMPLES%\hdevelop\3D-Object-Model\Segmentation\reduce_object_model_3d_to_visible_parts.

        2D映射不仅可以减小模型的数据量,而且可用于曲面比较之类的任务,因为处理2D图像而不是3D点云,效率可以显著提高。在用任何校准方法观察场景中定位的3D对象模型之后,可以通过比较模型和场景各自的2D映射来检测模型和场景之间的潜在偏差。因此,在场景和模型的Z图像上使用sub_image,会产生一个图像,其中像素值越高表示场景和模型之间的偏差越大。通过应用合适的阈值来提取缺陷的域。可以在CamParam设置为‘xyz_map’的情况下调用reduce_object_model_3d_by_view,以便将点云缩减到相应的视图。

3.3.5 变换3D对象模型

3D对象模型可以通过多种方式进行空间变换。 

  • rigid_trans_object_model_3d

rigid_trans_object_model_3dObjectModel3DPose ,ObjectModel3DRigidTrans) 对3D模型进行刚醒变换,变换由pose决定,pose通常由 create_posepose_invertget_object_model_3d_params.获得

  • affine_trans_object _model_3d

affine_trans_object_model_3dObjectModel3DHomMat3D , ObjectModel3DAffineTrans)对模型进行仿射变换,HomMat3D通常由 算子hom_mat3d_identityhom_mat3d_scalehom_mat3d_rotatehom_mat3d_translate,  pose_to_hom_mat3d ( affine_trans_point_3d).获得

  • projective_trans_object_model_3d

projective_trans_object_model_3dObjectModel3DHomMat3DObjectModel3DProjectiveTrans)对模型进行投影变换,HomMat3D为齐次投影变换矩阵,可以用vector_to_hom_mat3d获得,该算子可以由两个点的变换得到对应的变换矩阵。

        需要注意注意,经变换的3D对象模型仅包含可由3D对象模型表示且可被变换的数据。例如,在仿射3D变换之后,变换的3D对象模型中将不包含3D基元。对于3D基元的变换,只有刚体变换才是合适的。

3.3.6组合3D对象模型

        将多个3D对象模型合并为单个3D对象模型,可以应用运算符union_object_model_3d。请注意,生成的模型仅包含所有输入3D对象模型中包含的那些属性。或者,可以使用fuse_object_model_3d将多个3D对象模型(在同一坐标系中)融合到一个曲面中。

示例参考:hdevelop\3D-Object-Model\Transformations\fuse_object_model_3d.hdev

3.4 三维物体模型的特征提取

以下各节介绍

  • 如何计算或访问3D对象模型的特定功能,
  • 如何根据3D对象模型的特定功能选择3D对象模型。

3.4.1计算或访问3D对象模型的特征 

        3D对象模型中显式或隐式地包含了几种特征。

        一方面,3D对象模型显式包含不同的属性,如第3.2节中所介绍的。这些属性可以与点坐标、法线、三角形、面或3D基本体的参数等特征相关,并且可以使用算子get_object_model_3d_params得到。

        另一方面,3D对象模型包含关于特定几何特征的隐式信息,可以用以下算子得到:

  • area_object_model_3d 计算3D对象模型的曲面面积
  • distance_object_model_3d 计算一个3D对象模型中的点到另一个3D对象模型中的点、三角形或基本体的距离,
  • max_diameter_object_model_3d 计算3D对象模型的最大直径,
  • moments_object_model_3d 计算3D对象模型的平均或中心二阶矩,
  • smallest_bounding_box_object_model_3d smallest_sphere_object_model_3d 计算围绕3D对象模型的最小边界框或最小球体,
  • volume_object_model_3d_relative_to_plane 如果3D对象模型中包含三角形或多边形列表,则计算3D对象模型相对于平面的体积
  • intersect_plane_object_model_3d 计算3D对象模型和平面之间的交点,并将横截面作为一组由线连接的3D点返回

(例如,参见下图,它显示了示例程序%HALCONEXAMPLES%\hDevelopment\3D-Object-Model\Transformations\intersect_plane_object_model_3d.hdev).的结果

3.4.2 根据特征选择3D对象模型

        如果有许多3D对象模型可用,但只需要那些具有特定功能的3D对象模型,则可以应用运算符select_object_model_3d。它根据全局特征(如是否存在特定属性或特征的特定值范围,如对象的平均直径或对象的体积)从3D对象模型阵列中选择3D对象模型。

        例如,在示例程序%HALCONEXAMPLES%\hdevelop\3D-Object-Model\
Features\select_object_model_3d.hdev中,3D 对象模型的连接组件的最大直径和体积仅用于选择具有特定尺寸的组件。

select_object_model_3d (ObjectModel3DTranslated, ['volume', \
'diameter_object'], 'and', [MinVolume,MinDiameter], \
[MaxVolume,MaxDiameter], ObjectModel3DSelected)

如下图所示:

3.5 3D对象模型的匹配

        HALCON提供了匹配表示同一对象或同一对象的重叠部分的3D对象模型的功能。这种匹配也称为3D对象模型的“配准”。

  • 介绍3D对象模型的配对和全局配准(参见3.5.1)
  • 展示如何使用 3D 对象模型的配准和进一步修改来派生曲面模型用于基于表面的 3D 匹配(参见第3.5.2节)。

3.5.1 配准3D对象模型

        使用算子register_object_model_3d_pair,可以在两个3D对象模型之间应用匹配,以获得描述它们之间空间关系的位姿。这一过程也称为3D对象模型的“配准”。匹配确定后然后被连续细化的初始位姿,使得两个3D对象模型的重叠部分之间的相互差异变得最小。最终位姿可用于将第一3D对象模型变换到第二3D对象模型的坐标系。注意,如果两个模型已在同一坐标系中可用,则它们之间的初始姿势已隐式已知。然后,运算符也可以应用于不执行初始匹配而只执行姿势细化的模式(Method=’icp’)。

  •  register_object_model_3d_pair(  ObjectModel3D1ObjectModel3D2MethodGenParamNameGenParamValue ,PoseScore) 搜索具有最佳对齐方式的两个 3D 对象模型之间的变换。此过程称为配准。在 Pose 中返回的转换可用于将 ObjectModel3D1 转换为第二个对象 ObjectModel3D2 的参考。Score 返回两个 3D 对象模型的重叠部分与非重叠部分的比率。如果两个对象不重叠,则不返回任何姿势。参数 Method 决定是通过“matching”计算初始相对位置,还是仅用’icp’细化。

        使用算子 register_object_model_3d_global ,可以改进许多 3D 对象模型之间的相对位置,这也称为 3D 对象模型的“全局配准”。特别是,如果一个 3D 对象由多个重叠的 3D 对象模型组成,则特定的重叠用于确定一个齐次变换矩阵阵组,可以使用这些矩阵对模型进行变换,从而细化所有模型之间的关系,即实现所有 3D 对象模型之间的最小互差,从而更好地表示完整的对象。

对于这两个算子,配准的结果通常用于通过运算符affine_trans_object_model_3d来变换初始3D对象模型。

3.5.2 应用示例:从一组3D图像导出曲面模型

例程:%HALCONEXAMPLES%\hdevelop\Applications\Robot-Vision\
reconstruct_3d_object_model_for_matching.hdev,使用配准从3D传感器获得的同一对象的一组视图中获取基于表面的3D匹配的唯一表面模型

3D传感器获得的视图:

步骤1:配准3D对象模型

        连续地读取多个3D对象模型,并将它们与之前的模型进行配准。配准后,每个模型相对于前一个模型的姿态被转换为一个齐次变换矩阵,并保存到一个列表中。同时,所有的注册过的3D对象模型也被保存到一个列表中。

// 读取一个初始的3D对象模型  
read_object_model_3d ('universal_joint_part/universal_joint_part_xyz_00.om3', \  
'm', [], [], ObjectModel3D, Status)  
  
// 将这个初始的3D对象模型保存到PreviousOM3变量中,以便后续使用  
PreviousOM3 := ObjectModel3D  
  
// 初始化一个列表(或数组)来保存所有配准过的3D对象模型  
RegisteredOM3s := ObjectModel3D  
  
// 循环遍历从1到NumTrainingImages-1的每一个索引  
for Index := 1 to NumTrainingImages - 1 by 1  
      
    // 根据索引读取新的3D对象模型,文件名是根据索引格式化的(例如:universal_joint_part_xyz_01.om3, universal_joint_part_xyz_02.om3等)  
    read_object_model_3d ('universal_joint_part/universal_joint_part_xyz_' + Index$'02d',             
                          \ 'm', [], [], ObjectModel3D, Status) 
  
    // 将新读取的3D对象模型与之前的模型(PreviousOM3)进行配准(对齐)  
    // 'matching'是配准的方法,'default_parameters'和'accurate'是配准的参数  
    register_object_model_3d_pair (ObjectModel3D, PreviousOM3, 'matching', \  
    'default_parameters', 'accurate', Pose, Score)  
      
    // 将配准得到的姿态(Pose)转换为齐次变换矩阵(HomMat3D)  
    pose_to_hom_mat3d (Pose, HomMat3D)  
      
    // 将新配准的3D对象模型添加到RegisteredOM3s列表中  
    RegisteredOM3s := [RegisteredOM3s,ObjectModel3D]  
      
    // 将得到的齐次变换矩阵添加到Offsets列表中  
    Offsets := [Offsets,HomMat3D]  
      
    // 将当前配准的3D对象模型设置为下一次循环的PreviousOM3  
    PreviousOM3 := ObjectModel3D  
endfor

上面为两张配准的图像,下面为配准后转换到相同坐标系的图像 

在所有的配准完成之后,所有3D对象模型都可以转换到第一个模型的坐标系中(见图,左侧)。这样转换的模型之间的关系然后通过全局配准和相应的仿射变换来细化(见图,右侧)。

// 使用全局配准(global registration)来将多个3D对象模型(RegisteredOM3s)相对于一个参考系进行配准  
// RegisteredOM3s是一个包含多个3D对象模型的列表  
// Offsets是一个包含之前计算得到的各个模型相对于前一个模型的齐次变换矩阵的列表  
// 'previous'指定了配准的顺序,即使用前一个模型作为参考  
// []是一个空的参数列表,用于某些可选参数(在此处未使用)  
// 'max_num_iterations'是一个可选参数,设置最大迭代次数为1(这可能是一个简化的设置,仅用于演示或快速配准)  
// HomMat3DRefined是输出参数,包含所有模型相对于参考系的最终齐次变换矩阵  
// Score是输出参数,包含配准过程的评分或质量度量  
register_object_model_3d_global (RegisteredOM3s, Offsets, 'previous', [], \  
    'max_num_iterations', 1, HomMat3DRefined, Score)  
  
// 使用得到的最终齐次变换矩阵(HomMat3DRefined)对原始配准的3D对象模型(RegisteredOM3s)进行仿射变换, 这将产生一组新的模型,这些模型都是相对于同一个参考系(通常是第一个模型或某个特定的参考点)对齐的  
// GloballyRegisteredOM3s是一个输出参数,包含变换后的3D对象模型列表  
affine_trans_object_model_3d (RegisteredOM3s, HomMat3DRefined, GloballyRegisteredOM3s)

左边为成对配准后的3D模型,右边为全局配准后的3D模型 

步骤2:从配准的3D对象模型中提取曲面模型

配准后的3D对象模型包括不同的结构,一部分为实际对象,另一部分为背景。从对准的3D对象模型集合中提取表面模型分几个步骤完成。首先,使用union_object_model_3d 将模型组合成单个3D对象模型(见图左侧)。用sample_object_model_3d获得具有较小且均匀的点密度的对象(见图右侧)。

// 将全局配准后的3D对象模型列表(GloballyRegisteredOM3s)合并为一个单一的3D对象模型  
// 'points_surface' 表示合并时将基于模型的表面点进行  
// UnionOptimized 是输出参数,包含合并后的优化后的3D对象模型  
union_object_model_3d (GloballyRegisteredOM3s, 'points_surface', \  
    UnionOptimized)  
  
// 设置采样点的最小数量,每个采样区域至少包5个点  
MinNumPoints := 5  
  
// 设置采样间隔 
SampleDistance := 0.5  

// 对合并后的3D对象模型(UnionOptimized)进行采样,'accurate' 是采样模式,
// sampleDistance 是之前设置的采样距离,'min_num_points' 是一个可选参数,指定每个采样区域的最小点数(之前已设置为5)   
sample_object_model_3d (UnionOptimized, 'accurate', SampleDistance, \  
    'min_num_points', MinNumPoints, SampleExact)

之后进行平滑处理,并计算曲面法线。

// 从3D对象模型SampleExact中获取其中心点坐标,并存储在变量Center中  
get_object_model_3d_params (SampleExact, 'center', Center)  
  
// 从3D对象模型SampleExact中获取其最小的封闭轴平行长方体,并存储在变量BoundingBox中   
get_object_model_3d_params (SampleExact, 'bounding_box1', BoundingBox)  
  
// 创建一个4x4的3D齐次变换矩阵HomMat3DTrans,并将其初始化为单位矩阵
hom_mat3d_identity (HomMat3DTrans)  
  
// 对HomMat3DTrans矩阵应用一个局部平移变换,  
// 将SampleExact的中心点平移到原点(0,0,0),并将边界框的最小Z坐标平移到Z=0平面(BoundingBox的数据为(min_x, min_y, min_z, max_x, max_y, max_z)) 
hom_mat3d_translate_local (HomMat3DTrans, -Center[0], -Center[1], \  
-BoundingBox[2], HomMat3DTranslate)  
  
// 使用HomMat3DTranslate矩阵对SampleExact进行仿射变换(这里主要是平移),  
// 并将变换后的对象模型存储在SampleExactTrans中  
affine_trans_object_model_3d (SampleExact, HomMat3DTranslate, \  
SampleExactTrans)  
  
// 对SampleExactTrans进行平滑处理,使用Moving Least Squares (MLS)方法,  
// 并强制平滑操作向模型内部进行('mls_force_inwards'为true),  
// 处理后的模型存储在SmoothObject3DTrans中  
smooth_object_model_3d (SampleExactTrans, 'mls', 'mls_force_inwards', \  
'true', SmoothObject3DTrans)  
  
// 计算HomMat3DTranslate矩阵的逆矩阵,即撤销之前平移的变换矩阵,  
// 并将逆矩阵存储在HomMat3DInvert中  
hom_mat3d_invert (HomMat3DTranslate, HomMat3DInvert)  
  
// 使用HomMat3DInvert矩阵对SmoothObject3DTrans进行仿射变换(这里是撤销之前的平移),  
// 并将撤销变换后的模型存储在SmoothObject3D中  
// 这样,SmoothObject3D就是SampleExact经过平滑处理后的版本,但其位置和原始SampleExact相同  
affine_trans_object_model_3d (SmoothObject3DTrans, HomMat3DInvert, \  
SmoothObject3D)

然后,使用triangulate_object_model_3d 对生成的模型进行三角剖分,并使用connection_object_model_3d 确定连接的组件(参见图2.42)。

// 使用贪心算法'greedy'对SmoothObject3D进行三角剖分,将结果存储在Surface3D中  
triangulate_object_model_3d (SmoothObject3D, 'greedy', [], [], Surface3D, \  
Information)  
  
// 对Surface3D进行连接操作,将连接后的对象模型存储在ObjectModel3DConnected中  
// 'mesh'表示返回 3D 对象模型中与三角形或多边形连接的部分
// 两个连接元件之间距离的最大值为“1” 
connection_object_model_3d (Surface3D, 'mesh', 1, ObjectModel3DConnected)

 3D对象模型(左)经过三角剖分和(右)分割成连通分量。

用算子select_object_model_3d将目标模型从背景中分离出来

// 使用select_object_model_3d函数从ObjectModel3DConnected中选择满足特定条件的3D对象模型  
// ['has_triangles', 'num_triangles'] 是一个特征列表,指定了两个条件:  
// 1. 'has_triangles' - 对象模型必须包含三角面片  
// 2. 'num_triangles' - 对象模型中的三角面片数量必须在指定的范围内   
// [1, 2000] 表示 'has_triangles' 条件的范围
// [1, 100000] 表示 'num_triangles' 条件的范围,即三角网格数量必须在1到100000之间  
// 选择的对象模型被存储在ObjectModel3DSelected中  
select_object_model_3d (ObjectModel3DConnected, ['has_triangles', 'num_triangles'], \'and', [1, 2000], [1, 100000], ObjectModel3DSelected)  
    
// 1. 'central_moment_2_x' - 对象模型关于其质心在x方向上的二阶中心矩(与x轴的惯性矩相关)  
// 2. 'central_moment_2_y' - 对象模型关于其质心在y方向上的二阶中心矩(与y轴的惯性矩相关)  
// 这两个中心矩通常用于描述对象模型的形状和方向   
// [150, 200] 表示 'central_moment_2_x' 的值在150到200之间  
// [400, 230] 表示 'central_moment_2_y' 的值在400到230之间
// 选择的对象模型被存储在ObjectModel3DCross中  
select_object_model_3d (ObjectModel3DSelected, ['central_moment_2_x', \  
'central_moment_2_y'], 'and', [150, 200], [400, 230], ObjectModel3DCross)

分离出来的表面模型: 

步骤3:使用表面模型进行基于表面的3D匹配

        首先在3D传感器获得的模型对象的初始视图上进行表面匹配(参见图2.44)。然后在不同视图的多视图立体图像中进行表面匹配(参见图2.45)。

对训练数据的一个视图进行基于表面的3D匹配的结果:

对多视点立体图像进行基于曲面的3D匹配的结果:

GitHub 加速计划 / vi / vision
36
0
下载
pytorch/vision: 一个基于 PyTorch 的计算机视觉库,提供了各种计算机视觉算法和工具,适合用于实现计算机视觉应用程序。
最近提交(Master分支:3 个月前 )
aa35ca19 14 小时前
96e77975 13 天前
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐