基于3D对象体积与直径特征的筛选

发布于:2025-06-07 ⋅ 阅读:(19) ⋅ 点赞:(0)

1,目的

  • 筛选出目标3D对象。

    效果如下:
    在这里插入图片描述


2,原理

  • 使用3D对象的体积与直径特征进行筛选。

3,代码解析

3.1,预处理2.5D深度图。
* 参考案例库:select_object_model_3d.hdev
* ************************************************************
* 目的:
*     筛选所需要的3D模型
* 原理:
*     基于3D对象的体积与直径特征进行筛选

* ************************************************************
* 
dev_update_off ()
dev_close_window ()
* Load X,Y,Z-Data, scale them to meter and generate a 3D object model
ImagePath := 'time_of_flight/'
* 加载2.5D深度图(带深度信息的图像)
read_image (Image, ImagePath + 'engine_cover_xyz_01')
* 将深度值(Z通道)缩小1000倍(实质是单位:mm->m)
scale_image (Image, Image, .001, .0)
* 长宽放大2倍用于增加细节观察
zoom_image_factor (Image, Image, 2, 2, 'constant')
decompose3 (Image, X, Y, Z)
xyz_to_object_model_3d (X, Y, Z, ObjectModel3DID)
* Compute a mesh (Delauney triangulation) of the model
prepare_object_model_3d (ObjectModel3DID, 'segmentation', 'true', [], [])

释疑解惑*

1,engine_cover_xyz-01.tif是什么图?

2.5D图,是通过深度传感器(如结构光相机)获取的‌二维投影深度图‌。每个像素存储三维坐标值(X/Y/Z轴),非传统RGB或灰度数据,像素值以浮点型(real)存储物理空间位置,单位为毫米级精度。

2,zoom_image_factor 对效果的影响?

zoom_image_factor (Image, Image, 2, 2, 'constant')

显示效果:
在这里插入图片描述

zoom_image_factor (Image, Image, 1, 1, 'constant')

显示效果:

在这里插入图片描述

对比可知:长宽放大2倍可增加细节观察

3,prepare_object_model_3d算子的作用?

用于优化 3D 对象模型(点云或网格)的核心预处理算子,其主要功能是为后续三维视觉任务(如匹配、分割、测量)提供标准化输入。

  1. 核心功能与技术细节

    • 数据规范化

      • 统一不同来源的 3D 数据格式(点云、网格模型等),修复拓扑缺陷(如孔洞填充、噪声过滤)。

      • ‌ 关键参数:

        • GenParamNames:指定预处理选项(如 'max_area_holes' 控制孔洞填充面积阈值)。
        • GenParamValues:设置参数值(如 'sampling' 调节点云采样密度)。
    • 几何特征计算

      • 自动生成法向量、曲率等几何属性,为基于形状的分割(segment_object_model_3d)或匹配(create_shape_model_3d)提供基础特征。
    • 多分辨率支持

      • 支持生成多层级细节模型(LOD),适应不同精度的处理需求,提升算法效率。
  2. 工业检测流程

‌ 预处理后提升后续算法效率 20%+
例如:

  1. 修复扫描点云的孔洞('max_area_holes' 设为实际缺陷尺寸)。
  2. 计算法向量辅助钣金件平面分割。

  1. 关键参数配置指南
参数 作用 典型值示例
Purpose 指定预处理目标: - 'shape_based_matching_3d'(匹配) - 'segmentation'(分割) 'segmentation'
GenParamNames 参数名数组: - 'point_coord_ranges'(坐标范围过滤) - 'distance_to'(邻近点距离) ['sampling','max_area_holes']
GenParamValues 对应参数值: - 采样密度 0.01(相对模型直径) - 最大孔洞面积 5.0(mm²) [0.02, 10.0]

  1. 与其他算子的协同应用

    • 分割优化‌:预处理后输入 segment_object_model_3d,支持基于曲率/颜色的智能分割。

    • 距离计算‌:为 distance_object_model_3d 提供拓扑完整的模型,确保距离精度。

    • 位姿调整‌:配合 rigid_trans_object_model_3d 实现坐标变换前的数据规范化。


  1. 注意事项

    • 必要性‌:若不调用该算子,后续操作(如分割)可能因缺失拓扑信息而失败或低效。
    • 性能平衡‌:过高的采样密度('sampling')会增大内存开销,需根据任务需求权衡。

示例:轴承检测中,通过 prepare_object_model_3d 填充球体表面扫描缺失点,使 gen_sphere_object_model_3d 生成的参考模型与实际点云精确对齐212。

作用前:

在这里插入图片描述

作用后:

在这里插入图片描述


3.2,去除背景,断开连接域
* Prepare the visualization and display the 3D object model
create_pose (0.058, -0.165, 0.660, 345.0, 355.0, 356.0, 'Rp+T', 'gba', 'point', Pose)
* 
* Instructions for visualize_object_model_3d
Instructions[0] := 'Rotate: Left button'
Instructions[1] := 'Zoom:   Shift + left button'
Instructions[2] := 'Move:   Ctrl  + left button'
* Configuration
CamParam := [0.01,0,7e-6,7e-6,352,288,710,576]
GenParamName := ['color','disp_pose','alpha','intensity']
GenParamValue := ['green','false',0.8,'none']
* 
dev_open_window (0, 0, 710, 576, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
* 
visualize_object_model_3d (WindowHandle, ObjectModel3DID, CamParam, Pose, GenParamName, GenParamValue, 'This scene will be segmented into single objects', [], Instructions, Pose)
* 
* Threshold the 3D object Model
MinValue := 0.500
MaxValue := 0.670
* 去除背景,筛选所需要的点云
select_points_object_model_3d (ObjectModel3DID, 'point_coord_z', MinValue, MaxValue, ObjectModel3DIDReduced)
visualize_object_model_3d (WindowHandle, ObjectModel3DIDReduced, CamParam, Pose, GenParamName, GenParamValue, 'Result after thresholding at z=' + (MaxValue * 1e3)$'.3' + 'mm from the camera', [], Instructions, Pose)
* 
* Calculate the connected components and the volume and diameter
* of each of the resulting object
GenParamName[0] := 'colored'
GenParamValue[0] := 12
* 断开连接域
connection_object_model_3d (ObjectModel3DIDReduced, 'distance_3d', 0.010, ObjectModel3DIDConnections)

ObjectModel3DIDConnections如图所示:

在这里插入图片描述


3.3,计算特征量:体积与直径
* 计算3D对象的相对于平面的体积
volume_object_model_3d_relative_to_plane (ObjectModel3DIDConnections, [0,0,MaxValue,0,0,0,0], 'signed', 'true', Volume)
* 计算3D对象的最大直径
max_diameter_object_model_3d (ObjectModel3DIDConnections, Diameter)
* 
* Display the results
dev_open_window (0, 720, 400, 576, 'black', WindowHandle1)
set_display_font (WindowHandle1, 14, 'mono', 'true', 'false')
Indices := [0:|ObjectModel3DIDConnections| - 1]
disp_message (WindowHandle1, ['Features of the connected components:',' ',' '], 'window', 12, 12, 'white', 'false')
ResultMessage := '  #  Max. diameter    Volume'
Sequence := [0:|ObjectModel3DIDConnections| - 1]
ResultMessage := [ResultMessage,Sequence$' 3' + '     ' + (Diameter * 1e3)$'7.1f' + ' mm  ' + (Volume * 1e3)$'7.3f' + ' dm³']
disp_message (WindowHandle1, ResultMessage, 'window', 50, 12, 'white', 'false')
dev_set_window (WindowHandle)
visualize_object_model_3d (WindowHandle, ObjectModel3DIDConnections, CamParam, Pose, GenParamName, GenParamValue, 'Found ' + |ObjectModel3DIDConnections| + ' connected components', '#' + Indices, Instructions, Pose)

释疑解惑

1,volume_object_model_3d_relative_to_plane的作用?

volume_object_model_d_relative_to_plane(  
    : :  
    ObjectModel3D,       // 输入3D模型句柄  
    Plane,               // 参考平面位姿或平面方程  
    Mode,                // 体积计算模式  
    UseFaceOrientation   // 是否考虑面片方向  
    : Volume             // 输出体积值  
)

  • 算子功能

计算3D对象模型相对于参考平面的体积分布,支持半空间体积分析和方向敏感计算。

  • 参数详解

    1. ObjectModel3D

      • 类型‌:输入对象

      • 要求‌:必须为三角化网格或包含多边形集合的3D模型。

      • 注意‌:若网格非封闭或面片不连续,计算结果受 ModeUseFaceOrientation 参数影响。

    2. Plane

      • 定义‌:标准平面方程参数 [a, b, c, d],对应方程 ax + by + cz + d = 0

      • 获取方式

        • 通过 fit_primitives_object_model_3d 拟合点云平面;
        • 手动定义(如 [0, 0, 1, -100] 表示 z=100 的平面)。
    3. Mode

控制体积计算模式,可选值及含义:

模式 计算逻辑 应用场景
'signed' 返回平面以上(正)和以下(负)体积的代数和(例:80 + (-40) = 40 需要方向信息的平衡分析
'unsigned' 返回平面上下体积绝对值之和(例:` 80
'positive' 仅计算平面以上体积(正值) 凸起特征测量(如焊接高度)
'negative' 仅计算平面以下体积(自动取绝对值) 凹陷或容器液位分析
  1. UseFaceOrientation

    • **'true'**‌:考虑三角面片的法向方向,精确判断面片与平面的相对位置(适用于CAD模型)。
    • ‌**'false'**‌:仅根据顶点位置判断面片在平面上/下(适用于点云数据)。
  2. Volume

    • 输出‌:根据 Mode 返回对应的体积值(单位与模型坐标一致)。
  • 工业应用示例

    1. ‌注塑件毛刺检测 ‌

      • 定义分型面平面,使用 'positive' 模式检测凸出异常体积。
    2. 容器液位测量

      • 设置液面平面,通过 'negative' 模式计算液体体积。
  • 注意事项

    • 模型质量‌:网格法向一致性会影响方向敏感模式(UseFaceOrientation='true')的结果精度19。

    • 性能优化‌:对非封闭模型,优先使用 'false' 模式以减少计算开销11。

Plane效果演示:

在这里插入图片描述

3.4,筛选出3D对象
* Select components by their volume and maximal diameter
* 
MinVolume := 0.35e-003
MaxVolume := 1.0e-003
MinDiameter := 185.0e-003
MaxDiameter := 300.0e-003
* *** Attention:
*     select_object_model_3d uses the plane [0,0,0,0,0,0]
*     for the volume calculation! Therefore we have
*     to transform the 3d object models, so that the
*     reference plane (as defined in the former call to
*     volume_object_model_3d_relative_to_plane) coincides to the
*     default plane.
hom_mat3d_identity (HomMat3DIdentity)
hom_mat3d_translate (HomMat3DIdentity, 0, 0, -MaxValue, HomMat3DTranslation)
hom_mat3d_invert (HomMat3DTranslation, HomMat3DInvert)
affine_trans_object_model_3d (ObjectModel3DIDConnections, HomMat3DTranslation, ObjectModel3DTranslated)
* Set a label for each part
for Index := 0 to |ObjectModel3DIDConnections| - 1 by 1
    set_object_model_3d_attrib_mod (ObjectModel3DTranslated[Index], '&Index', [], Index)
endfor
* 
volume_object_model_3d_relative_to_plane (ObjectModel3DTranslated, [0,0,0,0,0,0,0], 'signed', 'true', Volume1)
select_object_model_3d (ObjectModel3DTranslated, ['volume','diameter_object'], 'and', [MinVolume,MinDiameter], [MaxVolume,MaxDiameter], ObjectModel3DSelected)
* 
Title := ['Parts selected by using the following features: ','       ' + (MinVolume * 1e3)$'3.1f' + ' dm³ <= volume <= ' + (MaxVolume * 1e3)$'3.1f' + ' dm³','and:   ' + (MinDiameter * 1e3)$'.1f' + ' mm <= max. diameter <= ' + (MaxDiameter * 1e3)$'.1f' + ' mm']
* Create the labels
Label := []
for Index := 0 to |ObjectModel3DSelected| - 1 by 1
    get_object_model_3d_params (ObjectModel3DSelected[Index], '&Index', FormerIndex)
    Label := [Label,'#' + FormerIndex]
endfor
* 
if (|ObjectModel3DSelected| > 1)
    visualize_object_model_3d (WindowHandle, ObjectModel3DSelected, CamParam, [], GenParamName, GenParamValue, Title, Label, Instructions, Pose)
else
    Message := 'No object left after using the following features: '
    Message[1] := '       ' + (MinVolume * 1e3)$'3.1f' + ' dm³ <= volume <= ' + (MaxVolume * 1e3)$'3.1f' + ' dm³'
    Message[2] := 'and:   ' + (MinDiameter * 1e3)$'.1f' + ' mm <= max. diameter <= ' + (MaxDiameter * 1e3)$'.1f' + ' mm'
    disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
endif
* 
* Clear the 3d object models
dev_set_window (WindowHandle1)
dev_close_window ()
clear_object_model_3d ([ObjectModel3DID,ObjectModel3DIDReduced,ObjectModel3DSelected,ObjectModel3DTranslated,ObjectModel3DIDConnections])

筛选结果:

在这里插入图片描述

4,完整代码。

* 参考案例库:select_object_model_3d.hdev
* ************************************************************
* 目的:
*     筛选所需要的3D模型
* 原理:
*     基于3D对象的体积与直径特征进行筛选

* ************************************************************
* 
dev_update_off ()
dev_close_window ()
* Load X,Y,Z-Data, scale them to meter and generate a 3D object model
ImagePath := 'time_of_flight/'
* 加载2.5D深度图(带深度信息的图像)
read_image (Image, ImagePath + 'engine_cover_xyz_01')
* 将深度值(Z通道)缩小1000倍(实质是单位:mm->m)
scale_image (Image, Image, .001, .0)
* 长宽放大2倍用于增加细节观察
zoom_image_factor (Image, Image, 2,2, 'constant')
decompose3 (Image, X, Y, Z)
xyz_to_object_model_3d (X, Y, Z, ObjectModel3DID)
* Compute a mesh (Delauney triangulation) of the model
prepare_object_model_3d (ObjectModel3DID, 'segmentation', 'true', [], [])
* 
* Prepare the visualization and display the 3D object model
create_pose (0.058, -0.165, 0.660, 345.0, 355.0, 356.0, 'Rp+T', 'gba', 'point', Pose)
* 
* Instructions for visualize_object_model_3d
Instructions[0] := 'Rotate: Left button'
Instructions[1] := 'Zoom:   Shift + left button'
Instructions[2] := 'Move:   Ctrl  + left button'
* Configuration
CamParam := [0.01,0,7e-6,7e-6,352,288,710,576]
GenParamName := ['color','disp_pose','alpha','intensity']
GenParamValue := ['green','false',0.8,'none']
* 
dev_open_window (0, 0, 710, 576, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
* 
visualize_object_model_3d (WindowHandle, ObjectModel3DID, CamParam, Pose, GenParamName, GenParamValue, 'This scene will be segmented into single objects', [], Instructions, Pose)
* 
* Threshold the 3D object Model
MinValue := 0.500
MaxValue := 0.670
* 去除背景,筛选所需要的点云
select_points_object_model_3d (ObjectModel3DID, 'point_coord_z', MinValue, MaxValue, ObjectModel3DIDReduced)
visualize_object_model_3d (WindowHandle, ObjectModel3DIDReduced, CamParam, Pose, GenParamName, GenParamValue, 'Result after thresholding at z=' + (MaxValue * 1e3)$'.3' + 'mm from the camera', [], Instructions, Pose)
* 
* Calculate the connected components and the volume and diameter
* of each of the resulting object
GenParamName[0] := 'colored'
GenParamValue[0] := 12
* 断开连接域
connection_object_model_3d (ObjectModel3DIDReduced, 'distance_3d', 0.010, ObjectModel3DIDConnections)
* gen_plane_object_model_3d ([0,0,MaxValue,0,0,0,0], [-0.5,-0.5,0.5,0.5], [0.5,-0.5,-0.5,0.5],plane01)

* visualize_object_model_3d (WindowHandle, [plane01,ObjectModel3DIDConnections], [], [],\
                           ['color_0','color_'+[1:|ObjectModel3DIDConnections|-1],'alpha_0','disp_pose'], ['orange',gen_tuple_const(|ObjectModel3DIDConnections|-1,'green')  ,0.7,'true'], [], [], [], PoseOut)
* 计算3D对象的相对于平面的体积
volume_object_model_3d_relative_to_plane (ObjectModel3DIDConnections, [0,0,MaxValue,0,0,0,0], 'negative', 'true', Volume)
* 计算3D对象的最大直径
max_diameter_object_model_3d (ObjectModel3DIDConnections, Diameter)
* 
* Display the results
dev_open_window (0, 720, 400, 576, 'black', WindowHandle1)
set_display_font (WindowHandle1, 14, 'mono', 'true', 'false')
Indices := [0:|ObjectModel3DIDConnections| - 1]
disp_message (WindowHandle1, ['Features of the connected components:',' ',' '], 'window', 12, 12, 'white', 'false')
ResultMessage := '  #  Max. diameter    Volume'
Sequence := [0:|ObjectModel3DIDConnections| - 1]
ResultMessage := [ResultMessage,Sequence$' 3' + '     ' + (Diameter * 1e3)$'7.1f' + ' mm  ' + (Volume * 1e3)$'7.3f' + ' dm³']
disp_message (WindowHandle1, ResultMessage, 'window', 50, 12, 'white', 'false')
dev_set_window (WindowHandle)
visualize_object_model_3d (WindowHandle, ObjectModel3DIDConnections, CamParam, Pose, GenParamName, GenParamValue, 'Found ' + |ObjectModel3DIDConnections| + ' connected components', '#' + Indices, Instructions, Pose)
* 
* Select components by their volume and maximal diameter
* 
MinVolume := 0.35e-003
MaxVolume := 1.0e-003
MinDiameter := 185.0e-003
MaxDiameter := 300.0e-003
* *** Attention:
*     select_object_model_3d uses the plane [0,0,0,0,0,0]
*     for the volume calculation! Therefore we have
*     to transform the 3d object models, so that the
*     reference plane (as defined in the former call to
*     volume_object_model_3d_relative_to_plane) coincides to the
*     default plane.
hom_mat3d_identity (HomMat3DIdentity)
hom_mat3d_translate (HomMat3DIdentity, 0, 0, -MaxValue, HomMat3DTranslation)
hom_mat3d_invert (HomMat3DTranslation, HomMat3DInvert)
affine_trans_object_model_3d (ObjectModel3DIDConnections, HomMat3DTranslation, ObjectModel3DTranslated)
* Set a label for each part
for Index := 0 to |ObjectModel3DIDConnections| - 1 by 1
    set_object_model_3d_attrib_mod (ObjectModel3DTranslated[Index], '&Index', [], Index)
endfor
* 
volume_object_model_3d_relative_to_plane (ObjectModel3DTranslated, [0,0,0,0,0,0,0], 'signed', 'true', Volume1)
select_object_model_3d (ObjectModel3DTranslated, ['volume','diameter_object'], 'and', [MinVolume,MinDiameter], [MaxVolume,MaxDiameter], ObjectModel3DSelected)
* 
Title := ['Parts selected by using the following features: ','       ' + (MinVolume * 1e3)$'3.1f' + ' dm³ <= volume <= ' + (MaxVolume * 1e3)$'3.1f' + ' dm³','and:   ' + (MinDiameter * 1e3)$'.1f' + ' mm <= max. diameter <= ' + (MaxDiameter * 1e3)$'.1f' + ' mm']
* Create the labels
Label := []
for Index := 0 to |ObjectModel3DSelected| - 1 by 1
    get_object_model_3d_params (ObjectModel3DSelected[Index], '&Index', FormerIndex)
    Label := [Label,'#' + FormerIndex]
endfor
* 
if (|ObjectModel3DSelected| > 1)
    visualize_object_model_3d (WindowHandle, ObjectModel3DSelected, CamParam, [], GenParamName, GenParamValue, Title, Label, Instructions, Pose)
else
    Message := 'No object left after using the following features: '
    Message[1] := '       ' + (MinVolume * 1e3)$'3.1f' + ' dm³ <= volume <= ' + (MaxVolume * 1e3)$'3.1f' + ' dm³'
    Message[2] := 'and:   ' + (MinDiameter * 1e3)$'.1f' + ' mm <= max. diameter <= ' + (MaxDiameter * 1e3)$'.1f' + ' mm'
    disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
endif
* 
* Clear the 3d object models
dev_set_window (WindowHandle1)
dev_close_window ()
clear_object_model_3d ([ObjectModel3DID,ObjectModel3DIDReduced,ObjectModel3DSelected,ObjectModel3DTranslated,ObjectModel3DIDConnections])

网站公告

今日签到

点亮在社区的每一天
去签到