文章目錄
- 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
)。
- ?StereoModelID?:生成的立體模型句柄,用于后續操作(如
- 輸入參數
-
典型工作流程
- 創建模型? ```
create_stereo_model(CameraSetupModelID, 'surface_pairwise', [], [], StereoModelID)
創建表面重建模型,初始化參數為空列表。
-
?配置參數?
通過set_stereo_model_param
設置關鍵參數:'sub_sampling_step'
:控制重建分辨率(如3
表示每 3 個像素采樣一次)。'rectif_interpolation'
:指定圖像矯正插值方法(如'bilinear'
)。
-
?執行重建?
調用reconstruct_surface_stereo
生成 3D 表面模型。 -
應用場景
-
?工業檢測?:如管道接頭的多視角 3D 重建,通過 4 相機系統生成高精度表面模型。
-
?機器人導航?:結合手眼標定,將重建的 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])
作用?
? 指定用于表面重建的立體圖像對?,其核心原理和必要性如下:
-
函數功能與參數含義
-
?功能定位?
該函數用于為'surface_pairwise'
或'surface_fusion'
類型的立體模型(StereoModelID
)配置圖像對列表,通過視差計算實現表面重建。若模型類型不匹配(如'points_3d'
),則會報錯。- 參數解析:
[0,2]
表示第一組圖像對的左視圖索引為0,右視圖索引為2;[1,3]
表示第二組圖像對的左視圖索引為1,右視圖索引為3。
這些索引需在相機標定模型(CameraSetupModelID
)的有效范圍內。
- 參數解析:
-
多視角重建流程?
該函數是重建流程的關鍵步驟之一,需在create_stereo_model
創建模型后調用,并在reconstruct_surface_stereo
執行前完成圖像對配置。
-
-
圖像對選擇的依據
- ?視差計算需求?
多視角重建通過計算圖像對的視差圖生成3D表面。例如,[0,2]
表示從相機0到相機2的視差計算,覆蓋不同視角的幾何關系。- ?優化策略?:選擇交會角適中(如30°-60°)、特征匹配數量多的圖像對,可提升重建精度。
- 覆蓋性與效率平衡?
- ?覆蓋性?:
[0,2]
和[1,3]
的組合可能覆蓋場景的不同區域,避免單一視角的盲區。 - ?效率?:減少冗余圖像對(如相鄰視角)可降低計算量,但需保證重建完整性。
- ?覆蓋性?:
- ?視差計算需求?
-
參數設置示例分析
- ? 相機布局假設
- 相機0和2、1和3可能分別位于場景的左右兩側,形成交叉基線,增強深度感知。
- 視差多樣性
- 不同基線的圖像對(如短基線0-1和長基線0-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)