Halcon 3D 三维重建

一、简介

三维重建(3D Reconstruction)技术一直是计算机图形学和计算机视觉领域的一个热点课题。早期的三维重建技术通常以二维图像作为输入,重建出场景中的三维模型。但是,受限于输入的数据,重建出的三维模型通常不够完整,而且真实感较低。随着各种面向普通消费者的深度相机(depth camera)的出现,基于深度相机的三维扫描和重建技术得到了飞速发展。

 二、算子解释

1、为 3D 对象模型创建表面三角剖分。 triangulate_object_model_3d

*3D 对象模型 ObjectModel3D 生成三角形面的表面,并在 TriangulatedObjectModel3D 中返回结果表面
*ObjectModel3D 
*
*Method 三种三角剖分方法: 
*           'greedy', 
*           'implicit',
*           'polygon_triangulation'(多边形三角剖分)
*
*GenParamName 通用三角测量参数的名称
*         'greedy_fix_flips':启用/禁用算法的翻转解决步骤 ---- true' (default), 'false
*         'greedy_hole_filling':设置应考虑用于孔填充的表面边界长度(以点顶点数计)。如果指定了“false”,则禁用孔填充步骤
*         'greedy_kNN':指定邻域的大小 k。在寻找表面边界点的可达 SNC 邻居时,该算法仅考虑其最近的 k 个邻居
*         'greedy_mesh_dilation':指定膨胀周期数。在网格腐蚀之后应用网格膨胀。如果 'greedy_mesh_dilation' 设置为大于 'greedy_mesh_erosion' 的值,它将在内部减少为 'greedy_mesh_erosion' 的值。
*         'greedy_mesh_erosion':指定膨胀周期数。在网格腐蚀之后应用网格膨胀。如果 'greedy_mesh_dilation' 设置为大于 'greedy_mesh_erosion' 的值,它将在内部减少为 'greedy_mesh_erosion' 的值。
*         'greedy_neigh_latitude_tol', 
*         'greedy_neigh_orient_consistent',
*         'greedy_neigh_orient_tol', 
*         'greedy_neigh_vertical_tol',
*         'greedy_prefetch_neighbors', 
*         'greedy_radius_type':如果设置为 'fixed','greedy_radius_value' 以米为单位指定 SNC 半径 r。
*                               如果设置为“z_factor”,则通过将其 z 坐标乘以“greedy_radius_value”指定的值来计算每个点 P 的 r。 r 的这种表示适用于点的密度与它们与记录它们的传感器的距离相关的数据。这通常是深度传感器或 TOF 相机的情况。
*                               如果设置为“auto”,算法会在内部确定是使用“fixed”还是“z_factor”半径并估计其值。然后将估计值乘以“greedy_radius_value”中指定的值。这样,用户指定估计半径的比例因子。
*                               值列表:'auto'(默认)、'fixed'、'z_factor'
*         'greedy_radius_value':0.01, 0.05, 0.5, 0.66, 1.0, 1.5, 2.0, 3.0, 4.0
*         'greedy_remove_small_surfaces',
*         'greedy_suppress_timeout_error',
*         'greedy_timeout',
*         'implicit_min_num_samples',
*         'information' *3D 对象模型 ObjectModel3D 生成三角形面的表面,并在 TriangulatedObjectModel3D 中返回结果表面
*ObjectModel3D 
*
*Method 三种三角剖分方法: 
*           'greedy', 
*           'implicit',
*           'polygon_triangulation'(多边形三角剖分)
*
*GenParamName 通用三角测量参数的名称
*         'greedy_fix_flips':启用/禁用算法的翻转解决步骤 ---- true' (default), 'false
*         'greedy_hole_filling':设置应考虑用于孔填充的表面边界长度(以点顶点数计)。如果指定了“false”,则禁用孔填充步骤
*         'greedy_kNN':指定邻域的大小 k。在寻找表面边界点的可达 SNC 邻居时,该算法仅考虑其最近的 k 个邻居
*         'greedy_mesh_dilation':指定膨胀周期数。在网格腐蚀之后应用网格膨胀。如果 'greedy_mesh_dilation' 设置为大于 'greedy_mesh_erosion' 的值,它将在内部减少为 'greedy_mesh_erosion' 的值。
*         'greedy_mesh_erosion':指定膨胀周期数。在网格腐蚀之后应用网格膨胀。如果 'greedy_mesh_dilation' 设置为大于 'greedy_mesh_erosion' 的值,它将在内部减少为 'greedy_mesh_erosion' 的值。
*         'greedy_neigh_latitude_tol', 
*         'greedy_neigh_orient_consistent',
*         'greedy_neigh_orient_tol', 
*         'greedy_neigh_vertical_tol',
*         'greedy_prefetch_neighbors', 
*         'greedy_radius_type':如果设置为 'fixed','greedy_radius_value' 以米为单位指定 SNC 半径 r。
*                               如果设置为“z_factor”,则通过将其 z 坐标乘以“greedy_radius_value”指定的值来计算每个点 P 的 r。 r 的这种表示适用于点的密度与它们与记录它们的传感器的距离相关的数据。这通常是深度传感器或 TOF 相机的情况。
*                               如果设置为“auto”,算法会在内部确定是使用“fixed”还是“z_factor”半径并估计其值。然后将估计值乘以“greedy_radius_value”中指定的值。这样,用户指定估计半径的比例因子。
*                               值列表:'auto'(默认)、'fixed'、'z_factor'
*         'greedy_radius_value':0.01, 0.05, 0.5, 0.66, 1.0, 1.5, 2.0, 3.0, 4.0
*         'greedy_remove_small_surfaces',
*         'greedy_suppress_timeout_error',
*         'greedy_timeout',
*         'implicit_min_num_samples',
*         'information':  默认情况下('information'='num_triangles'),报告生成的三角形的数量。对于 'information'='verbose',返回名称-值信息对列表
*         'implicit_octree_depth':设置八叉树的深度。八叉树深度控制表面生成的分辨率 - 深度越高,表面分辨率越高。八叉树深度对运行时间有指数影响,对八叉树的内存需求有指数影响。因此,深度限制为 12。
*        'implicit_solver_depth':启用替代算法,该算法可以在原始算法接管其余计算之前将隐式函数准备到用户指定的八叉树深度。这个算法比原来的算法需要更少的内存,但速度有点慢。
*GenParamValue 通用三角测量参数的值: 6, 8, 12, 'true', 'false', 'auto', 'fixed', 'z_factor', 'verbose', 'num_triangles'
*
*TriangulatedObjectModel3D 具有三角形表面的 3D 对象模型的句柄
*


*         'implicit_octree_depth':设置八叉树的深度。八叉树深度控制表面生成的分辨率 - 深度越高,表面分辨率越高。八叉树深度对运行时间有指数影响,对八叉树的内存需求有指数影响。因此,深度限制为 12。
*        'implicit_solver_depth':启用替代算法,该算法可以在原始算法接管其余计算之前将隐式函数准备到用户指定的八叉树深度。这个算法比原来的算法需要更少的内存,但速度有点慢。
*GenParamValue 通用三角测量参数的值: 6, 8, 12, 'true', 'false', 'auto', 'fixed', 'z_factor', 'verbose', 'num_triangles'
*
*TriangulatedObjectModel3D 具有三角形表面的 3D 对象模型的句柄
*
*Information 默认情况下('information'='num_triangles'),报告生成的三角形的数量。对于 'information'='verbose',返回名称-值信息对列表

三、代码显示

* 
* This example program demonstrates how to use the operator
* triangulate_object_model_3d
* 
* 
* Init visualization
dev_close_window ()
dev_update_off ()
dev_open_window (0, 0, 800, 600, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
Instructions[0] := 'Rotate: Left button'
Instructions[1] := 'Zoom:   Shift + left button'
Instructions[2] := 'Move:   Ctrl  + left button'
ForcePause := 1.5
get_system_opengl_supported (WindowHandle, OpenGLSupported)
* 
* Overview of all default triangulation parameters (greedy mode):
* 'greedy_kNN' --> 40
* 'greedy_radius_type' --> 'auto'
* 'greedy_radius_value' --> 1.0
* 'greedy_neigh_orient_tol' --> 30
* 'greedy_neigh_orient_consistent' --> 'false'
* 'greedy_neigh_vertical_tol' --> 0.1
* 'greedy_neigh_latitude_tol' --> 30
* 'greedy_hole_filling' --> 40
* 'greedy_fix_flips' --> 'true'
* 'greedy_mesh_erosion' --> 0
* 'greedy_mesh_dilation' --> 0
* 'greedy_remove_small_surfaces' --> 'false'
* 'greedy_prefetch_neighbors' --> 'true'
* 'greedy_timeout' --> 'false'
* 'greedy_suppress_timeout_error' --> 'false'
* 'information' --> 'num_triangles'
* 
create_pose (-49.9194, 43.0534, 1343.74, 199.373, 27.1203, 3.17326, 'Rp+T', 'gba', 'point', Pose0)
read_object_model_3d ('mvtec_bunny.om3', 'mm', [], [], ObjectModel3D, Status)
if (OpenGLSupported)
    SamplingFactor := 0.003
    MeshMorpologyParams := [4,3,30000]
else
    SamplingFactor := 0.0053
    MeshMorpologyParams := [3,2,300]
endif
* The raw data contains a huge number of points. Although they can
* be triangulated as well, we sample down their number. This has two
* major advantages:
* - both the triangulation and the visualization of the objects are
*   much faster
* - the sub-sampling results in a smoother point cloud and hence -
*   a smoother triangulated surface
get_object_model_3d_params (ObjectModel3D, 'diameter_axis_aligned_bounding_box', Diameter)
*'diameter_axis_aligned_bounding_box'  :3D 点集的直径,定义为最小封闭轴平行长方体的对角线长度(参见参数 'bounding_box1')。该属性的长度为 1。
sample_object_model_3d (ObjectModel3D, 'fast', SamplingFactor * Diameter, [], [], RawPointData3D)
* 
* Inspect the point cloud data
visualize_object_model_3d (WindowHandle, RawPointData3D, [], Pose0, 'point_size', 1, 'Raw point data to be triangulated', [], Instructions, Pose)
* 
* 
* Triangulation with default settings
* 
* (Only 'information' is set to 'verbose', to give
* additional informations about the triangulation
* process.)
* 
* Display status
DescriptionText := []
ParameterNames := 'information'
ParameterValues := 'verbose'
Status := 'Performing triangulation with default settings ...'
disp_message (WindowHandle, [DescriptionText,Status], 'window', 12, 12, 'black', 'true')
* 
* Perform triangulation
count_seconds (Start)
*
triangulate_object_model_3d (RawPointData3D, 'greedy', ParameterNames, ParameterValues, Surface3DDefault, Info)
*3D 对象模型 ObjectModel3D 生成三角形面的表面,并在 TriangulatedObjectModel3D 中返回结果表面
*ObjectModel3D 
*
*Method 三种三角剖分方法: 'greedy', 'implicit', 'polygon_triangulation'(多边形三角剖分)
*
*GenParamName 通用三角测量参数的名称
*         'greedy_fix_flips':启用/禁用算法的翻转解决步骤 ---- true' (default), 'false
*         'greedy_hole_filling':设置应考虑用于孔填充的表面边界长度(以点顶点数计)。如果指定了“false”,则禁用孔填充步骤
*         'greedy_kNN':指定邻域的大小 k。在寻找表面边界点的可达 SNC 邻居时,该算法仅考虑其最近的 k 个邻居
*         'greedy_mesh_dilation':指定膨胀周期数。在网格腐蚀之后应用网格膨胀。如果 'greedy_mesh_dilation' 设置为大于 'greedy_mesh_erosion' 的值,它将在内部减少为 'greedy_mesh_erosion' 的值。
*         'greedy_mesh_erosion':指定膨胀周期数。在网格腐蚀之后应用网格膨胀。如果 'greedy_mesh_dilation' 设置为大于 'greedy_mesh_erosion' 的值,它将在内部减少为 'greedy_mesh_erosion' 的值。
*         'greedy_neigh_latitude_tol', 
*         'greedy_neigh_orient_consistent',
*         'greedy_neigh_orient_tol', 
*         'greedy_neigh_vertical_tol',
*         'greedy_prefetch_neighbors', 
*         'greedy_radius_type':如果设置为 'fixed','greedy_radius_value' 以米为单位指定 SNC 半径 r。
*                               如果设置为“z_factor”,则通过将其 z 坐标乘以“greedy_radius_value”指定的值来计算每个点 P 的 r。 r 的这种表示适用于点的密度与它们与记录它们的传感器的距离相关的数据。这通常是深度传感器或 TOF 相机的情况。
*                               如果设置为“auto”,算法会在内部确定是使用“fixed”还是“z_factor”半径并估计其值。然后将估计值乘以“greedy_radius_value”中指定的值。这样,用户指定估计半径的比例因子。
*                               值列表:'auto'(默认)、'fixed'、'z_factor'
*         'greedy_radius_value':0.01, 0.05, 0.5, 0.66, 1.0, 1.5, 2.0, 3.0, 4.0
*         'greedy_remove_small_surfaces',
*         'greedy_suppress_timeout_error',
*         'greedy_timeout',
*         'implicit_min_num_samples',
*         'information'
*         'implicit_octree_depth':设置八叉树的深度。八叉树深度控制表面生成的分辨率 - 深度越高,表面分辨率越高。八叉树深度对运行时间有指数影响,对八叉树的内存需求有指数影响。因此,深度限制为 12。
*        'implicit_solver_depth':启用替代算法,该算法可以在原始算法接管其余计算之前将隐式函数准备到用户指定的八叉树深度。这个算法比原来的算法需要更少的内存,但速度有点慢。
*GenParamValue 通用三角测量参数的值: 6, 8, 12, 'true', 'false', 'auto', 'fixed', 'z_factor', 'verbose', 'num_triangles'
*
*TriangulatedObjectModel3D 具有三角形表面的 3D 对象模型的句柄
*
*Information 默认情况下('information'='num_triangles'),报告生成的三角形的数量。对于 'information'='verbose',返回名称-值信息对列表
count_seconds (End)
TimeDefault := End - Start
force_pause (TimeDefault, ForcePause)
* If 'information' is set to 'verbose', a lot of useful
* information is returned by triangulate_object_model_3d
* dev_inspect_ctrl (Info)
* 
* Display results
VisParNames := ['disp_lines','color','line_color','alpha']
VisParValues := ['true','white','green',0.5]
Status := 'Execution time (default settings): ' + TimeDefault$'.2' + 's'
set_system ('flush_graphic', 'false')
dev_clear_window ()
set_system ('flush_graphic', 'true')
if (OpenGLSupported)
    KeyPoses := []
    KeyPoses := [KeyPoses,-29.0731,38.9057,261.771,180.149,29.2463,0.42091,0]
    KeyPoses := [KeyPoses,-29.0731,38.9057,261.771,180.149,29.2463,0.42091,0]
    KeyPoses := [KeyPoses,22.1251,63.0441,427.428,73.4444,86.7452,174.49,0]
    KeyPoses := [KeyPoses,22.1251,63.0441,427.428,73.4444,86.7452,174.49,0]
    KeyPoses := [KeyPoses,58.9778,21.3299,299.749,47.4176,17.0851,206.948,0]
    KeyPoses := [KeyPoses,58.9778,21.3299,299.749,47.4176,17.0851,206.948,0]
    Durations := [3.0,0.5,1.5,0.5,2.0,0.5]
    animate_object_model_3d (WindowHandle, Surface3DDefault, Pose, [Pose,KeyPoses,Pose0], [0.5,Durations,3.0], VisParNames, VisParValues, 'Resulting triangulation', Pose)
endif
delayed_clear_titled_window (WindowHandle, [], 12, 12, OpenGLSupported)
visualize_object_model_3d (WindowHandle, Surface3DDefault, [], Pose, VisParNames, VisParValues, [DescriptionText,Status], [], Instructions, Pose)
* 
* 
* Triangulation with mesh morphology
* 
* Following parameters enable the mesh morphology, to
* remove artifacts on the surface boundaries.
ParameterNames := ['greedy_mesh_erosion','greedy_mesh_dilation']
ParameterValues := MeshMorpologyParams[0:1]
* 
* Display status
DescriptionText := 'Mesh morphology is used to remove artifacts on the boundary'
Status := 'Performing triangulation with mesh morphology ...'
disp_message (WindowHandle, [DescriptionText,Status], 'window', 12, 12, 'black', 'true')
* 
* Perform triangulation
count_seconds (Start)
triangulate_object_model_3d (RawPointData3D, 'greedy', [ParameterNames,'information'], [ParameterValues,'verbose'], Surface3DMorphology, Info)
count_seconds (End)
TimeMorphology := End - Start
force_pause (TimeMorphology, ForcePause)
* 
* Display results
* object 的颜色  1 2 ,透明程度  背景
VisParNames := ['color_0','color_1','alpha','disp_background']
if (OpenGLSupported)
    Objects3D := [Surface3DMorphology,Surface3DDefault]
    VisParValues := ['green','red',0.5,'true']
else
    Objects3D := [Surface3DDefault,Surface3DMorphology]
    VisParValues := ['red','green',0.5,'true']
endif
Status := 'Execution time (with mesh morphology): ' + TimeMorphology$'.2' + 's'
Message := ['After mesh morphology (' + VisParValues[0] + ')','Default settings (' + VisParValues[1] + ')']
delayed_clear_titled_window (WindowHandle, Message, 65, 12, OpenGLSupported)
visualize_object_model_3d (WindowHandle, Objects3D, [], Pose, VisParNames, VisParValues, [DescriptionText,Status], [], Instructions, Pose)
* 
* 
* Triangulation with mesh morphology and surface removal
* 
* Following parameters enable the mesh morphology, to
* remove artifacts on the surface boundaries.
ParameterNames := ['greedy_mesh_erosion','greedy_mesh_dilation','greedy_remove_small_surfaces']
ParameterValues := MeshMorpologyParams
* 
* 
* Display status
DescriptionText := 'Additionaly you can remove undesired surface pieces.         '
Status := 'Performing triangulation with mesh morphology ...'
dev_clear_window ()
disp_object_model_3d_safe (WindowHandle, Objects3D, [], Pose, VisParNames, VisParValues)
disp_message (WindowHandle, [DescriptionText,Status], 'window', 12, 12, 'black', 'true')
* 
* Perform triangulation
count_seconds (Start)
triangulate_object_model_3d (RawPointData3D, 'greedy', [ParameterNames,'information'], [ParameterValues,'verbose'], Surface3DErasure, Info)
count_seconds (End)
TimeSurfaceErasure := End - Start
force_pause (TimeSurfaceErasure, ForcePause)
* 
* Display results
VisParNames := ['color_0','color_1','alpha','disp_background']
if (OpenGLSupported)
    Objects3D := [Surface3DErasure,Surface3DMorphology]
    VisParValues := ['green','red',0.5,'true']
else
    Objects3D := [Surface3DMorphology,Surface3DErasure]
    VisParValues := ['red','green',0.5,'true']
endif
* 
Status := 'Execution time (with mesh erasure): ' + TimeSurfaceErasure$'.2' + 's'
Message := ['After surface erasure (' + VisParValues[0] + ')','After mesh morphology (' + VisParValues[1] + ')']
delayed_clear_titled_window (WindowHandle, Message, 65, 12, OpenGLSupported)
visualize_object_model_3d (WindowHandle, Objects3D, [], Pose, VisParNames, VisParValues, [DescriptionText,Status], [], Instructions, Pose)
* 
* 
* Triangulate with reduced number of neighbors (k-NN = 10)
* 
ParameterNames := [ParameterNames,'greedy_kNN']
ParameterValues := [ParameterValues,10]
* 
* Display status
DescriptionText := 'The number of neighbors has a direct impact over the'
DescriptionText[1] := 'triangulation speed. Reduce k-NN to 10 (default = 40)'
DescriptionText[2] := 'and compare execution times.'
Status := 'Performing triangulation with reduced number of neighbors ...'
dev_clear_window ()
disp_object_model_3d_safe (WindowHandle, Objects3D, [], Pose, VisParNames, VisParValues)
disp_message (WindowHandle, [DescriptionText,Status], 'window', 12, 12, 'black', 'true')
* 
* Perform triangulation
count_seconds (Start)
triangulate_object_model_3d (RawPointData3D, 'greedy', [ParameterNames,'information'], [ParameterValues,'verbose'], Surface3DkNN10, Info)
count_seconds (End)
TimeKNN10 := End - Start
force_pause (TimeKNN10, ForcePause)
* 
* Display results
VisParNames := 'color'
VisParValues := 'green'
Objects3D := Surface3DkNN10
Status := 'Execution time k-NN = 10: ' + TimeKNN10$'.2' + 's (compared to ' + TimeDefault$'.2' + 's (default settings))'
delayed_clear_titled_window (WindowHandle, [], 12, 12, OpenGLSupported)
visualize_object_model_3d (WindowHandle, Objects3D, [], Pose, VisParNames, VisParValues, [DescriptionText,Status], [], Instructions, Pose)
if (OpenGLSupported)
    * The sub-sampled 3d object used with OpenGL is big
    * enough to demonstrate what happens with too few
    * neighbors selected (KNN=5).
    * 
    * 
    * Triangulation with insufficient number of neighbors
    * 
    ParameterValues[find(ParameterNames,'greedy_kNN')] := 5
    * 
    * Display status
    DescriptionText := 'The number of neighbors must not be too small. An insufficient     '
    DescriptionText[1] := 'number of neighbors leads to inconsistent triangulation and'
    DescriptionText[2] := 'eventually increases the time of the triangulation as well.'
    Status := 'Performing triangulation with too few neighbors ...'
    dev_clear_window ()
    disp_object_model_3d_safe (WindowHandle, Objects3D, [], Pose, VisParNames, VisParValues)
    disp_message (WindowHandle, [DescriptionText,Status], 'window', 12, 12, 'black', 'true')
    * 
    * Perform triangulation
    count_seconds (Start)
    triangulate_object_model_3d (RawPointData3D, 'greedy', [ParameterNames,'information'], [ParameterValues,'verbose'], Surface3DkNN5, Info)
    count_seconds (End)
    TimeKNN5 := End - Start
    force_pause (TimeKNN5, ForcePause)
    * 
    * Display results
    Objects3D := Surface3DkNN5
    VisParNames := 'color_0'
    VisParValues := 'red'
    Status := 'Execution time k-NN = 5: ' + TimeKNN5$'.2' + 's (compared to ' + TimeKNN10$'.2' + 's with k-NN = 10)'
    delayed_clear_titled_window (WindowHandle, [], 12, 12, OpenGLSupported)
    visualize_object_model_3d (WindowHandle, Objects3D, [], Pose, VisParNames, VisParValues, [DescriptionText,Status], [], Instructions, Pose)
endif
* 
* 
* Cleanup memory
* 
dev_clear_window ()
disp_object_model_3d_safe (WindowHandle, Objects3D, [], Pose, VisParNames, VisParValues)
disp_message (WindowHandle, 'End of program', 'window', 12, 12, 'black', 'true')

猜你喜欢

转载自blog.csdn.net/weixin_39354845/article/details/125344507