该例程的主要功能是线激光轮廓仪设备采集金属零件的 3D 轮廓数据,构建参考 3D 模型,再对多个待测零件做3D 表面对比检测,识别零件的凸起 / 凹陷缺陷(弯曲变形)。

一、工作流程

step 1: 创建线激光模型:配置轮廓参数、3D 缩放系数(未标定,仅近似坐标)

step 2:采集参考件数据:读取线激光的视差轮廓,重建参考 3D 模型

step 3:优化参考模型:三角剖分、重采样、创建表面匹配模型(用于对齐)

step 4:检测待测件逐件采集轮廓→3D 重建→与参考模型配准→计算表面距离→筛选缺陷

step 5:可视化缺陷:标记凸起(品红)、凹陷(红色)区域

其中Step4是整个工作流程的核心。

二、代码解析

1. 初始化线激光模型

* 配置线激光基础参数
NumProfiles := 441        //总扫描轮廓数(Y方向行数)
DisparityRange := 512    //视差范围(Z轴高度)
ProfileWidth := 626      //单条轮廓宽度(X轴像素数)

* 临时关闭区域裁剪,生成矩形ROI定义轮廓尺寸
get_system ('clip_region', ClipRegion)
set_system ('clip_region', 'false')
gen_rectangle1 (Rectangle, 0, 0, DisparityRange - 1, ProfileWidth - 1)
set_system ('clip_region', ClipRegion)

* 创建线激光模型:未标定模式(offset_scale)
create_sheet_of_light_model (Rectangle, 'calibration', 'offset_scale', SheetOfLightModelID)

* 设置3D缩放系数(将像素值转为近似实际尺寸)
ScaleX := 2    // X轴缩放(轮廓宽度方向)
ScaleY := 8    // Y轴缩放(扫描行间距)
ScaleZ := 1    // Z轴缩放(视差→高度)
Clip := 435    // Z轴裁剪阈值(过滤无效低高度点)

* 写入参数到线激光模型
set_sheet_of_light_param (SheetOfLightModelID, 'scale_x', ScaleX)
set_sheet_of_light_param (SheetOfLightModelID, 'scale_y', ScaleY)
set_sheet_of_light_param (SheetOfLightModelID, 'scale_z', ScaleZ)

说明:

1)calibration='offset_scale':未标定模式,仅用缩放系数将像素视差转为 3D 坐标,替代高精度标定,成本低、速度快,适合定性对比。

2)Rectangle:定义单条轮廓的有效区域。

3)缩放系数是经验值,让 3D 点间距近似真实零件尺寸,不代表绝对精度,完全满足表面对比需求。

2. 可视化初始化及采集参考件 3D 数据

* 窗口初始化
dev_update_off ()
dev_close_window ()
dev_open_window_fit_size (0, 0, ProfileWidth, NumProfiles, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
* 创建空图像,用于实时显示视差图
gen_image_const (Image, 'uint2', ProfileWidth, NumProfiles)

* 循环读取所有参考件轮廓,构建3D模型
for Index := 0 to NumProfiles - 1 by 1
    * 读取单条视差图像
    read_image (ImageModel, 'sheet_of_light/metal_part_1_disparity_line_' + Index$'03d')
    * 将轮廓添加到线激光模型(核心算子)
    set_profile_sheet_of_light (ImageModel, SheetOfLightModelID, [])
    
    * 实时绘制视差图(每5行刷新一次)
    get_grayval (ImageModel, gen_tuple_const(ProfileWidth,0), [0:ProfileWidth - 1], Grayval)
    set_grayval (Image, gen_tuple_const(ProfileWidth,Index), [0:ProfileWidth - 1], Grayval)
    if (Index % 5 == 0)
        dev_display (Image)
    endif
    * 显示进度
    Message := 'Measure reference object'
    Message[1] := 'Add profile ' + (Index + 1) + '/' + NumProfiles
    disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
endfor

算子说明:

1)set_profile_sheet_of_light:,将线激光采集的单条视差轮廓存入模型,自动拼接为完整 3D 点云。

2)包含有名称metal_part_1的零件模型是标准无缺陷零件。

3. 优化参考 3D 模型

该步骤主要是为稳健对比做准备。也是3D 表面对比的关键,原始点云稀疏、无拓扑,直接对比误差大,需要预处理。

* 1. 从线激光模型导出完整3D点云
get_sheet_of_light_result_object_model_3d (SheetOfLightModelID, Model3DAll)
* 2. 裁剪无效点:保留Z坐标在 [Clip, 800] 之间的点
select_points_object_model_3d (Model3DAll, 'point_coord_z', Clip, 800, Model3D)
* 3. 计算表面法向量(3D三角剖分前置条件)
surface_normals_object_model_3d (Model3D, 'mls', 'mls_force_inwards', 'true', ObjectModel3DNormals)
* 4. 贪婪三角剖分(构建3D曲面拓扑)
triangulate_object_model_3d (ObjectModel3DNormals, 'greedy', 'greedy_remove_small_surfaces', 200, TriangulatedObjectModel3D, Information)
* 5. 重采样点云:均匀加密,提升对比精度
max_diameter_object_model_3d (TriangulatedObjectModel3D, Diameter)
sample_object_model_3d (TriangulatedObjectModel3D, 'fast', Diameter * 0.002, [], [], Model3DSampled)
* 6. 创建表面匹配模型(用于待测件与参考件自动对齐)
create_surface_model (TriangulatedObjectModel3D, 0.03, 'model_invert_normals', 'true', SurfaceModelID)
* 参考模型显示
dev_clear_window ()
create_pose (1100, 1300, 35000, 140, 350, 55, 'Rp+T', 'gba', 'point', PoseDisplay)
Title := 'Reference object (uncalibrated measurement)'
Instructions[0] := 'Rotate: Left button'
Instructions[1] := 'Zoom:   Shift + left button'
Instructions[2] := 'Move:   Ctrl  + left button'
visualize_object_model_3d (WindowHandle, TriangulatedObjectModel3D, [], PoseDisplay, [], [], Title, [], Instructions, PoseOut)

代码说明:

1)三角剖分让离散点云变成连续曲面,后续可以精准计算点到面的距离。

2)重采样后点云密度均匀,避免因原始点疏密不均导致对比误差。

3)create_surface_model:生成3D 匹配模板,后续可以快速将待测件与参考件对齐。

4)可视化参考 3D 模型:visualize_object_model_3d 提供鼠标交互(旋转 / 平移 / 缩放)。

4. 批量检测待测件

该步骤主要功能是表面对比及缺陷检测。共检测 4 个待测件(SceneIndex=1~4),流程完全标准化。

NumScenes := 4
for SceneIndex := 1 to NumScenes by 1
    * 1. 重置线激光模型(清空历史轮廓,保留参数)
    reset_sheet_of_light_model (SheetOfLightModelID)
    gen_image_const (Image, 'uint2', ProfileWidth, NumProfiles)
    
    * 2. 读取待测件所有轮廓,重建3D点云
    for Index := 0 to NumProfiles - 1 by 1
        read_image (ImageSearch, 'sheet_of_light/metal_part_' + (SceneIndex + 1) + '_disparity_line_' + Index$'03d')
        * 实时显示视差图
        get_grayval (ImageSearch, gen_tuple_const(ProfileWidth,0), [0:ProfileWidth - 1], Grayval)
        set_grayval (Image, gen_tuple_const(ProfileWidth,Index), [0:ProfileWidth - 1], Grayval)
        if (Index % 5 == 0)
            dev_display (Image)
        endif
        * 添加轮廓到模型
        set_profile_sheet_of_light (ImageSearch, SheetOfLightModelID, [])
    endfor

    * 3. 导出待测件3D点云+裁剪无效点
    get_sheet_of_light_result_object_model_3d (SheetOfLightModelID, Scene3DAll)
    select_points_object_model_3d (Scene3DAll, 'point_coord_z', Clip, 800, Scene3D)
    
    * 4. 3D匹配:待测件与参考模型自动对齐
    find_surface_model (SurfaceModelID, Scene3D, 0.02, 0.2, 0, 'false', [], [], Pose, Score, NotUsed)
    refine_surface_model_pose (SurfaceModelID, Scene3D, Pose, 0, 'false', [], [], Pose, Score, SurfaceMatchingResultID)
    * 反转位姿,将待测件变换到参考模型坐标系
    pose_invert (Pose, PosesInvert)
    rigid_trans_object_model_3d (Scene3D, PosesInvert, ObjectModel3DRigidTrans)

    * 5. 核心:计算待测件与参考模型的表面距离(带符号)
    distance_object_model_3d (ObjectModel3DRigidTrans, Model3DSampled, [], 0.0, 'signed_distances', 'true')

    * 6. 筛选缺陷点(阈值:1.5倍扫描行间距,过滤噪声)
    select_points_object_model_3d (ObjectModel3DRigidTrans, '&distance', -1000, -ScaleY * 1.5, ObjectModel3DThresholdedUp)
    select_points_object_model_3d (ObjectModel3DRigidTrans, '&distance', ScaleY * 1.5, 1000, ObjectModel3DThresholdedDown)
    
    * 7. 聚类缺陷:连通域分析(去除孤立噪声点)
    connection_object_model_3d (ObjectModel3DThresholdedUp, 'distance_3d', ScaleY + 5, ObjectModel3DConnectedUp)
    connection_object_model_3d (ObjectModel3DThresholdedDown, 'distance_3d', ScaleY + 5, ObjectModel3DConnectedDown)
    
    * 8. 保留大缺陷(点数>200,过滤微小噪声)
    select_object_model_3d (ObjectModel3DConnectedUp, 'num_points', 'and', 200, 1000000, ObjectModel3DSelectedUp)
    select_object_model_3d (ObjectModel3DConnectedDown, 'num_points', 'and', 200, 1000000, ObjectModel3DSelectedDown)

    * 9. 可视化缺陷
    * 白色=参考模型,绿色=待测件,品红=上弯,红色=下弯
    visualize_object_model_3d (WindowHandle, [TriangulatedObjectModel3D,ObjectModel3DRigidTrans,ObjectModel3DSelectedUp,ObjectModel3DSelectedDown], [], PoseDisplay, VisParamNames, VisParamValues, Title, ['', '','#' + [1:NumErrors]], Instructions, PoseOut1)
endfor

Logo

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

更多推荐