文章目录

      • 1,目的
      • 2,过程
      • 3,易混易错点
      • 4,代码详解
        • 4.1,初始化窗口
        • 4.2,创建多视角立体视觉模型。
        • 4.3,创建表面匹配模型
        • 4.4,多视角立体视觉重建管件堆表面模型
        • 4.5,管道接头查找匹配
      • 5,完整代码

1,目的

获取管件堆中管件接头的位姿,从而实现无序抓取。

效果如下:

在这里插入图片描述


2,过程

  • 多相机获取多视角的图像,这里是四个相机获取四个角度的图像。
  • 结合四个角度图像进行表面点云重建,获取图像中管件堆的点云
  • 进而再使用3D表面匹配实现对管道接头位姿的获取。

3,易混易错点

1, 通过标定获取的CameraPose实质是标定板在相机坐标系的位姿,并不是相机的位姿。相机的位姿其实是CameraPose的逆变换。

calibrate_cameras (CalibHandle, TmpCtrl_Errors)
get_calib_data (CalibHandle, 'camera', 0, 'params', CameraParameters)
get_calib_data (CalibHandle, 'calib_obj_pose', [0, >TmpCtrl_ReferenceIndex], 'pose', CameraPose)
* Calibration 01: Adjust origin for plate thickness
set_origin_pose (CameraPose, 0.0, 0.0, 0.001, CameraPose)

2,disp_3d_coord_system算子中的仿射变换,并不是使标定板坐标系原点与相机坐标系原点重合,而是为了在相机坐标系中‌可视化标定板坐标系的位置和方向,标定板坐标系原点与相机坐标系原点位置关系并不发生改变‌。 该算子直接使用CameraPose参数将标定板坐标系渲染到图像空间,保持其相对于相机坐标系的原始位姿关系。

3,pose_compose (Pose1,Pose2, PoseCompose)执行顺序是先执行Pose2变换,再执行 Pose1 变化。参数是有执行顺序,并不可以随意互换。
例如以下:

正确的合并:

pose_compose (BaseInCamPose, ToolInBasePose, ToolInCamPose)
pose_compose (ToolInCamPose, CalObjInToolPose, CalObjInCamPose)

错误的合并

pose_compose (ToolInBasePose,BaseInCamPose,  ToolInCamPose)
pose_compose ( CalObjInToolPose,ToolInCamPose, CalObjInCamPose)

4,代码详解

4.1,初始化窗口
* 案例库:locate_pipe_joints_stereo.hdev* 目的:
* 查找立体视觉获取的3D对象中管道连接头的立体位置* 过程:
* 采用四个相机采集的图像立体重建一堆管道连接头的三维表面* 基于表面的3D匹配,查找
* 
* 
*---------------------part01:初始化窗口
* *****
* Initializations:
* *****
* 
dev_close_window ()
dev_update_off ()
dev_get_preferences ('suppress_handled_exceptions_dlg', PreferenceValue)
dev_set_preferences ('suppress_handled_exceptions_dlg', 'true')
ImagePath := '3d_machine_vision/multi_view/'
ImagePrefix := 'multi_view_pipe_joints'
read_image (Image, ImagePath + ImagePrefix + '_cam_0_01')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_set_draw ('margin')
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
* 
* *****

4.2,创建多视角立体视觉模型。
*-------------------- Part02: 多视角立体视觉模型创建
* *****
* 2.1,Read the camera setup model from file and get the parameters
* and the poses of the cameras
tryread_camera_setup_model ('../four_camera_setup_model.csm', CameraSetupModelID)
catch (Exception)if (Exception[0] == 5200)* 初始化生成相机内参+外参init_camera_setup (CameraSetupModelID)elsethrow (Exception)endif
endtry
* 
* 2.2 ,获取多视角立体视觉模型参数
get_camera_setup_param (CameraSetupModelID, 'general', 'num_cameras', NumCameras)
* 需要特别注意:结合上下文可知Pose0应该是常见标定获取的camerapose的逆变换
* (camerapose为标定板在相机坐标系的位姿)
get_camera_setup_param (CameraSetupModelID, 0, 'pose', Pose0)
get_camera_setup_param (CameraSetupModelID, 1, 'pose', Pose1)
get_camera_setup_param (CameraSetupModelID, 2, 'pose', Pose2)
get_camera_setup_param (CameraSetupModelID, 3, 'pose', Pose3)
get_camera_setup_param (CameraSetupModelID, 0, 'params', CamParam0)
get_camera_setup_param (CameraSetupModelID, 1, 'params', CamParam1)
get_camera_setup_param (CameraSetupModelID, 2, 'params', CamParam2)
get_camera_setup_param (CameraSetupModelID, 3, 'params', CamParam3)* 
* Create a multi-view stereo model, initialize it, and clear
* the camera setup, which is no longer required* 2.3,创建双目立体视觉。
* 'surface_pairwise':基于成对图像进行表面重建
create_stereo_model (CameraSetupModelID, 'surface_pairwise', [], [], StereoModelID)
clear_camera_setup_model (CameraSetupModelID)* 2.4,多视角立体视觉模型参数设置*-----图像校正参数组* -> Subsampling X, Y, Z
* 设置下采样步长为3,可降低计算量但可能导致锯齿效应,需配合抗锯齿参数使用
set_stereo_model_param (StereoModelID, 'sub_sampling_step', 3)
* -> Interpolation aliasing by binocular image rectification
* 双线性插值('bilinear'),平衡校正图像的质量与计算效率
set_stereo_model_param (StereoModelID, 'rectif_interpolation', 'bilinear')
* 子采样系数1.2,轻微降低分辨率以加速处理
set_stereo_model_param (StereoModelID, 'rectif_sub_sampling', 1.2)* -----双目视差计算参数组* 采用归一化互相关('ncc')匹配算法,对光照变化鲁棒性强
set_stereo_model_param (StereoModelID, 'binocular_method', 'ncc')
* 视差计算的金字塔层级数,设置为1时单层直接计算,应用于高纹理/实时性要求高的场景
set_stereo_model_param (StereoModelID, 'binocular_num_levels', 1)
* 匹配掩模尺寸19×19像素,适合中等纹理场景
set_stereo_model_param (StereoModelID, 'binocular_mask_width', 19)
set_stereo_model_param (StereoModelID, 'binocular_mask_height', 19)
* 纹理阈值设为0,禁用纹理过滤,适用于低纹理场景
set_stereo_model_param (StereoModelID, 'binocular_texture_thresh', 0)
* 匹配分数阈值0.4,过滤低置信度匹配点
set_stereo_model_param (StereoModelID, 'binocular_score_thresh', 0.4)
* 启用左右一致性检查('left_right_check'),消除遮挡区域误匹配
set_stereo_model_param (StereoModelID, 'binocular_filter', 'left_right_check')
* 子像素优化模式为插值法('interpolation'),提升深度分辨率
set_stereo_model_param (StereoModelID, 'binocular_sub_disparity', 'interpolation')*------ 空间约束和相机约束* 定义3D工作空间为[-0.2,-0.07,-0.075]到[0.2,0.07,-0.004](单位:米),自动计算视差范围
* 边界框(bounding_box)可约束重建范围,提升效率
set_stereo_model_param (StereoModelID, 'bounding_box', [-0.2,-0.07,-0.075,0.2,0.07,-0.004])
* 配置相机对为(0,2)和(1,3),支持多相机阵列的灵活组合
set_stereo_model_image_pairs (StereoModelID, [0,2], [1,3])

释疑解惑:
1,算子create_stereo_model

  • 功能概述:
    是 HALCON 中用于创建立体视觉模型的操作符,主要用于从多视角校准的相机配置中重建 3D 点或表面。其核心功能包括:
    3D 点重建‌:通过多幅校准图像中的点对应关系,计算 3D 点坐(Method='points_3d')。
    表面重建‌:基于立体图像对生成视差图,进而重建表面(Method='surface_pairwise''surface_fusion')。

  • 参数详解

    • 输入参数
      • CameraSetupModelID :校准后的多视角相机配置模型句柄,包含相机内外参等信息。
    • Method:指定重建类型
      • 'points_3d':用于 3D 点云重建。
      • 'surface_pairwise':基于成对图像重建表面。
      • 'surface_fusion':融合多视角数据重建表面。
    • 输出参数
      • StereoModelID‌:生成的立体模型句柄,用于后续操作(如 reconstruct_surface_stereo)。
  • 典型工作流程

    • 创建模型‌ ```
    create_stereo_model(CameraSetupModelID, 'surface_pairwise', [], [], StereoModelID)
    

创建表面重建模型,初始化参数为空列表。

  • 配置参数
    通过 set_stereo_model_param 设置关键参数:

    • 'sub_sampling_step':控制重建分辨率(如 3 表示每 3 个像素采样一次)。
    • 'rectif_interpolation':指定图像矫正插值方法(如 'bilinear')。
  • 执行重建
    调用 reconstruct_surface_stereo 生成 3D 表面模型。

  • 应用场景

    1. 工业检测‌:如管道接头的多视角 3D 重建,通过 4 相机系统生成高精度表面模型。

    2. 机器人导航‌:结合手眼标定,将重建的 3D 点云转换到机器人坐标系。

  • 注意事项

    • 相机标定‌:需提前完成多相机标定,确保 CameraSetupModelID 参数准确。

    • 图像对选择‌:使用 set_stereo_model_image_pairs 指定有效的图像对索引(如 [0,2], [1,3])以优化视差计算。

  • 错误处理

    • Method 与模型类型不匹配(如对 'points_3d' 模型调用表面重建),会触发错误。

    • 无效的相机索引或未校准参数会导致重建失败。

2,set_stereo_model_image_pairs (StereoModelID, [0,2], [1,3])作用?

指定用于表面重建的立体图像对‌,其核心原理和必要性如下:

  • 函数功能与参数含义

    1. 功能定位
      该函数用于为 'surface_pairwise''surface_fusion' 类型的立体模型(StereoModelID)配置图像对列表,通过视差计算实现表面重建。若模型类型不匹配(如 'points_3d'),则会报错。

      • 参数解析:
        • [0,2] 表示第一组图像对的左视图索引为0,右视图索引为2;
        • [1,3] 表示第二组图像对的左视图索引为1,右视图索引为3。
          这些索引需在相机标定模型(CameraSetupModelID)的有效范围内。
    2. 多视角重建流程
      该函数是重建流程的关键步骤之一,需在 create_stereo_model 创建模型后调用,并在 reconstruct_surface_stereo 执行前完成图像对配置。

  • 图像对选择的依据

    1. 视差计算需求
      多视角重建通过计算图像对的视差图生成3D表面。例如,[0,2] 表示从相机0到相机2的视差计算,覆盖不同视角的几何关系。
      • 优化策略‌:选择交会角适中(如30°-60°)、特征匹配数量多的图像对,可提升重建精度。
    2. 覆盖性与效率平衡
      1. 覆盖性‌:[0,2][1,3] 的组合可能覆盖场景的不同区域,避免单一视角的盲区。
      2. 效率‌:减少冗余图像对(如相邻视角)可降低计算量,但需保证重建完整性。
  • 参数设置示例分析

    1. ‌ 相机布局假设
      • 相机0和2、1和3可能分别位于场景的左右两侧,形成交叉基线,增强深度感知。
    2. 视差多样性
      • 不同基线的图像对(如短基线0-1和长基线0-2)可兼顾细节与深度范围。
      • 注意事项
        1. 参数验证
          • 相机索引需与标定模型一致,否则会报错。
        2. 重建质量优化
          • 结合 set_stereo_model_param 设置边界框(bounding_box)可约束重建范围,提升效率。
  • 总结
    设置 set_stereo_model_image_pairs 的核心目的是 ‌通过合理配置图像对,优化视差计算与表面重建的精度和效率‌。参数 [0,2], [1,3] 体现了多视角立体视觉中交叉基线、覆盖性与计算资源的平衡设计。


4.3,创建表面匹配模型
* --------------------Part03: 创建表面匹配模型
* *****
* 3.1,读取管道接头3D对象
read_object_model_3d ('pipe_joint', 'm', [], [], PipeJointOM3DID, Status)
create_surface_model (PipeJointOM3DID, 0.03, [], [], PipeJointSMID)* 3.2,预处理匹配模型,提高匹配效率
* 'shape_base _matching_3d':激活基于表面集合特征的匹配模式,适用于管道接头等工业零件的定位
* 为true时进行法向量计算,曲率特征提取,关键点自动选择,提高匹配效率
prepare_object_model_3d (PipeJointOM3DID, 'shape_based_matching_3d', 'true', [], [])
* 
* *****

PipeJointOM3DID

在这里插入图片描述

4.4,多视角立体视觉重建管件堆表面模型
*-------------------Part04:多视角立体视觉重建管件堆表面模型* 4.1,设置多视角立体模型重建表面3D模型所需必要参数
* 重建管件堆的表面,并利用基于表面的三维匹配技术确定多个管道接头的位置。
* *****
NumMatches := 3
MinScore := .3* pose_ref_scoring_dist_rel:HALCON中用于曲面匹配(Surface-Based Matching)的关键参数,主要控制精细化姿态优化阶段的评分距离容差
* 该参数以相对值形式(相对于物体尺寸)设置匹配评分时的最大允许距离偏差
Params := ['num_matches','pose_ref_scoring_dist_rel','scene_normal_computation']
Values := [NumMatches,0.02,'mls']
Instructions[0] := 'Rotate: Left button'
Instructions[1] := 'Zoom:   Shift + left button'
Instructions[2] := 'Move:   Ctrl  + left button'
* 
* 注意:这里的Pose0是相机在世界坐标系的位姿,不是常见标定产生的标定板在相机坐标系的位姿camerapose
pose_invert (Pose0, WorldPose0)
* 
gen_empty_obj (EmptyObject)
NumImages := 15
for Index := 1 to NumImages by 1* * 4.2,读取重建多视角立体表面模型所需的图像read_multi_view_stereo_images (Images, ImagePath, ImagePrefix, Index, NumCameras)* * Reconstruct the 3D scene (the pile of pipe fittings)Message := 'Performing the reconstruction...'* 4.3,显示表面重建所用的图像display_multi_view_stereo_images (Images, WindowHandle)

Images

在这里插入图片描述

本地函数:

1,read_multi_view_stereo_images

* Read the images of the multi-view stereo setup
* 
read_image (Images, ImagePath + ImagePrefix + '_cam_0_' + SceneIndex$'.02')
for Index := 1 to NumCamera - 1 by 1read_image (Img, ImagePath + ImagePrefix + '_cam_' + Index + '_' + SceneIndex$'.02')concat_obj (Images, Img, Images)
endfor
return ()

2,display_multi_view_stereo_images

* Display the images of a multi-view stereo setup
* consisting of four cameras
* 
dev_set_window (WindowHandle)
* 
count_obj (Images, NumImages)
if (NumImages != 4)disp_message (WindowHandle, 'Wrong number of images provided!', 'window', 12, 12, 'black', 'true')stop ()
endif
* 
NumCols := 2
select_obj (Images, Img, 1)
get_image_size (Img, Width, Height)
tile_images (Images, TiledImage, NumCols, 'horizontal')
dev_set_part (0, 0, (2 * Height) - 1, (2 * Width) - 1)
dev_display (TiledImage)
* 
for Index := 0 to NumImages - 1 by 1RowIdx := (Index / NumCols) + 1ColIdx := Index % NumColsdisp_message (WindowHandle, 'Camera ' + Index, 'image', (RowIdx * Height) - 72, (ColIdx * Width) + 12, 'white', 'false')
endfor
return ()
* 

 disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')count_seconds (T0)---* 4.4,多视角立体模型重建表面3D模型reconstruct_surface_stereo (Images, StereoModelID, PipeJointPileOM3DID)count_seconds (T1)* 重建所用时间ReconsTime := T1 - T0* PoseIn := [0.0,0.0,0.5,-30,0,180,0]* 4.5,显示重建的3D模型   if (Index == 1)visualize_object_model_3d (WindowHandle, PipeJointPileOM3DID, CamParam0, PoseIn, ['color','point_size'], ['yellow',1], 'Reconstructed scene in ' + ReconsTime$'.3' + ' s', [], Instructions, PoseOut)endif

PipeJointPileOM3DID

在这里插入图片描述


4.5,管道接头查找匹配
 * Perform surface-based 3D matchingMessage := 'Search ' + NumMatches + ' best parts with surface based matching...'disp_message (WindowHandle, Message, 'window', 36, 12, 'black', 'true')count_seconds (T2)* 4.6,表面匹配查找find_surface_model (PipeJointSMID, PipeJointPileOM3DID, 0.03, 0.05, MinScore, 'false', Params, Values, Poses, Scores, SurfaceMatchingResultID)count_seconds (T3)* 表面匹配耗时:MatchingDiff := T3 - T2* * Display the results* 4.7, 禁用形输出的实时刷新,将多个图形操作缓存后统一显示,可有效解决界面闪烁问题   set_system ('flush_graphic', 'false')select_obj (Images, Img, 1)dev_set_part (0, 0, Height - 1, Width - 1)dev_display (Img)
*     count_seconds (T4)for MatchIndex := 0 to |Scores| - 1 by 1* 管道接头在世界坐标系中位姿PoseObjInWorld := Poses[MatchIndex * 7:(MatchIndex * 7) + 6]* 世界坐标系在对象坐标系的位姿
*         rigid_trans_object_model_3d (PipeJointOM3DID, PoseObjInWorld, ObjectModel3DRigidTrans1)
*         visualize_object_model_3d (WindowHandle, [PipeJointPileOM3DID,ObjectModel3DRigidTrans1], [], [],\['color_0','color_1','alpha_1'], ['gray','green',0.5], [], [], [], PoseOut1)pose_invert (PoseObjInWorld, PoseWorldInObj)* 相机在世界坐标系的位姿+世界坐标系在对象坐标系的位姿=相机坐标系在对象坐标系的位姿        pose_compose (PoseWorldInObj, Pose0, PoseCamInObj)   *对象在相机坐标系中的位姿 pose_invert (PoseCamInObj, ObjPoseInCam0)* Display the coordinate system of the partdev_set_colored (3)dev_set_line_width (3)*  4.8,显示匹配到的管道接头的坐标系        disp_3d_coord_system (WindowHandle, CamParam0, ObjPoseInCam0, 0.03)* Display the faces of the partrigid_trans_object_model_3d (PipeJointOM3DID, PoseObjInWorld, ObjectModel3DRigidTrans)* 4.9,投影到平面形成轮廓* 'data':'face',指定投影时处理模型的三角面片(faces)而非原始点云数据* 'hidden_surface_removal':'true',使用隐藏面移除技术,消除被遮挡的不可见面,提升投影结果的真实感  project_object_model_3d (ModelContours, ObjectModel3DRigidTrans, CamParam0, WorldPose0, ['data','hidden_surface_removal'], ['faces','true'])dev_set_line_width (2)dev_set_color ('green')dev_display (ModelContours)* clear_object_model_3d (ObjectModel3DRigidTrans)endforset_system ('flush_graphic', 'true')
*     count_seconds (T5)
*     DispTime := T5 - T4* Message := '立体视觉重建耗时: ' + ReconsTime$'.2f' + ' s'Message[1] := '找到: ' + |Scores| + ' 管道接头表面匹配耗时: ' + MatchingDiff$'.2f' + ' s'
*     Message[2] := 'Visualization: ' + DispTime$'.1f' + ' s'disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')disp_message (WindowHandle, 'Camera 0', 'window', Height - 36, 12, 'white', 'false')if (Index < NumImages)disp_continue_message (WindowHandle, 'black', 'true')stop ()endif* * clear the 3D object modelclear_object_model_3d (PipeJointPileOM3DID)copy_obj (Images, OldImage, 1, 1)
endfor
* 

ModelContours
在这里插入图片描述


5,完整代码

* 案例库:locate_pipe_joints_stereo.hdev* 目的:
* 查找立体视觉获取的3D对象中管道连接头的立体位置* 过程:
* 采用四个相机采集的图像立体重建一堆管道连接头的三维表面* 基于表面的3D匹配,查找
* 
* 
*---------------------part01:初始化窗口
* *****
* Initializations:
* *****
* 
dev_close_window ()
dev_update_off ()
dev_get_preferences ('suppress_handled_exceptions_dlg', PreferenceValue)
dev_set_preferences ('suppress_handled_exceptions_dlg', 'true')
ImagePath := '3d_machine_vision/multi_view/'
ImagePrefix := 'multi_view_pipe_joints'
read_image (Image, ImagePath + ImagePrefix + '_cam_0_01')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_set_draw ('margin')
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
* 
* *****
*-------------------- Part02: 多视角立体视觉模型创建
* *****
* 2.1,Read the camera setup model from file and get the parameters
* and the poses of the cameras
tryread_camera_setup_model ('../four_camera_setup_model.csm', CameraSetupModelID)
catch (Exception)if (Exception[0] == 5200)* 初始化生成相机内参+外参* 需要特别注意这里的外参是常见标定获取的camerapose的逆变换init_camera_setup (CameraSetupModelID)elsethrow (Exception)endif
endtry
* 
* 2.2 ,获取多视角立体视觉模型参数
get_camera_setup_param (CameraSetupModelID, 'general', 'num_cameras', NumCameras)
* 需要特别注意:结合上下文可知Pose0应该是常见标定获取的camerapose的逆变换
* (camerapose为标定板在相机坐标系的位姿)
get_camera_setup_param (CameraSetupModelID, 0, 'pose', Pose0)
get_camera_setup_param (CameraSetupModelID, 1, 'pose', Pose1)
get_camera_setup_param (CameraSetupModelID, 2, 'pose', Pose2)
get_camera_setup_param (CameraSetupModelID, 3, 'pose', Pose3)
get_camera_setup_param (CameraSetupModelID, 0, 'params', CamParam0)
get_camera_setup_param (CameraSetupModelID, 1, 'params', CamParam1)
get_camera_setup_param (CameraSetupModelID, 2, 'params', CamParam2)
get_camera_setup_param (CameraSetupModelID, 3, 'params', CamParam3)* 
* Create a multi-view stereo model, initialize it, and clear
* the camera setup, which is no longer required* 2.3,创建双目立体视觉。
* 'surface_pairwise':基于成对图像进行表面重建
create_stereo_model (CameraSetupModelID, 'surface_pairwise', [], [], StereoModelID)
clear_camera_setup_model (CameraSetupModelID)* 2.4,多视角立体视觉模型参数设置*-----图像校正参数组* -> Subsampling X, Y, Z
* 设置下采样步长为3,可降低计算量但可能导致锯齿效应,需配合抗锯齿参数使用
set_stereo_model_param (StereoModelID, 'sub_sampling_step', 3)
* -> Interpolation aliasing by binocular image rectification
* 双线性插值('bilinear'),平衡校正图像的质量与计算效率
set_stereo_model_param (StereoModelID, 'rectif_interpolation', 'bilinear')
* 子采样系数1.2,轻微降低分辨率以加速处理
set_stereo_model_param (StereoModelID, 'rectif_sub_sampling', 1.2)* -----双目视差计算参数组* 采用归一化互相关('ncc')匹配算法,对光照变化鲁棒性强
set_stereo_model_param (StereoModelID, 'binocular_method', 'ncc')
* 视差计算的金字塔层级数,设置为1时单层直接计算,应用于高纹理/实时性要求高的场景
set_stereo_model_param (StereoModelID, 'binocular_num_levels', 1)
* 匹配掩模尺寸19×19像素,适合中等纹理场景
set_stereo_model_param (StereoModelID, 'binocular_mask_width', 19)
set_stereo_model_param (StereoModelID, 'binocular_mask_height', 19)
* 纹理阈值设为0,禁用纹理过滤,适用于低纹理场景
set_stereo_model_param (StereoModelID, 'binocular_texture_thresh', 0)
* 匹配分数阈值0.4,过滤低置信度匹配点
set_stereo_model_param (StereoModelID, 'binocular_score_thresh', 0.4)
* 启用左右一致性检查('left_right_check'),消除遮挡区域误匹配
set_stereo_model_param (StereoModelID, 'binocular_filter', 'left_right_check')
* 子像素优化模式为插值法('interpolation'),提升深度分辨率
set_stereo_model_param (StereoModelID, 'binocular_sub_disparity', 'interpolation')*------ 空间约束和相机约束* 定义3D工作空间为[-0.2,-0.07,-0.075]到[0.2,0.07,-0.004](单位:米),自动计算视差范围
* 边界框(bounding_box)可约束重建范围,提升效率
set_stereo_model_param (StereoModelID, 'bounding_box', [-0.2,-0.07,-0.075,0.2,0.07,-0.004])
* 配置相机对为(0,2)和(1,3),支持多相机阵列的灵活组合
set_stereo_model_image_pairs (StereoModelID, [0,2], [1,3])
* 
* *****
* --------------------Part03: 创建表面匹配模型
* *****
* 3.1,读取管道接头3D对象
read_object_model_3d ('pipe_joint', 'm', [], [], PipeJointOM3DID, Status)
create_surface_model (PipeJointOM3DID, 0.03, [], [], PipeJointSMID)* 3.2,预处理匹配模型,提高匹配效率
* 'shape_base _matching_3d':激活基于表面集合特征的匹配模式,适用于管道接头等工业零件的定位
* 为true时进行法向量计算,曲率特征提取,关键点自动选择,提高匹配效率
prepare_object_model_3d (PipeJointOM3DID, 'shape_based_matching_3d', 'true', [], [])
* 
* *****
*-------------------Part04:多视角立体视觉重建管件堆表面模型* 4.1,设置多视角立体模型重建表面3D模型所需必要参数
* 重建管件堆的表面,并利用基于表面的三维匹配技术确定多个管道接头的位置。
* *****
NumMatches := 3
MinScore := .3* pose_ref_scoring_dist_rel:HALCON中用于曲面匹配(Surface-Based Matching)的关键参数,主要控制精细化姿态优化阶段的评分距离容差
* 该参数以相对值形式(相对于物体尺寸)设置匹配评分时的最大允许距离偏差
Params := ['num_matches','pose_ref_scoring_dist_rel','scene_normal_computation']
Values := [NumMatches,0.02,'mls']
Instructions[0] := 'Rotate: Left button'
Instructions[1] := 'Zoom:   Shift + left button'
Instructions[2] := 'Move:   Ctrl  + left button'
* 
* 注意:这里的Pose0是相机在世界坐标系的位姿,不是常见标定产生的标定板在相机坐标系的位姿camerapose
pose_invert (Pose0, WorldPose0)
* 
gen_empty_obj (EmptyObject)
NumImages := 15
for Index := 1 to NumImages by 1* * 4.2,读取重建多视角立体表面模型所需的图像read_multi_view_stereo_images (Images, ImagePath, ImagePrefix, Index, NumCameras)* * Reconstruct the 3D scene (the pile of pipe fittings)Message := 'Performing the reconstruction...'* 4.3,显示表面重建所用的图像display_multi_view_stereo_images (Images, WindowHandle)disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')count_seconds (T0)* 4.4,多视角立体模型重建表面3D模型reconstruct_surface_stereo (Images, StereoModelID, PipeJointPileOM3DID)count_seconds (T1)* 重建所用时间ReconsTime := T1 - T0* PoseIn := [0.0,0.0,0.5,-30,0,180,0]* 4.5,显示重建的3D模型   if (Index == 1)visualize_object_model_3d (WindowHandle, PipeJointPileOM3DID, CamParam0, PoseIn, ['color','point_size'], ['yellow',1], 'Reconstructed scene in ' + ReconsTime$'.3' + ' s', [], Instructions, PoseOut)endif* * Perform surface-based 3D matchingMessage := 'Search ' + NumMatches + ' best parts with surface based matching...'disp_message (WindowHandle, Message, 'window', 36, 12, 'black', 'true')count_seconds (T2)* 4.6,表面匹配查找find_surface_model (PipeJointSMID, PipeJointPileOM3DID, 0.03, 0.05, MinScore, 'false', Params, Values, Poses, Scores, SurfaceMatchingResultID)count_seconds (T3)* 表面匹配耗时:MatchingDiff := T3 - T2* * Display the results* 4.7, 禁用形输出的实时刷新,将多个图形操作缓存后统一显示,可有效解决界面闪烁问题   set_system ('flush_graphic', 'false')select_obj (Images, Img, 1)dev_set_part (0, 0, Height - 1, Width - 1)dev_display (Img)
*     count_seconds (T4)for MatchIndex := 0 to |Scores| - 1 by 1* 管道接头在世界坐标系中位姿PoseObjInWorld := Poses[MatchIndex * 7:(MatchIndex * 7) + 6]* 世界坐标系在对象坐标系的位姿
*         rigid_trans_object_model_3d (PipeJointOM3DID, PoseObjInWorld, ObjectModel3DRigidTrans1)
*         visualize_object_model_3d (WindowHandle, [PipeJointPileOM3DID,ObjectModel3DRigidTrans1], [], [],\['color_0','color_1','alpha_1'], ['gray','green',0.5], [], [], [], PoseOut1)pose_invert (PoseObjInWorld, PoseWorldInObj)* 相机在世界坐标系的位姿+世界坐标系在对象坐标系的位姿=相机坐标系在对象坐标系的位姿        pose_compose (PoseWorldInObj, Pose0, PoseCamInObj)   *对象在相机坐标系中的位姿 pose_invert (PoseCamInObj, ObjPoseInCam0)* Display the coordinate system of the partdev_set_colored (3)dev_set_line_width (3)*  4.8,显示匹配到的管道接头的坐标系        disp_3d_coord_system (WindowHandle, CamParam0, ObjPoseInCam0, 0.03)* Display the faces of the partrigid_trans_object_model_3d (PipeJointOM3DID, PoseObjInWorld, ObjectModel3DRigidTrans)* 4.9,投影到平面形成轮廓* 'data':'face',指定投影时处理模型的三角面片(faces)而非原始点云数据* 'hidden_surface_removal':'true',使用隐藏面移除技术,消除被遮挡的不可见面,提升投影结果的真实感  project_object_model_3d (ModelContours, ObjectModel3DRigidTrans, CamParam0, WorldPose0, ['data','hidden_surface_removal'], ['faces','true'])dev_set_line_width (2)dev_set_color ('green')dev_display (ModelContours)* clear_object_model_3d (ObjectModel3DRigidTrans)endforset_system ('flush_graphic', 'true')
*     count_seconds (T5)
*     DispTime := T5 - T4* Message := '立体视觉重建耗时: ' + ReconsTime$'.2f' + ' s'Message[1] := '找到: ' + |Scores| + ' 管道接头表面匹配耗时: ' + MatchingDiff$'.2f' + ' s'
*     Message[2] := 'Visualization: ' + DispTime$'.1f' + ' s'disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')disp_message (WindowHandle, 'Camera 0', 'window', Height - 36, 12, 'white', 'false')if (Index < NumImages)disp_continue_message (WindowHandle, 'black', 'true')stop ()endif* * clear the 3D object modelclear_object_model_3d (PipeJointPileOM3DID)copy_obj (Images, OldImage, 1, 1)
endfor
* 
* Clear the stereo model and the surface model
clear_stereo_model (StereoModelID)
clear_surface_model (PipeJointSMID)
clear_object_model_3d (PipeJointOM3DID)
dev_set_preferences ('suppress_handled_exceptions_dlg', PreferenceValue)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/84779.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/84779.shtml
英文地址,请注明出处:http://en.pswp.cn/web/84779.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

移远通信 × 紫光展锐,推动FWA “5G+AI”新体验

6月19日&#xff0c;在2025 MWC上海期间&#xff0c;移远通信宣布&#xff0c;携手紫光展锐&#xff0c;推出面向下一代CPE应用的“5GAI”融合解决方案。目前双方正联合多家CPE厂商开展方案深度调优&#xff0c;以加速5GAI CPE终端的产业化落地进程。 该方案以移远5G模组RG620…

深入理解Grad-CAM:用梯度可视化神经网络的“注意力“

深入理解Grad-CAM&#xff1a;用梯度可视化神经网络的"注意力" 引言 在深度学习的发展过程中&#xff0c;模型的可解释性一直是一个重要的研究方向。尽管现代神经网络在图像识别、自然语言处理等任务上取得了令人瞩目的成果&#xff0c;但它们往往被称为"黑盒…

离线环境jenkins构建前端部署镜像

gitlabjenkins 实现前端项目打包成 docker 镜像&#xff1b;gitlab部署就不赘述了&#xff1b;因部署的gitlab版本的webhooks有问题&#xff0c;无法进行配置,所以文章的构建是手动触发的。并且nodejs部署应该也能跟docker一样直接安装进jenkins的镜像(但是多版本可能就有其他问…

案例:塔能科技×某市智能照明——从传统亮化到智慧光生态的跨越

在城市发展的滚滚浪潮中&#xff0c;市政照明不仅是驱散黑夜的光明使者&#xff0c;更是衡量城市智能化水平的关键标尺。贵州某市的城市照明系统正经历一场意义深远的革新&#xff0c;塔能科技以创新科技为核心驱动力&#xff0c;为这座城市的夜间照明生态注入全新活力。通过智…

LeapMotion-HandPoseRecorder 脚本详解

HandPoseRecorder 脚本详解 这个脚本是一个用于在 Unity 中录制和保存 Leap Motion 手部姿势的工具。下面我将详细解释脚本的各个部分: 核心功能 该脚本的主要作用是: 从 Leap Motion 设备捕获当前手部姿势数据 将姿势数据序列化为可重用的 ScriptableObject 在 Unity 项目…

【Guava】0.做自己的编程语言

【Guava】0.做自己的编程语言 0.前言1.明确你的目标1.2.设计1.3.写一个介绍 2.开始吧&#xff01; 0.前言 DO WHAT THE F**K YOU WANT TO DO 我相信&#xff0c;网上有许多各式各样的做自己的编程语言教程&#xff0c;but 都是这样 收费 shit 本教程教你真正教你实现一个名叫G…

【软考高级系统架构论文】论无服务器架构及其应用

论文真题 近年来&#xff0c;随着信息技术的迅猛发展和 应用需求的快速更迭&#xff0c;传统的多层企业应用系统架构面临越来越多的挑战&#xff0c;已经难以适应这种变化。在这一背景下&#xff0c;无服务器架构(Serverless Architecture) 逐渐流行&#xff0c;它强调业务逻辑…

国产MCU A\B SWAP原理及实操

看到有读者留言说还是没理清A\B SWAP的原理。 今天就以某国产MCU为例&#xff0c;实际演示一番&#xff0c;看看大家在芯片设计时思路是什么。 我们首先回顾下SWAP的基本思想。 SWAP的基本思想是将PFLASH分成两组Bank&#xff0c;Bank A(假设是active)和Bank B(假设是inacti…

目标检测neck经典算法之FPN的源码实现

┌────────────────────────────────────────────────────┐│ 初始化构造 (__init__) │└─────────────────────────────────────────────…

extern关键字:C/C++跨文件编程利器

在 C 和 C 中&#xff0c;extern 是一个关键字&#xff0c;用于声明变量或函数是在其他文件中定义的。它主要用于实现多个源文件之间的符号共享。 目录 &#x1f4cc; 一、C语言中的 extern 1. 基本作用 2. 示例说明 定义全局变量&#xff08;只在一个 .c 文件中&#xff…

编程语言的演化与选择:技术浪潮中的理性决策

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;为什么“选对语言”比“掌握语言”更重要&#xff1f; 在软件开发的世界里&#xff0c;语言是一切的基础。…

【StarRocks系列】StarRocks vs Mysql

目录 StarRocks 简介 核心特性 典型应用场景 StarRocks vs MySQL&#xff1a;核心区别详解 关键差异总结 如何选择&#xff1f; StarRocks 简介 StarRocks 是一款高性能、全场景、分布式、实时分析型的数据库&#xff08;MPP - 大规模并行处理&#xff09;。它诞生于解决…

Axios 知识点全面总结

文章目录 Axios 知识点全面总结一、Axios 基础概念1. 什么是 Axios&#xff1f;2. 核心特性 二、安装与基本用法1. 安装2. 基本请求示例 三、请求方法与参数四、请求配置选项&#xff08;config&#xff09;五、拦截器&#xff08;Interceptors&#xff09;六、错误处理七、取消…

【软考高级系统架构论文】论 SOA 在企业集成架构设计中的应用

论文真题 企业应用集成(Enterprise Application Integration, EAI)是每个企业都必须要面对的实际问题。面向服务的企业应用集成是一种基于面向服务体系结构(Service - Oriented Architecture, SOA)的新型企业应用集成技术,强调将企业和组织内部的资源和业务功能暴露为服务,实…

springboot 提供的可扩展接口

一、spring 和 springboot Spring框架提供了全面的基础架构支持。包含依赖注入和开箱即用等模块&#xff0c;如&#xff1a;Spring JDBC 、Spring MVC 、Spring Security、 Spring AOP 、Spring ORM 、Spring Test Spring Boot 约定大于配置-----消除了设置Spring应用程序所需…

python学习打卡day55

DAY 55 序列预测任务介绍 知识点回顾 序列预测介绍 单步预测多步预测的2种方式 序列数据的处理&#xff1a;滑动窗口多输入多输出任务的思路经典机器学习在序列任务上的劣势&#xff1b;以随机森林为例 作业&#xff1a;手动构造类似的数据集&#xff08;如cosx数据&#xff09…

Leetcode hot100 Java刷题

文章目录 快排146. LRU 缓存acm模式树的前中后序遍历acm模式链表的基本操作1. 两数之和49. 字母异位词分组128. 最长连续序列283. 移动零11. 盛最多水的容器15. 三数之和42. 接雨水53. 最大子数组和56. 合并区间73. 矩阵置零48. 旋转图像141. 环形链表142. 环形链表 II24. 两两…

Linux 命令详解 —— 进程管理

文章目录 精通Linux操作系统(以Centos7为例)进程管理ps常用组合进程状态 STAT 详解高级筛选与格式化输出按条件过滤进程自定义输出字段显示进程树关系排障场景定位高 CPU检查僵尸进程查看进程的线程查看进程打开的文件/网络连接常用组合速查top前5摘要区进程列表信息交互式命令…

【软考高级系统架构论文】论湖仓一体架构及其应用

论文真题&#xff1a; 随着5G、大数据、人工智能、物联网等技术的不断成熟&#xff0c;各行各业的业务场景日益复杂&#xff0c;企业数据呈现出大规模、多样性的特点&#xff0c;特别是非结构化数据呈现出爆发式增长趋势。在这一背景下&#xff0c;企业数据管理不再局限于传统…

Docker 高级管理笔记

前言&#xff1a;Docker 高级管理概述 随着 Docker 技术的广泛应用&#xff0c;容器化已成为现代软件开发与部署的核心方式。本笔记聚焦 Docker 高级管理中的两大关键技术 —— 容器通信与数据持久化&#xff0c;深入解析 Docker 网络模式、端口映射、容器互联机制及数据卷管理…