news 2026/4/3 3:02:06

【多目立体视觉】--多相机3D表面重建技术(通过从不同视角拍摄的多张二维图像,计算像素间的视差,进而恢复出场景的三维结构)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【多目立体视觉】--多相机3D表面重建技术(通过从不同视角拍摄的多张二维图像,计算像素间的视差,进而恢复出场景的三维结构)

Halcon实战:基于surface_fusion的多相机3D表面重建技术详解

一、引言

在工业机器视觉领域,多视图立体视觉(MVS)是实现三维重建的核心技术之一。它通过从不同视角拍摄的多张二维图像,计算像素间的视差,进而恢复出场景的三维结构。本案例详细展示了如何使用Halcon的surface_fusion方法,对多相机采集的图像序列进行3D表面重建。

surface_fusion方法是Halcon提供的一种高级3D重建技术,它建立在surface_pairwise(成对匹配)的基础上,通过融合来自多个相机对的重建结果,生成一个更完整、更精确的三维表面模型。这种方法特别适用于需要高精度、高完整性3D模型的场景,如零部件检测、逆向工程和质量控制。

二、核心知识点铺垫

1. 多相机系统与相机模型

一个典型的多相机3D重建系统由多个固定在不同位置的相机组成。在进行重建前,必须通过相机标定过程获取每个相机的内参(如焦距、主点)和外参(如位置、姿态)。这些参数被保存在相机设置模型(.csm文件)中,供重建算法使用。

2. 视差计算(Disparity Calculation)

视差是指同一物理点在不同相机图像上的投影位置差异。它是三维重建的基础。Halcon提供了多种视差计算方法,如binocular_disparity,可以通过设置不同的匹配算法(如NCC)、窗口大小和过滤选项来优化视差图的质量。

3.surface_pairwisesurface_fusion

  • surface_pairwise:该方法首先对每一对相机拍摄的图像进行立体匹配,计算出视差图,然后通过三角测量原理,将视差图转换为稀疏的三维点云。
  • surface_fusion:该方法以surface_pairwise生成的多组稀疏点云为输入,通过一种融合算法,将这些点云合并并优化,最终生成一个连续、光滑的三维表面模型。

4. 关键参数

  • Resolution:定义了重建后3D模型的体素(Voxel)大小。分辨率越高,模型越精细,但计算量和内存消耗也越大。
  • BoundingBox:定义了3D重建的空间范围。只有在该范围内的点才会被重建,合理设置可以显著减少计算量。
  • SurfaceTolerance:表面容差,用于控制表面重建的平滑程度和精度。

三、核心算子列表

算子名核心功能
read_camera_setup_model读取相机设置模型文件(.csm),获取相机内外参。
create_stereo_model创建一个多视图立体模型,并指定重建方法(如’surface_fusion’)。
set_stereo_model_param设置立体模型的各种参数,如视差计算方法、分辨率、边界框等。
set_stereo_model_image_pairs定义用于立体匹配的相机图像对。
reconstruct_surface_stereo执行3D表面重建,生成最终的3D物体模型。
get_stereo_model_object_model_3d获取重建过程中生成的中间结果(如’surface_pairwise’的点云)。
visualize_object_model_3d可视化显示3D物体模型,支持旋转、缩放和平移交互。
clear_stereo_model清除立体模型,释放内存。
clear_object_model_3d清除3D物体模型,释放内存。

四、完整代码+中文注释(// 格式)

// 【示例说明】本示例演示如何使用 'surface_fusion' 方法从多个相机的图像中重建多个物体的3D模型。 // 核心流程:加载相机模型 -> 创建立体模型 -> 设置参数 -> 循环重建并显示结果。 dev_close_window () // 关闭当前窗口 dev_update_off () // 关闭窗口更新,提高运行效率 dev_open_window (0, 0, 512, 512, 'black', WindowHandle) // 打开一个新窗口 dev_resize_window_fit_size (0, 0, 1024, 600, -1, -1) // 调整窗口大小以适应显示 set_display_font (WindowHandle, 14, 'mono', 'true', 'false') // 设置显示字体 // 定义交互说明信息 Instructions := 'Rotate: Left button' Instructions[1] := 'Zoom: Shift + left button' Instructions[2] := 'Move: Ctrl + left button' // 显示介绍信息 Message := 'This example reconstructs several 3D objects using the method \'surface_fusion\'.' Message[2] := ' ' Message[3] := 'The \'surface_fusion\' method uses the results of the method \'surface_pairwise\' as' Message[4] := 'input for the fusion algorithm. Therefore, the pairwise parameters have to be' Message[5] := 'configured as well.' Message[6] := ' ' Message[7] := 'For all reconstructions, the same parameter settings are used. ' Message[8] := 'It is possible to tweak the parameters to optimally fit one particular object.' Message[9] := 'This will improve the reconstruction results even further.' dev_disp_text (Message, 'window', 12, 12, 'white', 'box', 'false') // 显示多行文本 dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], []) // 显示底部提示 stop () // 暂停,等待用户按键 // 【重建分辨率选择】 // 为了演示目的,使用相对较低的分辨率,以减少运行时间。 // 如果追求更高精度,可以将此参数设置为false。 FastReconstruction := true // 根据分辨率选择设置参数 if (FastReconstruction) Resolution := 0.0012 // 设置重建分辨率为1.2毫米 Info := ', coarse resolution' // 记录分辨率信息 else Resolution := 0.0006 // 设置重建分辨率为0.6毫米 Info := ', fine resolution' // 记录分辨率信息 endif SurfaceTolerance := 2 * Resolution // 设置表面容差为分辨率的两倍 // 【加载相机模型】 read_camera_setup_model ('cam_setup_model.csm', CameraSetupModelID) // 读取相机设置模型文件 // 获取相机数量 get_camera_setup_param (CameraSetupModelID, 'general', 'num_cameras', NumCameras) // 【创建立体模型】 // 使用 'surface_fusion' 方法创建一个多视图立体模型 create_stereo_model (CameraSetupModelID, 'surface_fusion', [], [], StereoModelID) clear_camera_setup_model (CameraSetupModelID) // 清除相机设置模型,释放内存 // 【配置立体模型参数】 // 设置图像校正的插值方法为双线性插值 set_stereo_model_param (StereoModelID, 'rectif_interpolation', 'bilinear') // 定义用于立体匹配的相机图像对(这里使用相机0与相机1、相机0与相机2的组合) set_stereo_model_image_pairs (StereoModelID, [0,0], [1,2]) // 设置视差计算方法为 'binocular' set_stereo_model_param (StereoModelID, 'disparity_method', 'binocular') // 设置双目匹配算法为归一化互相关(NCC) set_stereo_model_param (StereoModelID, 'binocular_method', 'ncc') // 设置匹配窗口大小为11x11 set_stereo_model_param (StereoModelID, 'binocular_mask_width', 11) set_stereo_model_param (StereoModelID, 'binocular_mask_height', 11) // 启用左右一致性检查以提高匹配的鲁棒性 set_stereo_model_param (StereoModelID, 'binocular_filter', 'left_right_check') // 使用插值方法计算亚像素级视差,提高精度 set_stereo_model_param (StereoModelID, 'binocular_sub_disparity', 'interpolation') // 【循环处理多个物体数据集】 NumObjects := 5 // 物体总数 for I := 1 to NumObjects by 1 // 读取当前物体的所有相机图像 read_image (Images, '3d_machine_vision/multi_view/engine_part_cam_' + [0:2] + '_0' + I) // 将图像拼接起来以便显示 tile_images (Images, TiledImage, 2, 'vertical') // 【设置重建边界框】 // 根据不同物体设置不同的3D重建空间范围 if (I == 1) BoundingBox := [-0.134,-0.043,-0.005,-0.022,0.067,0.042] elseif (I == 2) BoundingBox := [-0.135,-0.039,-0.005,-0.02,0.075,0.035] elseif (I == 3 or I == 4) BoundingBox := [-0.14,-0.048,-0.005,-0.018,0.088,0.040] elseif (I == 5) BoundingBox := [-0.147,-0.077,-0.005,-0.02,0.088,0.04] endif set_stereo_model_param (StereoModelID, 'bounding_box', BoundingBox) // 启用持久化模式,以便获取 'surface_pairwise' 的中间结果 set_stereo_model_param (StereoModelID, 'persistence', 1) // 设置点云网格化方法为 'isosurface',生成连续的表面 set_stereo_model_param (StereoModelID, 'point_meshing', 'isosurface') // 设置重建分辨率 set_stereo_model_param (StereoModelID, 'resolution', Resolution) // 设置表面容差 set_stereo_model_param (StereoModelID, 'surface_tolerance', SurfaceTolerance) // 设置结果的颜色属性为 'median'(中值颜色) set_stereo_model_param (StereoModelID, 'color', 'median') // 如果是快速重建,增加平滑程度以减少噪点 if (FastReconstruction) set_stereo_model_param (StereoModelID, 'smoothing', 1.5) endif // 显示当前处理的图像 dev_resize_window_fit_image (TiledImage, 0, 0, -1, -1) get_part (WindowHandle, Row1, Column1, Row2, Column2) dev_clear_window () dev_display (TiledImage) dev_disp_text ('Reconstruct scene from 3 different views. Please wait...', 'window', 12, 12, 'black', [], []) // 【执行3D重建】 count_seconds (S1) // 记录开始时间 reconstruct_surface_stereo (Images, StereoModelID, OM3DFusion) // 执行表面融合重建 count_seconds (S2) // 记录结束时间 // 获取 'surface_pairwise' 方法生成的中间3D模型(点云) get_stereo_model_object_model_3d (StereoModelID, 'm3d_pairwise', OM3DPairwise) // 创建一个可视化用的位姿(Pose) create_pose (0.026, -0.07, 1.9, 330, 345, 300, 'Rp+T', 'gba', 'point', VisPose) // 【可视化显示结果】 // 1. 显示 'surface_pairwise' 的中间结果(橙色点云) Title := 'Intermediate result (reconstructed using \'surface_pairwise\'' + Info + ') (' + I + '/' + NumObjects + ')' visualize_object_model_3d (WindowHandle, OM3DPairwise, [], VisPose, ['color','point_size'], ['orange',1], Title, [], Instructions, VisPose) // 2. 显示 'surface_fusion' 的融合结果 Title := 'Reconstructed object model using \'surface_fusion\'' + Info + ' (' + I + '/' + NumObjects + ')' visualize_object_model_3d (WindowHandle, OM3DFusion, [], VisPose, [], [], Title, [], Instructions, VisPose) // 3. 显示最终的、带颜色和三角化的融合结果,并显示重建时间 Title := 'Final result (colored and triangulated' + Info + ') (' + I + '/' + NumObjects + ')\nReconstruction time: ' + (S2 - S1)$'.2' + ' s (Resolution ' + (Resolution * 1000) + ' mm)' visualize_object_model_3d (WindowHandle, OM3DFusion, [], VisPose, 'color_attrib', 'red', Title, [], Instructions, VisPose) // 清理当前物体的3D模型,释放内存 clear_object_model_3d (OM3DPairwise) clear_object_model_3d (OM3DFusion) endfor // 清理立体模型,释放内存 clear_stereo_model (StereoModelID)


五、核心算子深度剖析

1.create_stereo_model

功能

创建一个多视图立体视觉模型,是进行3D重建的入口。该算子会根据指定的相机设置模型和重建方法,初始化内部数据结构。

参数说明
参数名含义示例值
CameraSetupModelID输入相机设置模型的句柄,包含了所有相机的内外参数。CameraSetupModelID
Method指定3D重建的方法。'surface_fusion'
GenParamName可选的通用参数名列表。[]
GenParamValue可选的通用参数值列表。[]
StereoModelID输出新创建的立体模型的句柄。StereoModelID

2.set_stereo_model_param

功能

设置立体模型的各种参数,以控制重建过程的各个方面。这是优化重建效果的关键。

常用参数说明
参数名含义常用取值
'disparity_method'视差计算方法。'binocular'
'binocular_method'双目匹配算法。'ncc','sad'
'binocular_mask_width'匹配窗口宽度。5, 7, 9, 11
'binocular_mask_height'匹配窗口高度。5, 7, 9, 11
'bounding_box'3D重建的空间范围。[XMin, YMin, ZMin, XMax, YMax, ZMax]
'resolution'3D模型的体素分辨率。0.001(1mm)
'surface_tolerance'表面重建的容差。2 * Resolution
'color'输出3D模型的颜色属性。'median','nearest'

3.reconstruct_surface_stereo

功能

执行3D表面重建。该算子是整个流程的核心,它会使用之前设置好的所有参数和相机模型,对输入的多张图像进行处理,最终生成一个三维物体模型。

参数说明
参数名含义示例值
Images输入的多张相机图像。Images
StereoModelID立体模型的句柄。StereoModelID
ObjectModel3D输出的重建结果,是一个3D物体模型句柄。OM3DFusion

4.get_stereo_model_object_model_3d

功能

获取在reconstruct_surface_stereo执行过程中生成的中间或附加的3D物体模型。

参数说明
参数名含义示例值
StereoModelID立体模型的句柄。StereoModelID
ObjectName要获取的3D物体模型的名称。'm3d_pairwise'
ObjectModel3D输出获取到的3D物体模型句柄。OM3DPairwise

六、全流程解析

步骤1:环境初始化与参数设置

代码首先关闭了不必要的窗口更新,打开了一个新的显示窗口,并设置了字体。然后定义了一个布尔变量FastReconstruction来选择不同的重建分辨率,这直接影响了重建的速度和精度。

步骤2:加载相机模型

通过read_camera_setup_model读取相机配置文件(.csm),该文件包含了进行三维重建所必需的相机内外参数。

步骤3:创建并配置立体模型

使用create_stereo_model创建了一个基于'surface_fusion'方法的立体模型。接着,通过一系列set_stereo_model_param调用,详细配置了视差计算、图像对选择、重建分辨率、边界框等关键参数。

步骤4:循环处理多个物体

代码对5个不同的物体进行了循环处理:

  1. 读取图像:读取当前物体的所有相机视图图像。
  2. 设置边界框:根据物体的大小和位置,设置合适的3D重建空间范围。
  3. 执行重建:调用reconstruct_surface_stereo进行3D表面融合重建,并记录重建时间。
  4. 获取中间结果:使用get_stereo_model_object_model_3d获取'surface_pairwise'方法生成的中间点云结果。
  5. 可视化结果:使用visualize_object_model_3d分别显示了中间的点云结果、最终的融合表面模型以及带有颜色和三角化的最终模型,方便用户进行观察和比较。
  6. 资源清理:在每次循环结束后,清理当前物体的3D模型,释放内存。

步骤5:资源释放

最后,在所有物体处理完毕后,清理立体模型,释放所有相关资源。

七、实战优化建议

1. 分辨率与精度的权衡

  • 高精度需求:如果应用场景(如精密零件检测)对模型精度要求极高,应将FastReconstruction设为false,使用Resolution := 0.0006或更小的分辨率。
  • 实时性需求:如果需要快速得到重建结果(如在线检测),则应使用较高的分辨率(如0.0012),并可以考虑启用smoothing参数来减少噪点。

2. 边界框(BoundingBox)的优化

  • 精确测量:在设置BoundingBox前,可以先用较低分辨率对物体进行一次快速重建,获取其大致的空间范围,然后在此基础上稍微扩大一点作为精确重建的边界框。
  • 避免冗余:边界框不应设置过大,否则会包含大量空的空间,增加计算量和内存使用。

3. 视差计算参数调优

  • 匹配窗口大小:对于纹理丰富的表面,可以使用较小的窗口(如5x5或7x7)以提高细节;对于纹理较少或重复纹理的表面,应使用较大的窗口(如11x11或15x15)以提高匹配的鲁棒性。
  • 匹配算法选择'ncc'(归一化互相关)对光照变化不敏感,适用于大多数场景;'sad'(绝对差之和)计算速度更快,但对光照变化较为敏感。

4. 表面后处理

重建得到的3D模型可以通过Halcon的其他算子进行后处理,例如:

  • smooth_object_model_3d:对表面进行平滑处理。
  • reduce_object_model_3d:对点云进行下采样,减少数据量。
  • compute_object_model_3d_metrics:计算3D模型的体积、表面积等度量。

八、总结

本案例详细介绍了如何使用Halcon的surface_fusion方法进行多相机3D表面重建。通过对代码的逐行解析和核心算子的深入剖析,我们理解了多视图立体视觉重建的完整流程,包括相机模型加载、立体模型创建与配置、三维重建执行以及结果可视化。

surface_fusion方法通过融合多个相机对的重建结果,能够生成比传统成对匹配方法更完整、更精确的3D表面模型,是工业三维检测和质量控制领域的强大工具。掌握其参数调优方法和实战技巧,对于成功应用该技术至关重要。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/1 14:53:28

python基于Vue的网上药店购物管理系统_ngw98_django Flask pycharm项目

目录已开发项目效果实现截图关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!已开发项目效果实现截图 同行可拿货,招校园代理 ,本人源头供货商 python基于Vue的网上药店购物管理系统…

作者头像 李华
网站建设 2026/3/11 16:11:02

JAVA无人台球棋牌室:线上智控,畅玩无忧

JAVA无人台球棋牌室系统通过高并发架构、智能硬件集成与社交化运营,实现了线上预约、智能设备控制、安全管控及数据分析的全流程自动化,为用户提供“畅玩无忧”的无人化娱乐体验,同时助力商家降本增效。 以下是具体分析:一、技术架…

作者头像 李华
网站建设 2026/3/29 7:29:14

无需手动CUDA安装:Miniconda-Python3.9自动匹配NVIDIA驱动版本

无需手动CUDA安装:Miniconda-Python3.9自动匹配NVIDIA驱动版本 在深度学习项目启动的前48小时里,有多少开发者真正用在写代码上?恐怕大部分时间都花在了“为什么PyTorch检测不到GPU”“cuDNN版本不兼容”这类环境问题上。尤其是在实验室共用服…

作者头像 李华
网站建设 2026/3/28 23:05:43

CUDA Toolkit静默安装:Miniconda-Python3.9镜像后台自动配置

CUDA Toolkit静默安装:Miniconda-Python3.9镜像后台自动配置 在深度学习项目部署过程中,最让人头疼的往往不是模型本身,而是环境搭建——明明本地跑得好好的代码,换一台机器就报错“CUDA not available”;不同项目的依…

作者头像 李华
网站建设 2026/3/25 23:16:27

Anaconda配置PyTorch环境步骤繁琐?Miniconda-Python3.9一键搞定

Miniconda-Python3.9:轻量构建PyTorch环境,告别Anaconda臃肿配置 在人工智能实验室的深夜里,你是否经历过这样的场景:刚拿到一台新的GPU服务器,满心期待地准备复现一篇论文,结果卡在了环境配置上&#xff1…

作者头像 李华