Halcon例程(基于3D形状匹配识别方法)详解 —— create_shape_model_3d_lowest_model_level.hdev
一、例程簡(jiǎn)介
最近在研究3D識(shí)別方面的東西,查了不少資料,發(fā)現(xiàn)halcon里有不少關(guān)于三維物體識(shí)別的例程,這里對(duì)其中一個(gè)做出詳解。該例程是基于三維匹配方法的,因?yàn)橛腥S模型SM3,所以不需要自己創(chuàng)建;另因?yàn)槔讨械膱D像有多種不同的姿態(tài),建立三維模型所需要的內(nèi)存會(huì)很大,所以設(shè)定最低模型級(jí)別,顯著降低了算法運(yùn)行時(shí)間,但相對(duì)的,會(huì)損失算法的魯棒性和檢索時(shí)間。
 
二、例程詳解
dev_update_off () * 設(shè)置面掃相機(jī)參數(shù),參數(shù)可通過相機(jī)校正來獲取。此算子為庫(kù)函數(shù),通過Division畸變模型生成一個(gè)相機(jī)參數(shù)元組。 * 其中參數(shù)含義為(焦距,模擬徑向透鏡畸變的畸變系數(shù),傳感器上兩個(gè)相鄰單元之間的水平距離,傳感器上兩個(gè)相鄰單元之間的垂直距離,光心列坐標(biāo),光心行坐標(biāo),圖寬,圖高,輸出相機(jī)參數(shù)) gen_cam_par_area_scan_division (0.0269462, -354.842, 1.27964e-005, 1.28e-005, 254.24, 201.977, 512, 384, CamParam) { CameraParam :=['area_scan_division',Focus,Kappa,Sx,Sy,Cx,Cy,ImageWidth,ImageHeight] return () } * 獲取相機(jī)參數(shù),返回要求的圖像寬參數(shù)。 get_cam_par_data (CamParam, 'image_width', IWidth) { *返回相機(jī)的類型和參數(shù)名 get_cam_par_names (CameraParam, CameraType, CameraParamNames) * * 找到相機(jī)數(shù)據(jù)的索引并返回對(duì)應(yīng)的值。 ParamValue := [] *依次讀取參數(shù)名,ParamName在get_cam_par_names已被賦值,為'image_width' for Index := 0 to |ParamName| - 1 by 1ParamNameInd := ParamName[Index]if (ParamNameInd == 'camera_type')ParamValue := [ParamValue,CameraType]continueendif* I為'image_width'在CameraParamNames的索引值,為7I := find(CameraParamNames,ParamNameInd)if (I != -1)*將圖寬值賦值給ParamValueParamValue := [ParamValue,CameraParam[I]]elsethrow ('Unknown camera parameter ' + ParamNameInd)endif endfor return () } get_cam_par_data (CamParam, 'image_height', IHeight) * read_image (Image, 'tile_spacers/tile_spacers_color_01') dev_close_window () dev_open_window (0, 0, 512 * 1.5, 384 * 1.5, 'white', WindowHandle) set_display_font (WindowHandle, 16, 'mono', 'true', 'false') dev_set_line_width (3) dev_clear_window () disp_message (WindowHandle, 'Reading the 3D shape model file from disk ...', 'window', 12, 12, 'black', 'false') * 如果磁盤沒有可用的話就創(chuàng)建3D模型 try * 讀取3D形狀模型,具體地址在C盤MVTec文件夾下examples\hdevelop\3D-Matching\Shape-Based。read_shape_model_3d ('tile_spacer.sm3', ShapeModel3DID) catch (Exception)* 讀目標(biāo)3D模型的DXF文件,CAD格式,但因?yàn)樯弦徊娇梢赃\(yùn)行,所以這一部分沒用了。* 參數(shù)(文件名,文件單位的轉(zhuǎn)換尺度(單位為100um),參數(shù)名,參數(shù)值,3D模型句柄,狀態(tài)信息)read_object_model_3d ('tile_spacer.dxf', 0.0001, [], [], ObjectModel3DID, DXFStatus)*為指定操作準(zhǔn)備3D模型,可以計(jì)算所需要的值并儲(chǔ)存在objectModel3D*參數(shù)(3D模型句柄,目的,指定是否應(yīng)覆蓋已存在的數(shù)據(jù),參數(shù)名,參數(shù)值)prepare_object_model_3d (ObjectModel3DID, 'shape_based_matching_3d', 'true', [], [])disp_message (WindowHandle, 'Reading the 3D shape model file from disk ... not found!', 'window', 12, 12, 'red', 'false')disp_message (WindowHandle, 'Creating the 3D shape model (may take a few seconds) ...', 'window', 42, 12, 'black', 'false')count_seconds (S1)* 創(chuàng)建3D形狀模型,是通過計(jì)算三維物體模型在用戶指定的姿勢(shì)范圍內(nèi)的不同視圖而生成的。通過在三維物體模型周圍放置虛擬攝像機(jī),并將三維物體模型投影到每個(gè)虛擬攝像機(jī)位置的圖像平面上,自動(dòng)生成視圖;* 因此,在生成三維形狀模型時(shí),不使用對(duì)象的圖像,只使用在objectModel3D中傳遞的三維對(duì)象模型,所有視圖的形狀表示都存儲(chǔ)在三維形狀模型中,該模型返回到shapeModel3DID中。在創(chuàng)建三維形狀模型之前,必須校準(zhǔn)相機(jī),以防止畸變。* 參數(shù)(3D模型句柄,相機(jī)參數(shù),沿x軸/x分量旋轉(zhuǎn)的羅德里格斯矢量,y軸,z軸,參考向量的旋轉(zhuǎn)值,模型視圖的最小經(jīng)度,* 最大經(jīng)度,模型視圖的最小緯度,最大緯度,模型視圖的最小攝影機(jī)滾動(dòng)角度,最大角度,模型視圖的最小攝影機(jī)對(duì)象距離,最大距離,搜索圖像中對(duì)象的最小對(duì)比度,用于控制運(yùn)算符行為的(可選)參數(shù)的名稱(最低模型級(jí)別),可選參數(shù)值,句柄)create_shape_model_3d (ObjectModel3DID, CamParam, 0, 0, 0, 'gba', -rad(60), rad(60), -rad(60), rad(60), 0, rad(360), 0.26, 0.27, 10, 'lowest_model_level', 3, ShapeModel3DID)count_seconds (S2)T := S2 - S1disp_message (WindowHandle, 'Creation time: ' + T$'.3' + ' s', 'window', 72, 12, 'black', 'false')trydisp_message (WindowHandle, 'Writing model to disk ...', 'window', 102, 12, 'black', 'false')*存儲(chǔ)3D模型write_shape_model_3d (ShapeModel3DID, 'tile_spacer.sm3')catch (Exception)disp_message (WindowHandle, 'Writing model to disk ... failed!', 'window', 102, 12, 'red', 'false')disp_continue_message (WindowHandle, 'black', 'true')stop ()endtry endtry *顯示模型信息 disp_lowest_model_level_info (WindowHandle) disp_continue_message (WindowHandle, 'black', 'true') stop () * 匹配 Times := [] NumImages := 12 for I := 1 to NumImages by 1read_image (Image, 'tile_spacers/tile_spacers_color_' + I$'02')dev_display (Image)* * 查找三個(gè)三維模型的實(shí)例,將“border”模型設(shè)置為“true”,因?yàn)閷?duì)象可能會(huì)接觸圖像邊界* 程序開始到現(xiàn)在過去的時(shí)間count_seconds (Seconds1)*在圖像中找出一個(gè)3D模型的最佳匹配*參數(shù)(輸入圖像,3D模型的句柄,最低分?jǐn)?shù)(值越大,搜索速度越快),貪婪度(值越大,搜索越快,但更容易失敗),(該值決定搜索過程中金字塔層的數(shù)量,設(shè)為0,則數(shù)量為創(chuàng)建模型時(shí)的指定值),控制操作行為的參數(shù)名,參數(shù)值,模型的3D位姿,姿態(tài)參數(shù)的36個(gè)協(xié)方差或6個(gè)標(biāo)準(zhǔn)差,分?jǐn)?shù))find_shape_model_3d (Image, ShapeModel3DID,0.7, 0.85, 0, ['num_matches','max_overlap','border_model'], [3,0.75,'true'], Pose, CovPose, Score)count_seconds (Seconds2)計(jì)算匹配時(shí)間Time := Seconds2 - Seconds1Times := [Times,Time]*通過使用匹配的姿勢(shì)將三維形狀模型投影到圖像中,將找到的匹配項(xiàng)可視化for J := 0 to |Score| - 1 by 1*顯示輪廓PoseTmp := Pose[J * 7:J * 7 + 6]*將三維形狀模型的邊投影到圖像坐標(biāo)中。project_shape_model_3d (ModelContours, ShapeModel3DID, CamParam, PoseTmp, 'true', rad(30))dev_set_color ('yellow')dev_display (ModelContours)* 顯示3D模型的坐標(biāo)系dev_set_colored (3)disp_3d_coord_system (WindowHandle, CamParam, PoseTmp, 0.015)endforfor K := 0 to |Score| - 1 by 1* 顯示找到的位姿的參數(shù)PoseTmp := Pose[K * 7:K * 7 + 6]*自定義函數(shù),顯示位姿信息display_match_pose (ShapeModel3DID, PoseTmp, WindowHandle){*查找模型參數(shù)(參考點(diǎn)坐標(biāo)),get_shape_model_3d_params (ShapeModel3DID, 'reference_point', ReferencePoint)*查找相機(jī)參數(shù)get_shape_model_3d_params (ShapeModel3DID, 'cam_param', CamParam) * * Project the reference point * 將三維姿態(tài)轉(zhuǎn)換為齊次變換矩陣。 pose_to_hom_mat3d (Pose, HomMat3D) *對(duì)點(diǎn)應(yīng)用任意仿射3D變換 affine_trans_point_3d (HomMat3D, ReferencePoint[0], ReferencePoint[1], ReferencePoint[2], X, Y, Z) *將3D點(diǎn)投影到(亞)像素圖像坐標(biāo)中。 project_3d_point (X, Y, Z, CamParam, Row, Column) * 顯示參考點(diǎn)坐標(biāo) Message := 'Pose:' Message[1] := ' X: ' + (1000 * Pose[0])$'4.1f' + ' mm' Message[2] := ' Y: ' + (1000 * Pose[1])$'4.1f' + ' mm' Message[3] := ' Z: ' + (1000 * Pose[2])$'4.1f' + ' mm' Message[4] := ' Alpha: ' + Pose[3]$'4.1f' + '°' Message[5] := ' Beta: ' + Pose[4]$'4.1f' + '°' Message[6] := ' Gamma: ' + Pose[5]$'4.1f' + '°' disp_message (WindowHandle, Message, 'image', Row, Column - 30, 'black', ['#ffffffcc','false']) return () }endfor*在左上角顯示匹配用時(shí)disp_message (WindowHandle, |Score| + ' Match(es) found in ' + Time$'4.2f' + ' s', 'window', 12, 12, 'dark green', ['white','false'])if (I < NumImages)disp_continue_message (WindowHandle, 'black', ['white','false'])stop ()endif endfor * disp_end_of_program_message (WindowHandle, 'black', ['white','false'])三、總結(jié)
下面對(duì)上述基于形狀的3D匹配方法進(jìn)行總結(jié),主要包含以下幾個(gè)步驟:
 1.讀取/創(chuàng)建3D模型read_object_model_3d/create_shape_model_3d;
 2.對(duì)二維圖像進(jìn)行3D匹配,計(jì)算得分,find_shape_model_3d
 3將匹配結(jié)果可視化,project_shape_model_3d,project_3d_point
 總的來看,這種3D匹配方法還是比較好用的,對(duì)于物體間遮擋的情況也可以進(jìn)行識(shí)別,難點(diǎn)在于調(diào)參吧。該方法的原理根據(jù)三維模型的位姿信息來對(duì)圖像中的目標(biāo)進(jìn)行搜索并判斷,返回一個(gè)匹配度值,網(wǎng)上沒有更為詳細(xì)的代碼,應(yīng)該是比較難吧,基于點(diǎn)云的還有不少資料,目前業(yè)界關(guān)于3D識(shí)別方面的項(xiàng)目還沒有很普遍,研究者較少,希望后面有所改善。
 如果大家有意見和想法,可以一起交流,注意點(diǎn)贊評(píng)論哦。
總結(jié)
以上是生活随笔為你收集整理的Halcon例程(基于3D形状匹配识别方法)详解 —— create_shape_model_3d_lowest_model_level.hdev的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 深入学习linux socket编程之s
 - 下一篇: cadence学习笔记(2)-PCB封装