HALCON示例程序measure_metal_part_id.hdev使用xld边缘拟合检测零件加工是否合格
HALCON示例程序measure_metal_part_id.hdev使用xld邊緣擬合檢測零件加工是否合格
示例程序源碼(加注釋)
-
關于顯示類函數解釋
dev_update_off ()
Imagefiles := [‘metal-parts/metal-part-model-01’,‘metal-parts/metal-parts-01’,‘metal-parts/metal-part-distorted-01’,‘metal-parts/metal-part-distorted-02’,‘metal-parts/metal-part-distorted-03’]
for k := 0 to |Imagefiles| - 1 by 1
read_image (Image, Imagefiles[k])
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, ‘light gray’, WindowID)
dev_set_part (0, 0, Height - 1, Width - 1)
dev_set_line_width (2)
dev_set_draw (‘margin’)
dev_display (Image)
set_display_font (WindowID, 16, ‘mono’, ‘true’, ‘false’)
disp_message (WindowID, ‘Image’ + k, ‘window’, 10, 10, ‘white’, ‘false’)
stop ()
dev_set_draw (‘fill’)- 二值化、膨脹,減少定義域、求取邊界
threshold (Image, Region, 90, 255)
dilation_rectangle1 (Region, RegionDilation, 10, 10)
reduce_domain (Image, RegionDilation, ImageReduced) - 提取水平閾值的交叉點
threshold_sub_pix (ImageReduced, Edges, 75) - 轉正檢測產品
orientation_region (Region, OrientationRegion)
area_center (Region, Area, RowCenter, ColumnCenter) - 創建一個以旋轉中心與旋轉角度為基礎的旋轉變換矩陣
vector_angle_to_rigid (RowCenter, ColumnCenter, OrientationRegion, RowCenter, ColumnCenter, 0, HomMat2DRotate) - 對XLD輪廓應用任意仿射2D變換。
affine_trans_contour_xld (Edges, ContoursAffinTrans, HomMat2DRotate) - 分割xld邊緣輪廓
segment_contours_xld (ContoursAffinTrans, ContoursSplit, ‘lines_circles’, 6, 4, 4) - 對XLD邊緣輪廓進行排序
sort_contours_xld (ContoursSplit, SortedContours, ‘upper_left’, ‘true’, ‘column’)
dev_clear_window ()
disp_message (WindowID, ‘Circles in a local coordinate system’, ‘window’, 10, 10, ‘white’, ‘false’)
dev_set_color (‘black’)
dev_display (SortedContours)
dev_set_color (‘white’)
count_obj (SortedContours, NumberSegments)
RowsE := []
ColsE := []
RadiiE := []
gen_empty_obj (Lines)
dev_set_color (‘white’)
count_obj (Lines, NumberLines)- 根據線的方向篩選xld輪廓
select_contours_xld (Lines, LinesVertical, ‘direction’, rad(88), rad(92), 0, 0)
count_obj (LinesVertical, NumberLV) - 根據線的方向篩選xld輪廓
select_contours_xld (Lines, LinesHorizontal, ‘direction’, rad(-2), rad(2), 0, 0)
count_obj (LinesHorizontal, NumberLH)
ColVmin := 0
RowHmax := 0
for i := 1 to NumberLV by 1
select_obj (LinesVertical, SelectedV, i)
get_contour_xld (SelectedV, RowV, ColV)
if (i == 1)
ColVmin := ColV[0]
RowA1 := RowV[0]
ColA1 := ColV[0]
RowA2 := RowV[1]
ColA2 := ColV[1]
else
if (ColV[0] < ColVmin)
ColVmin := ColV[0]
RowA1 := RowV[0]
ColA1 := ColV[0]
RowA2 := RowV[1]
ColA2 := ColV[1]
endif
endif
endfor
for j := 1 to NumberLH by 1
select_obj (LinesHorizontal, SelectedH, j)
get_contour_xld (SelectedH, RowH, ColH)
if (RowH[0] > RowHmax)
RowHmax := RowH[0]
RowB1 := RowH[0]
ColB1 := ColH[0]
RowB2 := RowH[1]
ColB2 := ColH[1]
endif
endfor - 求兩直線交點
intersection_lines (RowA1, ColA1, RowA2, ColA2, RowB1, ColB1, RowB2, ColB2, RowO, ColO, IsOverlapping)
gen_cross_contour_xld (Cross, RowO, ColO, 10, 0.785398)
dev_display (Cross)
disp_arrow (WindowID, RowO, ColO, RowO - 100, ColO, 2)
disp_arrow (WindowID, RowO, ColO, RowO, ColO + 100, 2) - 仿射變換的齊次矩陣
hom_mat2d_identity (HomMat2DIdentityResults) - 添加旋轉
hom_mat2d_slant (HomMat2DIdentityResults, rad(180), ‘x’, 0, 0, HomMat2DSlantResults) - 添加平移
hom_mat2d_translate (HomMat2DSlantResults, RowO, -ColO, HomMat2DTranslateResults) - 進行像素的仿射變換
affine_trans_pixel (HomMat2DTranslateResults, RowsE, ColsE, RowsELocal, ColsELocal)
if (k == 0)
RowsELocalRef := RowsELocal
ColsELocalRef := ColsELocal
RadiiERef := RadiiE
NumberRowsERef := |RowsELocal|
for i := 0 to |RadiiE| - 1 by 1
disp_message (WindowID, i + 1, ‘window’, RowsE[i] + 10, ColsE[i] + RadiiE[i], ‘white’, ‘false’)
endfor
disp_message (WindowID, ‘Reference Object’, ‘window’, 50, 10, ‘white’, ‘false’)
else
ID_Deviation := []
ID_Missing := []
NumberRowsE := |RowsE|
if (NumberRowsE == NumberRowsERef)
distance_pp (RowsELocalRef, ColsELocalRef, RowsELocal, ColsELocal, DistanceEllipseCenters)
DiffRadius := abs(RadiiE - RadiiERef)
for i := 0 to |DistanceEllipseCenters| - 1 by 1
if (DistanceEllipseCenters[i] > 2 or DiffRadius[i] > 2)
ID_Deviation := [ID_Deviation,i + 1]
endif
endfor
endif
if (NumberRowsE < NumberRowsERef)
j := 0
for i := 0 to NumberRowsE - 1 by 1
ok := 0
while (ok == 0)
distance_pp (RowsELocalRef[j], ColsELocalRef[j], RowsELocal[i], ColsELocal[i], Distance)
DiffRadius := abs(RadiiE[i] - RadiiERef[j])
if ((Distance < 10) and (DiffRadius < 10))
if (Distance > 2 or DiffRadius > 2)
ID_Deviation := [ID_Deviation,j + 1]
endif
ok := 1
else
ID_Missing := [ID_Missing,j + 1]
endif
if (j == NumberRowsERef - 1)
ok := 1
endif
j := j + 1
endwhile
endfor
endif
if (NumberRowsE > NumberRowsERef)
disp_message (WindowID, ‘There are more circles than in the reference model!’, ‘window’, 350, 150, ‘white’, ‘false’)
endif
dev_set_draw (‘margin’)
NumCircleDeviation := |ID_Deviation|
NumCircleMissing := |ID_Missing|
counter := 0
* 仿射變換的反變換
hom_mat2d_invert (HomMat2DTranslateResults, HomMat2DInvert)
for i := 0 to NumCircleDeviation - 1 by 1
index := ID_Deviation[i]
counter := counter + 1
disp_message (WindowID, 'Deviation (>2 pixels) for circle with index ’ + index, ‘window’, 30 + counter * 20, 10, ‘red’, ‘false’)
affine_trans_pixel (HomMat2DInvert, RowsELocalRef[index - 1], ColsELocalRef[index - 1], RowsEVis, ColsEVis)
gen_circle (Circle, RowsEVis, ColsEVis, RadiiERef[index - 1])
dev_display (Circle)
endfor
for i := 0 to NumCircleMissing - 1 by 1
index := ID_Missing[i]
counter := counter + 1
disp_message (WindowID, 'Missing: circle with index ’ + index, ‘window’, 30 + counter * 20, 10, ‘red’, ‘false’)
affine_trans_pixel (HomMat2DInvert, RowsELocalRef[index - 1], ColsELocalRef[index - 1], RowsEVis, ColsEVis)
gen_circle (Circle, RowsEVis, ColsEVis, RadiiERef[index - 1])
dev_display (Circle)
endfor
endif
stop ()
endfor
dev_update_window (‘on’) - 二值化、膨脹,減少定義域、求取邊界
處理思路
這個例子是主要講解了xld輪廓的擬合和xld輪廓的仿射變換。
后記
大家有什么問題可以向我提問哈,我看到了第一時間回復,希望在學習的路上多多結交良師益友。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的HALCON示例程序measure_metal_part_id.hdev使用xld边缘拟合检测零件加工是否合格的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Levenberg-Marquardt(
- 下一篇: 数论和有限域的基本概念