reconstruct_3d_object_model_for_matching例子

news2025/3/22 13:54:42

文章目录

  • 1.获取om3文件
  • 2.准备可视化
  • 3.准备3D可视化
  • 4.读取3D模型
  • 5.显示成对注册结果1
  • 6.显示成对注册结果2
  • 7.联合注册模型
  • 8.处理图像
    • 8.1子采样
    • 8.2 图像计算与平滑
    • 8.3 三角测量
  • 9.基于表面做3D匹配
  • 10.评估模型准确度
    • 10.1 在场景中找到模型
    • 10.2 计算模型和场景之间的距离
  • 11.立体系统重建
    • 11.1 开始匹配
    • 11.2 执行立体系统重建

此示例显示从3D对象获取和模型创建到匹配的完整流程

步骤是:

  • 成对注册3D数据
  • 全局注册所有3D数据
  • 注册3D数据的联合
  • 采样和平滑抑制异常值
  • 三角测量
  • 模型提取和培训
  • 匹配来自另一个相机的图像
    在这里插入图片描述

1.获取om3文件

dev_update_off () //暂停刷新
获取om3文件名
list_image_files ('universal_joint_part', 'default', [], AllImageFiles)
tuple_regexp_select (AllImageFiles, 'intensities', ImageFiles)  //选择符合公式的数组元素
ImageFiles := sort(ImageFiles) //图像文件

2.准备可视化

dev_close_window () //关闭窗体
dev_open_window (250, 0, 748 + 12, 300, 'black', WindowHandle3D) //打开窗体1
dev_open_window (0, 0, 748 / 2, 240, 'black', WindowHandle1) //打开窗体2
dev_open_window (0, 748 / 2 + 12, 748 / 2, 240, 'black', WindowHandle2) //打开窗体3
set_display_font (WindowHandle1, 16, 'mono', 'true', 'false')  //设置窗体1字体
set_display_font (WindowHandle2, 16, 'mono', 'true', 'false')  //设置窗体2字体
set_display_font (WindowHandle3D, 16, 'mono', 'true', 'false') //设置窗体3字体
准备可视化
Color1 := 'green'   //设置颜色1为绿色
Color2 := 'yellow'  //设置颜色2为黄色
Color3 := 'gray'    //设置颜色3为灰色
dev_set_window (WindowHandle1) //切换窗体1
dev_set_draw ('margin') //设置轮廓
dev_set_color (Color1)  //切换颜色1
dev_set_window (WindowHandle2) //切换窗体2
dev_set_draw ('margin') //设置轮廓
dev_set_color (Color2)  //设置颜色2

3.准备3D可视化

准备3D可视化
CamParam1 := [0.06,0,8.5e-6,8.5e-6,380.0,150.0,760,300]   //相机1内部参数
CamParam2 := [0.06,0,8.5e-6,8.5e-6,380.0,275.0,760,550]   //相机2内部参数
create_pose (70, -20, 1800, 125, 345, 185, 'Rp+T', 'gba', 'point', PoseVisualize) //创建一个三维坐标系
Instructions[0] := '旋转: 鼠标左键' 
Instructions[1] := '缩放:   Shift + 鼠标左键'
Instructions[2] := '移动:   Ctrl  + 鼠标左键'
VisualizeParameterNames := ['color','color_0','color_1','point_size','point_size_0','point_size_1'] //参数名称
VisualizeParameterValues := [Color3,Color1,Color2,1.0,1.0,1.0] //参数值

read_image (Image, 'universal_joint_part/universal_joint_part_intensities_00')  //读取图像1
read_image (Image2, 'universal_joint_part/universal_joint_part_intensities_01') //读取图像2
gen_rectangle1 (Rectangle, 0, 0, 479, 747) //创建矩形

dev_set_window (WindowHandle1) //切换窗体1
dev_display (Image) //显示图像
dev_set_window (WindowHandle2) //切换窗体2
dev_display (Image) //显示图像
Message := '该程序为基于表面的3D匹配创建的一个3D模型'
Message[1] := '通过从一系列3D传感器图像来注册3D传感器数据'
Message[2] := ' '
Message[3] := '之后,该模型用于将对象定位在不同源的3D数据中'
Message[4] := ' '
Message[5] := ' '
Message[6] := '步骤 1:'
Message[7] := '成对注册3D传感器数据'
disp_message (WindowHandle3D, Message, 'window', 12, 12, 'white', 'false') //显示信息
disp_continue_message (WindowHandle3D, 'black', 'true') //暂停信息
stop () //暂停

4.读取3D模型

读取一个 3D 模型
read_object_model_3d ('universal_joint_part/universal_joint_part_xyz_00.om3', 'm', \
                      [], [], ObjectModel3D, Status)
PreviousOM3 := ObjectModel3D
RegisteredOM3s := ObjectModel3D
copy_object_model_3d (ObjectModel3D, 'all', CollectedAffineObjects) //复制一个 3D 模型对象
Offsets := []
hom_mat3d_identity (HomMat3DStart) //创建一个三维变换矩阵
HomMat3DCompose := HomMat3DStart
采取22次扫描中的15次进行三角测量
NumTrainingImages := 15
NumSearchImages := |ImageFiles| - NumTrainingImages
for Index := 1 to NumTrainingImages - 1 by 1
    读取下一个 3D 模型
    read_object_model_3d ('universal_joint_part/universal_joint_part_xyz_' + Index$'02d', 'm',\
    [], [], ObjectModel3D, Status)
    跳过小对象,因为注册可能会失败
    get_object_model_3d_params (ObjectModel3D, 'num_points', ParamValue) //获取 3D 模型的参数
    if (ParamValue < 1000)
        clear_object_model_3d (ObjectModel3D) //清除3D模型
        continue 
    endif
    注册最后一个成功的比赛和当前的模型
    搜索两个 3D 模型之间的转换
    register_object_model_3d_pair (ObjectModel3D, PreviousOM3, 'matching', 'default_parameters',\
    'accurate', Pose, Score)
    如果注册失败,请忽略此视图
    if (|Pose| == 0 or Score < 0.7)
        clear_object_model_3d (ObjectModel3D) //清除3D模型
        continue
    endif
    try
        积累结果
        pose_to_hom_mat3d (Pose, HomMat3D)  //将一个三位模式转换为一个同质变换矩阵
        RegisteredOM3s := [RegisteredOM3s,ObjectModel3D]
        Offsets := [Offsets,HomMat3D]
        创建可视化的3D对象模型
        hom_mat3d_compose (HomMat3DCompose, HomMat3D, HomMat3DCompose)            //将两个三维变换矩阵相乘操作
        affine_trans_object_model_3d (ObjectModel3D, HomMat3DCompose, ObjectModel3DAffineTrans) //将一个 3D 模型进行任意仿射转换
        CollectedAffineObjects := [ObjectModel3DAffineTrans,CollectedAffineObjects]
        准备下一轮
        PreviousOM3 := ObjectModel3D
        显示所有3D对象模型
        dev_set_window (WindowHandle3D) //切换窗体1
        disp_object_model_3d_safe (WindowHandle3D, CollectedAffineObjects, CamParam1, PoseVisualize, VisualizeParameterNames, VisualizeParameterValues)
        disp_message (WindowHandle3D, '注册模型', 'window', 12, 12, 'black', 'true') //显示信息
        显示灰度值图像进行说明
        dev_set_window (WindowHandle1) //切换窗体2
        dev_display (Image) //显示图像
        dev_set_line_width (3) //设置线宽
        dev_display (Rectangle) //显示矩形
        Message := '视图 ' + Index 
        disp_message (WindowHandle1, Message, 'window', 12, 12, 'black', 'true') //显示信息
        读取图像
        read_image (Image, ImageFiles[Index]) //读取图像
        现在显示新的框架,看到两个框架
        dev_set_window (WindowHandle2) //切换窗体3
        dev_display (Image) //显示图像
        dev_set_line_width (3) //设置线宽
        dev_display (Rectangle) //显示矩形
        Message := '视图 ' + (Index + 1) 
        disp_message (WindowHandle2, Message, 'window', 12, 12, 'black', 'true') //显示信息
    catch (Exception1) 
        clear_object_model_3d (ObjectModel3D) //清除3D模型
    endtry
endfor

5.显示成对注册结果1

dev_set_window (WindowHandle1)   //切换窗体2
dev_close_window () //关闭窗体
dev_set_window (WindowHandle2)   //切换窗体3
dev_close_window () //关闭窗体
dev_set_window (WindowHandle3D)  //切换窗体1
dev_set_window_extents (0, 0, 760, 550) //调整窗体大小
dev_clear_window () //清除窗体
显示成对注册的结果
Message := '成对注册结果'
disp_message (WindowHandle3D, Message, 'window', 12, 12, 'black', 'true') //显示信息
Message := '成对注册在许多图像上存在累积错误的风险,' 
Message[1] := '因此,结果将在下一步全局细化'

disp_message (WindowHandle3D, Message, 'window', 50, 12, 'white', 'false') //显示信息
visualize_object_model_3d (WindowHandle3D, CollectedAffineObjects, CamParam2, PoseVisualize,\
                           ['colored','disp_background'], [12,'true'], [], [], Instructions,\
                           PoseVisualize)
clear_object_model_3d (CollectedAffineObjects) //清除3D模型

6.显示成对注册结果2

基于成对登记结果的所有视图的全局注册

全局登记需要近似的相对姿态(由齐次矩阵表示)作为输入。 在本例中,使用成对注册的结果。另一种可能性是使用机器人的姿势,例如,如果相机连接到机器人手臂上。

dev_clear_window () //清除窗体
Message := '步骤 2:'
Message[2] := ' '
Message[3] := '需要3D相机数据的全局注册来完善结果'
Message[4] := '这可能需要一分钟,请稍候...'
disp_message (WindowHandle3D, Message, 'window', 12, 12, 'white', 'false') //显示信息
register_object_model_3d_global (RegisteredOM3s, Offsets, 'previous', [], 'max_num_iterations',\
                                 1, HomMat3DRefined, Score) //改进 3D 模型间的相对变换
应用结果
affine_trans_object_model_3d (RegisteredOM3s, HomMat3DRefined, GloballyRegisteredOM3s) //将一个 3D 模型进行任意仿射转换
清除输入数据
clear_object_model_3d (RegisteredOM3s) //清除3D模型
Title := '全局注册结果'
visualize_object_model_3d (WindowHandle3D, GloballyRegisteredOM3s, CamParam2, PoseVisualize,\
                           'colored', 12, Title, [], Instructions, Pose) 

7.联合注册模型

union_object_model_3d (GloballyRegisteredOM3s, 'points_surface', UnionOptimized) //将多个 3D 模型集合当一个 3D 模型
dev_clear_window () //清除窗体
Title := '联合注册模型'
Message := '这个结果还是存在噪音'
Message[2] := '因此,下一步将进行进一步的处理。.'
disp_message (WindowHandle3D, Message, 'window', 50, 12, 'white', 'false') //显示信息
visualize_object_model_3d (WindowHandle3D, UnionOptimized, CamParam2, PoseVisualize, \
                           ['point_size','color','disp_background'], [1.0,'gray','true'],\
                           Title, [], Instructions, Pose)
clear_object_model_3d (GloballyRegisteredOM3s) //清除3D模型

8.处理图像

对原始数据:二次采样,平滑和三角测量

8.1子采样

样本距离表示目标精度。 在采样模式'准确'中,这个大小的体素必须至少包含'min_num_points'点,以被认为是有效的。 返回体素中所有点的平均值。
MinNumPoints := 5
SampleDistance := 0.53D对象模型的处理进行采样
sample_object_model_3d (UnionOptimized, 'accurate', SampleDistance, 'min_num_points',\
                        MinNumPoints, SampleExact)

Title := '采样对象(采样距离: ' + SampleDistance + 'mm)'
Message := '采样次数减少重叠区域的点数.'
Message[1] := '因此,现在的分数需要进行平均分配'
Message[2] := '另外,体素的点数少于'+ MinNumPoints + ' 删除的点数.'
* Message[3] :=  MinNumPoints + ' 删除的点数.'
*Message[3] := 'less than ' + MinNumPoints + ' points are removed.'
dev_clear_window () //清除窗体
disp_message (WindowHandle3D, Message, 'window', 50, 12, 'white', 'false') //显示信息
visualize_object_model_3d (WindowHandle3D, SampleExact, CamParam2, Pose, \
                           ['point_size','color','disp_background'], [1.0,'gray','true'],\
                           Title, [], Instructions, Pose)
clear_object_model_3d (UnionOptimized) //清除3D模型

8.2 图像计算与平滑

暂时移动物体,使坐标系的原点位于物体的正下方。
这样,结合smooth_object_model_3d'mls_force_inwards'选项,
平滑对象模型的法线将向下指示,使基于表面的3D匹配更加强大。

get_object_model_3d_params (SampleExact, 'center', Center) //获取 3D 模型的参数
get_object_model_3d_params (SampleExact, 'bounding_box1', BoundingBox) //获取 3D 模型的参数
hom_mat3d_identity (HomMat3DTrans) //创建一个三维变换矩阵
hom_mat3d_translate_local (HomMat3DTrans, -Center[0], -Center[1], -BoundingBox[2], HomMat3DTranslate) //对三维变换矩阵进行平移操作
affine_trans_object_model_3d (SampleExact, HomMat3DTranslate, SampleExactTrans)//将一个 3D 模型进行任意仿射转换
smooth_object_model_3d (SampleExactTrans, 'mls', 'mls_force_inwards', 'true', SmoothObject3DTrans)//对 3D 模型的三维点进行平滑处理
hom_mat3d_invert (HomMat3DTranslate, HomMat3DInvert) //对二维变换矩阵进行倒置操作
affine_trans_object_model_3d (SmoothObject3DTrans, HomMat3DInvert, SmoothObject3D) //将一个 3D 模型进行任意仿射转换
Title := '平滑对象'
Message := '平滑减少更多噪音'
dev_clear_window () //清除窗体
disp_message (WindowHandle3D, Message, 'window', 50, 12, 'white', 'false') //显示信息
visualize_object_model_3d (WindowHandle3D, SmoothObject3D, CamParam2, Pose, \
                           ['point_size','color','disp_background'], [1.0,'gray','true'],\
                           Title, [], Instructions, Pose)
clear_object_model_3d (SampleExact)          //清除3D模型
clear_object_model_3d (SampleExactTrans)     //清除3D模型
clear_object_model_3d (SmoothObject3DTrans)  //清除3D模型

8.3 三角测量

Message := '请等待三角测量...'
Message[1] := '检查状态栏以获取进度信息。'
dev_clear_window () //清除窗体
disp_message (WindowHandle3D, Message, 'window', 12, 12, 'white', 'false') //显示信息
triangulate_object_model_3d (SmoothObject3D, 'greedy', [], [], Surface3D, Information) //创建一个 3D 对象模型的表面三角
Title := '平滑和三角形表面处理'
dev_clear_window ()
visualize_object_model_3d (WindowHandle3D, Surface3D, CamParam2, Pose, 'disp_background', \
                           'true', Title, [], Instructions, Pose)
clear_object_model_3d (SmoothObject3D)   //清除3D模型

9.基于表面做3D匹配

从处理后的数据中分割万能接头部分,并从中提取基于表面的3D匹配模型。

connection_object_model_3d (Surface3D, 'mesh', 1, ObjectModel3DConnected) //确定三维对象模型的连接的组件
clear_object_model_3d (Surface3D)   //清除3D模型
选择大型组件
select_object_model_3d (ObjectModel3DConnected, ['has_triangles','num_triangles'], 'and', [1,2000], [1,100000], ObjectModel3DSelected)
Title := '大型连接组件以不同的颜色显示'
Message:= '在三角测量之后,所需对象可以容易地被分割,'
Message[1]:='该分割于基于表面的3D匹配的训练模型.'
dev_clear_window ()
disp_message (WindowHandle3D, Message, 'window', 50, 12, 'white', 'false')
visualize_object_model_3d (WindowHandle3D, ObjectModel3DSelected, CamParam2, Pose, ['colored','disp_background'], [12,'true'], Title, '#' + ObjectModel3DSelected, Instructions, Pose)
clear_object_model_3d (ObjectModel3DConnected)   //清除3D模型
select_object_model_3d (ObjectModel3DSelected, ['central_moment_2_x','central_moment_2_y'], 'and', [150,200], [400,230], ObjectModel3DCross)
clear_object_model_3d (ObjectModel3DSelected)   //清除3D模型
Title := '分段培训模式'
Message := '该对象被用作基于表面的3D匹配的输入'
dev_clear_window ()
disp_message (WindowHandle3D, Message, 'window', 50, 12, 'white', 'false')
visualize_object_model_3d (WindowHandle3D, ObjectModel3DCross, CamParam2, Pose, ['colored','disp_background'], [12,'true'], Title, '#' + ObjectModel3DCross, Instructions, Pose) 
确定生成的3D对象模型的法线方向
test_normal_direction (ObjectModel3DCross, InvertNormals)
创建一个最终反向法线的曲面模型
create_surface_model (ObjectModel3DCross, 0.03, 'model_invert_normals', InvertNormals, SurfaceModelID)

10.评估模型准确度

1.来自原始相机数据表面的3D匹配
2.将来自三角测量的结果应用于注册/三角测量管线的数据。
3.在此步骤中,我们评估该模型的准确度。

Message := '首先,我们尝试找到由相同相机获取的3D数据中的模型,而不是训练数据。'
for Index := 1 to NumSearchImages by 1
    * 读取下一个视图
    read_image (Image, ImageFiles[NumTrainingImages + Index - 1]) //读取图像
    * 从文件中读取一个 3D 模型
    read_object_model_3d ('universal_joint_part/universal_joint_part_xyz_' + (NumTrainingImages + Index - 1)$'02d', 'm', [], [], ObjectModel3D, Status)
    set_grayvals_object_model_3d (Image, ObjectModel3D)

10.1 在场景中找到模型

3D 背景中找出最佳匹配
    find_surface_model (SurfaceModelID, ObjectModel3D, 0.07, 0.2, 0.5, 'false', [], [],\
                        PoseMatch, Score, SurfaceMatchingResultID)
    pose_to_hom_mat3d (PoseMatch, HomMat3D) //将相机参数从 3D 姿态转变成 3×4 投影矩阵
    affine_trans_object_model_3d (ObjectModel3DCross, HomMat3D, ObjectModel3DAffineTrans)//将一个 3D 模型进行任意仿射转换
    dev_clear_window ()
    Title := '基于表面的匹配对应的原始数据 (' + Index + '/' + NumSearchImages + ')'
    visualize_object_model_3d (WindowHandle3D, [ObjectModel3DAffineTrans,ObjectModel3D],\
                               CamParam2, Pose, ['alpha_0','alpha_1','color_0','intensity_1'],\
                               [1.0,0.8,'green','&gray'], Title, [], Instructions, Pose)

10.2 计算模型和场景之间的距离

    计算指定 3D 模型到另一个 3D 模型的距离
    distance_object_model_3d (ObjectModel3D, ObjectModel3DAffineTrans, [], 0, 'distance_to', 'points')
    准备可视化中的颜色
    * 蓝色:远( - >),绿色:近(< - ),红色:近( - >* - >:强度随距离增加。
    * < - :强度随距离减小
    set_distance_colors (ObjectModel3D, 1.0, 2.0)
    Title := '模型质量评估,显示场景点'
    Message := '绿色阴影部分与模型对应 '
    Message[1] := '红色阴影部分距离模型很远'
    Message[2] := '蓝色阴影部分是背景'
    dev_clear_window ()
    disp_message (WindowHandle3D, Message, 'window', 50, 12, 'white', 'false')
    visualize_object_model_3d (WindowHandle3D, ObjectModel3D, CamParam2, Pose, \
                               ['alpha_0','color_0','intensity_red_0','intensity_green_0',\
                               'intensity_blue_0','disp_background'], \
                               [1.0,'gray','&interest','&correct','&distance','true'],\
                               Title, [], Instructions, Pose)
    清除场景和变形的模型
    clear_object_model_3d (ObjectModel3DAffineTrans)   //清除3D模型
    clear_object_model_3d (ObjectModel3D)   //清除3D模型
endfor
clear_surface_model (SurfaceModelID) //清除指定的曲面匹配模型

11.立体系统重建

来自不同相机的数据的3D匹配。在这种情况下:立体系统重建

init_stereo_and_surface_model (CamParam0, StereoModelID, cam_H_ref)
tuple_regexp_select (AllImageFiles, 'camera_0', ImageFiles1) //选择符合公式的数组元素
tuple_regexp_select (AllImageFiles, 'camera_1', ImageFiles2) //选择符合公式的数组元素
tuple_regexp_select (AllImageFiles, 'camera_2', ImageFiles3) //选择符合公式的数组元素
tuple_regexp_select (AllImageFiles, 'camera_3', ImageFiles4) //选择符合公式的数组元素
hom_mat3d_identity (HomMat3DScale) //创建一个三维变换矩阵
* 从mm到m(传感器数据之间的差异)
HomMat3DScale[0] := 0.001
HomMat3DScale[5] := 0.001
HomMat3DScale[10] := 0.001
affine_trans_object_model_3d (ObjectModel3DCross, HomMat3DScale, OM3DModelTmp) //将一个 3D 模型进行任意仿射转换
clear_object_model_3d (ObjectModel3DCross) //清除3D模型
get_object_model_3d_params (OM3DModelTmp, 'center', Center) //获取 3D 模型的参数
hom_mat3d_identity (HomMat3DTrans) //创建一个三维变换矩阵
hom_mat3d_translate_local (HomMat3DTrans, -Center[0], -Center[1], -Center[2], HomMat3DTranslate) //对三维变换矩阵进行平移操作
affine_trans_object_model_3d (OM3DModelTmp, HomMat3DTranslate, OM3DModel) //将一个 3D 模型进行任意仿射转换
get_object_model_3d_params (OM3DModelTmp, 'diameter', Diameter) //获取 3D 模型的参数
clear_object_model_3d (OM3DModelTmp) //清除3D模型
dev_set_draw ('margin') //设置轮廓
dev_set_line_width (3)  //设置线宽

11.1 开始匹配

为可能的正常方向创建曲面模型。 这个方向在多重设置中是不可预测的,因为它取决于使用哪个相机对来重建一个点。
create_surface_model (OM3DModel, 0.04, 'model_invert_normals', 'false', SurfaceModelID) //清除指定的曲面匹配模型

开始匹配
for IndexScene := 0 to |ImageFiles1| - 1 by 1
    * 每个场景打开4个图像
    gen_empty_obj (Images) //创建空对象
    read_image (Image1, ImageFiles1[IndexScene]) //读取图像1
    concat_obj (Images, Image1, Images) //合并图像
    read_image (Image2, ImageFiles2[IndexScene]) //读取图像2
    concat_obj (Images, Image2, Images) //合并图像
    read_image (Image3, ImageFiles3[IndexScene]) //读取图像3
    concat_obj (Images, Image3, Images) //合并图像
    read_image (Image4, ImageFiles4[IndexScene]) //读取图像4
    concat_obj (Images, Image4, Images) //合并图像
    将场景显示为图像
    dev_set_window (WindowHandle3D) //切换窗体
    tile_images (Images, TiledImage, 2, 'vertical') //把多重图像目标拼成一个大图像
    gen_rectangle1 (ImageBorders, [0,0,480,480], [0,754,0,754], [479,479,959,959], [753,1507,753,1507]) //创建矩形
    dev_display (TiledImage) //显示平铺图像
    dev_set_colored (12) //设置12众颜色
    dev_display (ImageBorders) //显示图像边界
    Message := '从4个不同的视图重建场景'
    disp_message (WindowHandle3D, Message, 'window', 12, 12, 'black', 'true') //显示信息

11.2 执行立体系统重建

    执行立体系统重建
    count_seconds (T0)  //统计时间
    reconstruct_surface_stereo (Images, StereoModelID, ObjectModelScene) //重建多视角 3D 曲面
    count_seconds (T1)  //统计时间
    Message[1] := '执行匹配...'
    disp_message (WindowHandle3D, Message, 'window', 12, 12, 'black', 'true') //显示信息

    3D数据的预处理
    首先通过消除稀疏点来过滤异常值:
    1.搜索附近其它点的点,并将对象模型划分为连接的组件
    2.只选择大组件
    3.将剩余组件合并为一个对象(如果剩余多个对象)
    4.在剩余点上,可以执行平滑以计算法线。
    这个步骤可以任意方向翻转法线,因为没有上下文可用性,哪个方向可能更好

    count_seconds (T2) //统计时间
    确定三维对象模型的连接的组件
    connection_object_model_3d (ObjectModelScene, 'distance_3d', 0.006, ObjectModel3DConnected)
    根据 3D 模型特征筛选出需要的 3D 模型
    select_object_model_3d (ObjectModel3DConnected, 'num_points', 'and', 2000, 10000000, \
                            ObjectModel3DSelected)
    clear_object_model_3d (ObjectModel3DConnected)     //清除3D模型
    * 
    if (|ObjectModel3DSelected| > 0)
        将多个 3D 模型集合当一个 3D 模型
        union_object_model_3d (ObjectModel3DSelected, 'points_surface', UnionObjectModel3D)3D 模型的三维点进行平滑处理
        smooth_object_model_3d (UnionObjectModel3D, 'mls', [], [], SmoothObject3D1)
        count_seconds (T3) //统计时间
        执行匹配,如果没有找到对象,请尝试其他正常方向
        从 3D 背景中找出最佳匹配
        find_surface_model (SurfaceModelID, SmoothObject3D1, 0.02, 0.7, 0.25, 'false', 'num_matches',\
                            3, Pose, Score, SurfaceMatchingResultID)
        count_seconds (T4) //统计时间
    else
        Score := []
    endif
    Title := '发现 ' + |Score| + ' 物体(带指示得分)在场景中 ' + (IndexScene + 1) + ' 中的 ' + |ImageFiles1|
    Message := '总执行时间: ' + (T4 - T0)$'4.2' + 's'
    Message[1] := ' - 重建:     ' + (T1 - T0)$'4.2' + 's'
    Message[2] := ' - 预处理:   ' + (T3 - T2)$'4.2' + 's'
    Message[3] := ' - 匹配:     ' + (T4 - T3)$'4.2' + 's'
    dev_clear_window () //清除窗体
    disp_message (WindowHandle3D, Message, 'window', 50, 12, 'white', 'false') //显示信息
    if (|Score| > 0)
        Objects := []
        for I := 0 to |Score| - 1 by 1
            pose_to_hom_mat3d (Pose[I * 7:I * 7 + 6], HomMat3D)//将一个三位模式转换为一个同质变换矩阵
            affine_trans_object_model_3d (OM3DModel, HomMat3D, ObjectModel3DAffineTrans)//将一个 3D 模型进行任意仿射转换
            Objects := [Objects,ObjectModel3DAffineTrans]
        endfor
        设置灰度值
        set_grayval_object_model_3d (Image1, SmoothObject3D1, cam_H_ref, CamParam0)
        3D显示结果
        visualize_object_model_3d (WindowHandle3D, [SmoothObject3D1,Objects], \
                                   CamParam0, [], \
                                   ['point_size','alpha','alpha_0','color','color_0',\
                                   'intensity_0','disp_background'], \
                                   [1.5,1.0,1.0,'green','white','&gray','true'], Title,\
                                   [' ',Score$'0.2f'], Instructions, PoseOut1)
        clear_object_model_3d ([ObjectModel3DSelected,SmoothObject3D1,Objects,UnionObjectModel3D])     //清除3D模型
        clear_object_model_3d (ObjectModelScene)     //清除3D模型
    else
        set_grayval_object_model_3d (Image1, SmoothObject3D1, cam_H_ref, CamParam0)
        visualize_object_model_3d (WindowHandle3D, SmoothObject3D1, CamParam0, [], \
                                   ['intensity','disp_background'], ['&gray','true'], \
                                   Title, [], Instructions, PoseOut)
        clear_object_model_3d (ObjectModelScene)     //清除3D模型
    endif
endfor
stop ()
clear_object_model_3d (OM3DModel)     //清除3D模型
clear_surface_model (SurfaceModelID)  //清除指定的曲面匹配模型
clear_stereo_model (StereoModelID)    //清除指定的多视角立体模型

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaWeb学习Day27】

Tlias前端 员工管理 条件分页查询&#xff1a; 页面布局 搜索栏&#xff1a; <!-- 搜索栏 --><div class"container"><el-form :inline"true" :model"searchEmp" class"demo-form-inline"><el-form-item label…

Webrtc编译官方示例实现视频通话

Webrtc编译官方示例实现视频通话 前言 webrtc官网demo中给了一个供我们学习和应用webrtc的一个很好的例子&#xff1a;peerconnection&#xff0c;这期我们就来编译和运行下这个程序看看视频通话的效果以。 1、打开源码工程 继上期源码编译完成后&#xff0c;我们使用vs打开…

大数据学习(80)-数仓分层

&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一…

刘强东突然发声:不该用算法压榨最底层兄弟!东哥,真正的人民企业家

今天忙了一天&#xff0c;很累&#xff0c;准备睡觉的时候&#xff0c;看到网上盛传的刘强东的朋友圈&#xff0c;东哥又在朋友圈发文了。 说实话&#xff0c;看完之后&#xff0c;感动&#xff0c;真的感动。 尤其是当我看到这两句话的时候。 1、我们所学的知识、商业模式、技…

Java 记忆链表,LinkedList 的升级版

文章目录 记忆链表 MemoryLinkedList实战源代码 众所周知&#xff0c;ArrayList 和 LinkedList 是 Java 集合中两个基本的数据结构&#xff0c;对应数据结构理论中的数组和链表。但在这两个数据结构&#xff0c;开发者们通常使用 ArrayList&#xff0c;而不使用 LinkedList。JD…

poetry安装与使用

文章目录 安装方法创建虚拟环境其他常用命令从 poetry.lock 中安装第三方依赖包 安装方法 安装命令&#xff08;全局安装&#xff0c;不要在虚拟环境中安装&#xff0c;方便后面创建环境使用&#xff09; pip install poetry修改虚拟环境路径&#xff08;首次使用poetry时执行&…

UVM config机制及uvm_resource_pool

目录 1. uvm_config_db 类源码 1.1 set 1.2 get 2. uvm_resource_pool 2.1 uvm_resource_pool::set 2.2 uvm_resource 3. usage 4. 小结 uvm提供一种uvm_config_db机制使得在仿真中通过变量设置来修改环境,使环境更加灵活。本文主要介绍uvm_config_db#(type)::get/set…

JAVA学习*接口

接口 在生活中我们常听说USB接口&#xff0c;那接口是什么呢&#xff1f; 在Java中&#xff0c;接口相当于多个类的一种公共规范&#xff0c;是一种引用数据类型。 定义接口 public interface IUSB {public static final String SIZE "small";public abstract vo…

Python实验:读写文本文件并添加行号

[实验目的] 熟练掌握内置函数open()的用法&#xff1b;熟练运用内置函数len()、max()、和enumerate()&#xff1b;熟练运用字符串的strip()、ljust()和其它方法&#xff1b;熟练运用列表推导式。 [实验和内容] 1.编写一个程序demo.py&#xff0c;要求运行该程序后&#xff0…

IDEA导入jar包后提示无法解析jar包中的类,比如无法解析符号 ‘log4j‘

IDEA导入jar包后提示无法解析jar包中的类 问题描述解决方法 问题描述 IDEA导入jar包的Maven坐标后&#xff0c;使用jar中的类比如log4j&#xff0c;仍然提示比如无法解析符号 log4j。 解决方法 在添加了依赖和配置文件后&#xff0c;确保刷新你的IDE项目和任何缓存&#xff…

数据结构——顺序栈seq_stack

前言&#xff1a;大家好&#x1f60d;&#xff0c;本文主要介绍了数据结构——顺序栈 目录 一、概念 1.1 顺序栈的基本概念 1.2 顺序栈的存储结构 二、基本操作 2.1 结构体定义 2.2 初始化 2.3 判空 2.4 判满 2.5 扩容 2.6 插入 入栈 2.7 删除 出栈 2.8 获取栈顶元…

python3.13.2安装详细步骤(附安装包)

文章目录 前言一、python3.13.2下载二、python3.13.2安装详细步骤1.查看安装文件2.启动安装程序3.安装模式选择4.自定义安装配置5.高级选项设置6.执行安装7.开始安装8.安装完成8.打开软件9.安装验证 前言 在数字化时代&#xff0c;Python 已成为不可或缺的编程语言。无论是开发…

AI-Talk开发板之更换串口引脚

一、默认引脚 CSK6011A使用UART0作为Debug uart&#xff0c;AI-Talk开发板默认使用的GPIOA2和GPIOA3作为Debug uart的RX和TX&#xff0c;通过连接器CN6引出。 二 、更换到其它引脚 查看60xx_iomux_v1.0可以&#xff0c;UART0的tx和rx可以映射到很多管脚上。 结合AI-Talk开发板…

深度解读DeepSeek:源码解读 DeepSeek-V3

深度解读DeepSeek&#xff1a;开源周&#xff08;Open Source Week&#xff09;技术解读 深度解读DeepSeek&#xff1a;源码解读 DeepSeek-V3 深度解读DeepSeek&#xff1a;技术原理 深度解读DeepSeek&#xff1a;发展历程 文章目录 整体流程模型初始化模型前向传播MoE https:/…

JavaIO流的使用和修饰器模式(直击心灵版)

系列文章目录 JavaIO流的使用和修饰器模式 文章目录 系列文章目录前言一、字节流&#xff1a; 1.FileInputStream(读取文件)2.FileOutputStream(写入文件) 二、字符流&#xff1a; 1..基础字符流:2.处理流&#xff1a;3.对象处理流&#xff1a;4.转换流&#xff1a; 三、修饰器…

爬虫入门re+bs4

目录 前言 1. 导入必要的库 2. 定义获取网页HTML内容的函数 get_html 3. 定义获取数据的函数 get_data 4. 定义获取文章正文内容的函数 content_text 5. 定义获取单条课程数据的函数 get_one_course_data 6. 定义保存数据的函数 save_data 7. 定义文件名合法化处理函数 sanitiz…

MySQL身份验证的auth_socket插件

在Ubuntu 20.04 LTS上&#xff0c;MySQL 8.0默认使用auth_socket插件进行身份验证&#xff0c;可能存在意想不到的情况。 一、auth_socket插件 在使用sudo mysql或通过sudo切换用户后执行任何MySQL命令时&#xff0c;不需要输入密码或错误密码都可以正常登入mysql数据库&…

使用Gitee Go流水线部署个人项目到服务器指南

使用Gitee Go流水线部署个人项目到服务器指南 前言&#xff01;&#xff01;&#xff01; 本文解决的问题&#xff1a; 你有一台ECS服务器&#xff0c;你在上面部署了一个Java服务也就是一个jar&#xff0c;你觉着你每次手动本地打包&#xff0c;上传&#xff0c;在通过命令去…

BlockChain.java

BlockChain 区块链&#xff0c;举个栗子 注意啦&#xff0c;列子里面的hashcode相等&#xff0c;但是字符串是不一样的哦&#xff0c;之前有记录这个问题 String.hashCode()-CSDN博客

【技术简析】触觉智能RK3506 Linux星闪网关开发板:重新定义工业物联新标杆

在工业智能化与物联网深度融合的今天&#xff0c;深圳触觉智能推出首款搭载瑞芯微RK3506芯片的Linux星闪网关开发板&#xff0c;为大家技术解析。 RK3506-国产芯的硬核实力 作为瑞芯微2024年第四季度推出的入门级工业芯片平台&#xff0c;RK3506以三核Cortex-A7&#xff08;1.…