利用形狀匹配進行定位,然後提取影象上特定的線段
阿新 • • 發佈:2018-12-10
*********************************************************************** * * 檔名稱: Matching Demo * 摘 要: 利用形狀匹配進行定位,然後提取影象上特定的線段 * 當前版本: 1.0 * 作 者: 平頭鷹 * 郵 箱: [email protected] * 完成日期: 2018年10月12日 *------------------------------------------------------------------------ ************************************************************************ *** 環境初始化 *** dev_close_window () list_image_files ('Image', 'default', [], ImageFiles) if (|ImageFiles|<1) return () endif read_image (Image, ImageFiles[0]) get_image_size (Image, Width, Height) dev_open_window (0, 0, Width/4, Height/4, 'black', WindowHandle) dev_set_draw ('margin') dev_display (Image) ************************************************************************ *** 建立形狀模板 *** ******************* * 根據專案的實際需求,建立模板可能會選擇不同的方式: * 1.如果影象是有紋理的,一般選用歸一化的灰度模板,create_ncc_model。 * 比如,有暗紋的窗簾布,上面又印刷了一些圖案,我們在定位這些圖案的時候,可以 * 考慮這種ncc。此外,99%的用到匹配的,基本上都用形狀匹配的方式; * 2.使用形狀匹配,Halcon中常用的有兩類建立模板的方式。其一,是使用給定的Region, * 利用create_(scaled_)shape_model運算元,自動提取輪廓建立模板;其二,某些情況, * 如果直接利用給定的Region,自動提取的結果會有比較多的干擾,這是時候,我們往 * 往會利用手動繪製輪廓,然後利用create_scaled_shape_model_xld的方式建立模板。 ************************************************ * 方法1,利用Region直接建立模板 ************************************************ * draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2) * gen_rectangle1 (Rect0, Row1, Column1, Row2, Column2) gen_rectangle1 (Rect0, 811.5, 991.5, 1171.5, 1251.5) * draw_rectangle1 (WindowHandle, Row11, Column11, Row21, Column21) * gen_rectangle1 (Rect1, Row11, Column11, Row21, Column21) gen_rectangle1 (Rect1, 895.5, 1119.5, 1079.5, 1339.5) * 通常情況下,我們需要的實際輪廓並不是標準圖形,如果用了標準圖形建立ModelRegion * 的話,會有一些非共同特徵的輪廓被提取出來,這樣會影響我們匹配的準確性,因此,可 * 在建立模板區域的時候,做一些區域處理。 difference (Rect0, Rect1, ModelRegion) reduce_domain (Image, ModelRegion, ModelImage) create_shape_model (ModelImage, 'auto', rad(-10), rad(20), 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID) get_shape_model_contours (ModelContours, ModelID, 1) * 顯示模板輪廓。使用get_shape_model_contours運算元得到的輪廓,預設的輪廓的中心會 * 在(0, 0)位置,為了顯示直觀,我們把輪廓移動的它“本來的”位置 area_center(ModelRegion, Area, RowRefer, ColRefer) vector_angle_to_rigid (0, 0, 0, RowRefer, ColRefer, 0, HomMat2D) affine_trans_contour_xld (ModelContours, ShowContours, HomMat2D) dev_display (Image) dev_display (ShowContours) * 儲存模板。在實際的專案開發中,模板不會在每次啟動程式都建立,因此,往往是建立之後 * 儲存下來,在下次程式啟動載入,直接使用。 write_shape_model (ModelID, 'RegionModel.shm') *----------------------------------------------- ************************************************ * 方法2,利用繪製XLD或者直接讀入.dxf檔案建立模板 ************************************************ ** draw_xld (ContOut, WindowHandle, 'true', 'true', 'true', 'true') ** write_contour_xld_dxf (ContOut, 'MyDrawXld.dxf') * read_contour_xld_dxf (ModelContours, 'MyDrawXld.dxf', [], [], DxfStatus) ** 注意:這裡用的是create_scaled_shape_model_xld,因為無論是手動畫的或者是讀入的CAD ** 檔案,可能和實際拍攝的都會有一個縮放差,因此用“scaled” * create_scaled_shape_model_xld (ModelContours, 'auto', rad(-10), rad(20), 'auto', 0.9, 1.1, 'auto', 'auto', 'ignore_local_polarity', 5, ModelID) * find_scaled_shape_model (Image, ModelID, rad(-10), rad(20), 0.9, 1.1, 0.5, 1, 0.5, 'least_squares', 0, 0.9, ReferRow, ReferCol, Angle1, Scale1, Score1) * write_shape_model (ModelID, 'XldModel.shm') * get_shape_model_contours (ModelContours, ModelID, 1) *----------------------------------------------- ************************************************************************ *** 建立測量模板 *** ******************* * 這部分可參考halcon標準例子"measure_stamping_part.hdev" create_metrology_model (MetrologyHandle) set_metrology_model_image_size (MetrologyHandle, Width, Height) * draw_line (WindowHandle, Row_1, Col_1, Row_2, Col_2) * Line := [Row_1, Col_1, Row_2, Col_2] Line := [892.385, 1395.79, 1245.35, 1395.79] add_metrology_object_generic (MetrologyHandle, 'line', Line, 25, 5, 1, 30, [], [], LineIndices) get_metrology_object_model_contour (ModelContour, MetrologyHandle, 'all', 1.5) get_metrology_object_measures (MeasureContour, MetrologyHandle, 'all', 'all', Row, Column) * 把測量的位置和模板的位置關聯起來 set_metrology_model_param (MetrologyHandle, 'reference_system', [RowRefer, ColRefer, 0]) set_metrology_object_param (MetrologyHandle, LineIndices, 'measure_transition', 'positive') set_metrology_object_param (MetrologyHandle, LineIndices, 'measure_select', 'first') set_metrology_object_param (MetrologyHandle, LineIndices, 'measure_length1', 55) set_metrology_object_param (MetrologyHandle, LineIndices, 'measure_length2', 5) set_metrology_object_param (MetrologyHandle, LineIndices, 'measure_threshold', 10) set_metrology_object_param (MetrologyHandle, LineIndices, 'min_score', 0.3) ************************************************************************ *** 查詢形狀模板 *** ******************* read_shape_model ('RegionModel.shm', ModelID) *read_shape_model ('XldModel.shm', ModelID) get_shape_model_contours (ModelContours, ModelID, 1) ** 畫搜尋ROI。實際應用中,查詢模板往往是要指定ROI的,這樣可以提高準確度,減少計算時間 * draw_rectangle1 (WindowHandle, Row12, Column12, Row22, Column22) * gen_rectangle1 (SearchRegion, Row12, Column12, Row22, Column22) gen_rectangle1 (SearchRegion, 811.5, 1003.5, 1159.5, 1279.5) for i := 0 to |ImageFiles|-1 by 1 read_image (Image, ImageFiles[i]) reduce_domain (Image, SearchRegion, SearchImage) find_scaled_shape_model (SearchImage, ModelID, rad(-10), rad(20), 0.9, 1.1, 0.3, 1, 0.5, 'least_squares', 0, 0.9, RowFound, ColFound, AngleFound, ScaleFound, ScoreFound) * 如果找到模板 if (1 = |RowFound|) hom_mat2d_identity (HomMat2D) hom_mat2d_scale (HomMat2D, ScaleFound, ScaleFound, 0, 0, HomMat2D) hom_mat2d_rotate (HomMat2D, AngleFound, 0, 0, HomMat2D) hom_mat2d_translate (HomMat2D, RowFound - 0, ColFound - 0, HomMat2D) affine_trans_contour_xld (ModelContours, ResultContours, HomMat2D) * 按照找到的模板位置,移動測量位置 align_metrology_model (MetrologyHandle, RowFound, ColFound, AngleFound) * 應用測量 apply_metrology_model (Image, MetrologyHandle) * 獲取結果 get_metrology_object_measures (Contour, MetrologyHandle, 'all', 'all', Row, Column) * gen_cross_contour_xld(Cross, Row, Column, 6, AngleFound) get_metrology_object_result (MetrologyHandle, 'all', 'all', 'used_edges', 'row', UsedRow) get_metrology_object_result (MetrologyHandle, 'all', 'all', 'used_edges', 'column', UsedColumn) gen_cross_contour_xld (UsedEdges, UsedRow, UsedColumn, 10, rad(45)) get_metrology_object_result_contour (ResultContours, MetrologyHandle, 'all', 'all', 1.5) dev_set_color ('gray') dev_display (Contour) dev_set_color ('blue') dev_display (UsedEdges) dev_set_color ('green') dev_display (ResultContours) *將xld轉換成region ,region轉換成骨架 gen_region_contour_xld (ResultContours, Region, 'filled') skeleton (Region, Skeleton) region_features (Skeleton, 'area', Value) else disp_message (WindowHandle, '沒有找到模板', 'window', Row, Column, 'black', 'true') endif stop () endfor