1. 程式人生 > >Halcon一維測量官方案例解析

Halcon一維測量官方案例解析

下面的例子簡要介紹瞭如何使用HALCON的一維測量工具。最長的部分是預處理和後處理;測量本身只包括兩個操作符呼叫。 # 測量保險絲-fuse ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200713193438593-793621641.png) 預處理主要是測量線的生成。在示例程式中,這個步驟是通過將測量物件的引數分配給變數來完成的。 ``` read_image (Fuse, 'fuse') Row := 297 Column := 545 Length1 := 80 Length2 := 10 Angle := rad(90) gen_rectangle2 (ROI, Row, Column, Angle, Length1, Length2) ``` 現在通過將測量物件應用到影象上進行實際測量。引數的選擇使得暗區周圍的邊緣被分為兩組線段,結果返回邊緣的位置和兩組線段的寬度和距離。 ``` measure_pairs (Fuse, MeasureHandle, 1, 1, 'negative', 'all', RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance) ``` ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200713193552248-838941218.png) 最後生成一個帶有測量線引數的區域,並將邊緣位置轉換為短XLD等值線來顯示結果。 ``` for i := 0 to |RowEdgeFirst| - 1 by 1 gen_contour_polygon_xld (EdgeFirst, [-sin(Angle + rad(90)) * Length2 + RowEdgeFirst[i],-sin(Angle - rad(90)) * Length2 + RowEdgeFirst[i]], [cos(Angle + rad(90)) * Length2 + ColumnEdgeFirst[i],cos(Angle - rad(90)) * Length2 + ColumnEdgeFirst[i]]) gen_contour_polygon_xld (EdgeSecond, [-sin(Angle + rad(90)) * Length2 + RowEdgeSecond[i],-sin(Angle - rad(90)) * Length2 + RowEdgeSecond[i]], [cos(Angle + rad(90)) * Length2 + ColumnEdgeSecond[i],cos(Angle - rad(90)) * Length2 + ColumnEdgeSecond[i]]) dev_set_color ('cyan') dev_display (EdgeFirst) dev_set_color ('magenta') dev_display (EdgeSecond) dev_set_color ('blue') if (i == 0) set_tposition (WindowID, RowEdgeFirst[i] + 5, ColumnEdgeFirst[i] + 20) else set_tposition (WindowID, RowEdgeFirst[i] - 40, ColumnEdgeFirst[i] + 20) endif write_string (WindowID, 'width: ' + IntraDistance[i] + ' pix') endfor ``` ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200713193629880-952777310.png) 源程式 ``` * fuse.hdev: 測量保險絲的寬度 * dev_update_window ('off') dev_close_window () * **** * 採集影象 * **** read_image (Fuse, 'fuse') get_image_size (Fuse, Width, Height) dev_open_window_fit_image (Fuse, 0, 0, Width, Height, WindowID) set_display_font (WindowID, 12, 'mono', 'true', 'false') dev_set_draw ('margin') dev_set_line_width (3) dev_display (Fuse) set_display_font (WindowID, 12, 'mono', 'true', 'false') disp_continue_message (WindowID, 'black', 'true') stop () * **** * 建立測量物件 * **** * -> specify ROI Row := 297 Column := 545 Length1 := 80 Length2 := 10 Angle := rad(90) gen_rectangle2 (ROI, Row, Column, Angle, Length1, Length2) * -> create measure object gen_measure_rectangle2 (Row, Column, Angle, Length1, Length2, Width, Height, 'bilinear', MeasureHandle) dev_display (ROI) disp_continue_message (WindowID, 'black', 'true') stop () * **** * 測量 * **** measure_pairs (Fuse, MeasureHandle, 1, 1, 'negative', 'all', RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance) disp_continue_message (WindowID, 'black', 'true') stop () * **** * 結果視覺化 * **** for i := 0 to |RowEdgeFirst| - 1 by 1 gen_contour_polygon_xld (EdgeFirst, [-sin(Angle + rad(90)) * Length2 + RowEdgeFirst[i],-sin(Angle - rad(90)) * Length2 + RowEdgeFirst[i]], [cos(Angle + rad(90)) * Length2 + ColumnEdgeFirst[i],cos(Angle - rad(90)) * Length2 + ColumnEdgeFirst[i]]) gen_contour_polygon_xld (EdgeSecond, [-sin(Angle + rad(90)) * Length2 + RowEdgeSecond[i],-sin(Angle - rad(90)) * Length2 + RowEdgeSecond[i]], [cos(Angle + rad(90)) * Length2 + ColumnEdgeSecond[i],cos(Angle - rad(90)) * Length2 + ColumnEdgeSecond[i]]) dev_set_color ('cyan') dev_display (EdgeFirst) dev_set_color ('magenta') dev_display (EdgeSecond) dev_set_color ('blue') if (i == 0) set_tposition (WindowID, RowEdgeFirst[i] + 5, ColumnEdgeFirst[i] + 20) else set_tposition (WindowID, RowEdgeFirst[i] - 40, ColumnEdgeFirst[i] + 20) endif write_string (WindowID, 'width: ' + IntraDistance[i] + ' pix') endfor disp_continue_message (WindowID, 'black', 'true') stop () * **** * 銷燬物件 * **** close_measure (MeasureHandle) dev_update_window ('on') dev_clear_window () ``` # 測量金屬鑄造部件-measure_arc 本例是檢測鑄件倒角後拉長孔之間的距離。為了達到最好的精度,建議使用背光與遠心鏡頭相結合的方式,而不是圖中的設定。 ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200713193714401-1735746743.png) 這個任務可以通過使用帶有圓形測量ROI的測量工具輕鬆解決。ROI的中心被放置在鑄件的中心;半徑設定為拉長孔與中心的距離。 ``` Row := 275 Column := 335 Radius := 107 AngleStart := -rad(55) AngleExtent := rad(170) gen_measure_arc (Row, Column, Radius, AngleStart, AngleExtent, 10, Width, Height, 'nearest_neighbor', MeasureHandle) ``` ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200713193738171-767456660.png) 現在,可以通過一個運算子的呼叫來測量孔之間的距離。 ``` measure_pos (Zeiss1, MeasureHandle, 1, 10, 'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance) ``` ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200713193744370-2142046793.png) 源程式 ``` * 例子包括很多視覺化操作。 read_image (Zeiss1, 'zeiss1') get_image_size (Zeiss1, Width, Height) dev_close_window () dev_open_window (0, 0, Width / 2, Height / 2, 'black', WindowHandle) set_display_font (WindowHandle, 14, 'mono', 'true', 'false') dev_display (Zeiss1) disp_continue_message (WindowHandle, 'black', 'true') stop () * draw_circle (WindowHandle, Row, Column, Radius) Row := 275 Column := 335 Radius := 107 AngleStart := -rad(55) AngleExtent := rad(170) dev_set_draw ('fill') dev_set_color ('green') dev_set_line_width (1) get_points_ellipse (AngleStart + AngleExtent, Row, Column, 0, Radius, Radius, RowPoint, ColPoint) disp_arc (WindowHandle, Row, Column, AngleExtent, RowPoint, ColPoint) dev_set_line_width (3) gen_measure_arc (Row, Column, Radius, AngleStart, AngleExtent, 10, Width, Height, 'nearest_neighbor', MeasureHandle) disp_continue_message (WindowHandle, 'black', 'true') stop () count_seconds (Seconds1) n := 10 for i := 1 to n by 1 measure_pos (Zeiss1, MeasureHandle, 1, 10, 'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance) endfor count_seconds (Seconds2) Time := (Seconds2 - Seconds1) / n disp_continue_message (WindowHandle, 'black', 'true') * stop () distance_pp (RowEdge[1], ColumnEdge[1], RowEdge[2], ColumnEdge[2], IntermedDist) * dev_display (Zeiss1) dev_set_color ('red') * disp_circle (WindowHandle, RowEdge, ColumnEdge, RowEdge - RowEdge + 1) disp_line (WindowHandle, RowEdge[1], ColumnEdge[1], RowEdge[2], ColumnEdge[2]) dev_set_color ('yellow') disp_message (WindowHandle, 'Distance: ' + IntermedDist, 'image', 250, 80, 'yellow', 'false') * dump_window (WindowHandle, 'tiff_rgb', 'C:\\Temp\\zeiss_result') dev_set_line_width (1) * disp_continue_message (WindowHandle, 'black', 'true') stop () dev_clear_window () ``` # 使用模糊測量法測量積體電路-fuzzy_measure_pin ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200713193807880-1228112791.png) 本例是測量IC的引線寬度和引線距離。本例中的照明條件相當困難,造成了每個引線都有四個邊緣可見。模糊規則就是用於將測量限制在正確的(外)引線上。 ``` gen_measure_rectangle2 (Row2, Col2, Phi2, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle2) create_funct_1d_pairs ([0.0,0.3], [1.0,0.0], FuzzyAbsSizeDiffFunction) set_fuzzy_measure_norm_pair (MeasureHandle1, 11.0, 'size_abs_diff', FuzzyAbsSizeDiffFunction) fuzzy_measure_pairs (Image, MeasureHandle1, 1, 30, 0.5, 'positive', RowEdgeFirst1, ColumnEdgeFirst1, AmplitudeFirst1, RowEdgeSecond1, ColumnEdgeSecond1, AmplitudeSecond1, RowEdgeMiddle1, ColumnEdgeMiddle1, FuzzyScore1, IntraDistance1, InterDistance1) ``` ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200713193816680-796505505.png) 源程式 ``` dev_close_window () read_image (Image, 'board/board-06') get_image_size (Image, Width, Height) dev_open_window (0, 0, Width, Height, 'black', WindowHandle) * * 模糊測量: Row1 := 305.5 Col1 := 375.5 Phi1 := 0.982 Length1 := 167 Length2 := 8 gen_measure_rectangle2 (Row1, Col1, Phi1, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle1) Row2 := 188.5 Col2 := 202.5 Phi2 := Phi1 - rad(180) gen_measure_rectangle2 (Row2, Col2, Phi2, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle2) * 建立一個模糊函式來選擇晶片引腳邊緣對的大小(約11Pixels)。 create_funct_1d_pairs ([0.0,0.3], [1.0,0.0], FuzzyAbsSizeDiffFunction) set_fuzzy_measure_norm_pair (MeasureHandle1, 11.0, 'size_abs_diff', FuzzyAbsSizeDiffFunction) set_fuzzy_measure_norm_pair (MeasureHandle2, 11.0, 'size_abs_diff', FuzzyAbsSizeDiffFunction) fuzzy_measure_pairs (Image, MeasureHandle1, 1, 30, 0.5, 'positive', RowEdgeFirst1, ColumnEdgeFirst1, AmplitudeFirst1, RowEdgeSecond1, ColumnEdgeSecond1, AmplitudeSecond1, RowEdgeMiddle1, ColumnEdgeMiddle1, FuzzyScore1, IntraDistance1, InterDistance1) fuzzy_measure_pairs (Image, MeasureHandle2, 1, 30, 0.5, 'positive', RowEdgeFirst2, ColumnEdgeFirst2, AmplitudeFirst2, RowEdgeSecond2, ColumnEdgeSecond2, AmplitudeSecond2, RowEdgeMiddle2, ColumnEdgeMiddle2, FuzzyScore2, IntraDistance2, InterDistance2) * * 視覺化: dev_display (Image) * 視覺化測量區域 dev_display_measure_object (Row1, Col1, Phi1, Length1, Length2) dev_display_measure_object (Row2, Col2, Phi2, Length1, Length2) * 視覺化邊緣對 dev_set_draw ('fill') Pin := 1 dev_display_profile_points ([RowEdgeFirst1,RowEdgeSecond1], [ColumnEdgeFirst1,ColumnEdgeSecond1], Row1, Col1, Phi1, Length1, Length2) for I := 0 to |ColumnEdgeFirst1| - 1 by 1 disp_message (WindowHandle, 'size:' + IntraDistance1[I]$'.2f' + ' score:' + FuzzyScore1[I]$'.2f', 'image', RowEdgeSecond1[I], ColumnEdgeSecond1[I] + 10, 'yellow', 'false') MRow := RowEdgeSecond1[I] - 5 MCol := ColumnEdgeSecond1[I] - 20 dev_set_color ('white') gen_circle (Circle, MRow, MCol, 10) dev_display (Circle) get_string_extents (WindowHandle, Pin, Ascent, Descent, SWidth, SHeight) disp_message (WindowHandle, Pin, 'window', MRow - SHeight / 2, MCol - SWidth / 2, 'black', 'false') Pin := Pin + 1 endfor dev_display_profile_points ([RowEdgeFirst2,RowEdgeSecond2], [ColumnEdgeFirst2,ColumnEdgeSecond2], Row2, Col2, Phi2, Length1, Length2) for I := 0 to |ColumnEdgeFirst2| - 1 by 1 dev_set_color ('yellow') disp_message (WindowHandle, 'size:' + IntraDistance2[I]$'.2f' + ' score:' + FuzzyScore2[I]$'.2f', 'image', RowEdgeFirst2[I], ColumnEdgeFirst2[I] + 10, 'yellow', 'false') MRow := RowEdgeFirst2[I] - 5 MCol := ColumnEdgeFirst2[I] - 20 dev_set_color ('white') gen_circle (Circle, MRow, MCol, 10) dev_display (Circle) get_string_extents (WindowHandle, Pin, Ascent, Descent, SWidth, SHeight) disp_message (WindowHandle, Pin, 'window', MRow - SHeight / 2, MCol - SWidth / 2, 'black', 'false') Pin := Pin + 1 endfor ``` # 測量可移動的IC的引線-pm_measure_board 本例的任務是測量可移動的晶片引線的位置。 由於晶片可以出現在不同的位置和角度,用於測量的感興趣的區域必須對齊。 在這種情況下,通過使用基於形狀的匹配搜尋晶片上的印刷字元來實現對準。 ``` gen_rectangle2 (Rectangle2, Row + Rect2Row, Column + Rect2Col, RectPhi, RectLength1, RectLength2) reduce_domain (Image, Rectangle, ImageReduced) create_shape_model (ImageReduced, 4, 0, rad(360), rad(1), 'none', 'use_polarity', 30, 10, ModelID) ``` ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200713193903648-1215389587.png) 找到印刷品後,ROI的位置將相對於印刷字元的位置進行幾何變換。 ``` find_shape_model (ImageCheck, ModelID, 0, rad(360), 0.7, 1, 0.5, 'least_squares', 4, 0.7, RowCheck, ColumnCheck, AngleCheck, Score) hom_mat2d_identity (HomMat2DIdentity) hom_mat2d_translate (HomMat2DIdentity, RowCheck, ColumnCheck, HomMat2DTranslate) hom_mat2d_rotate (HomMat2DTranslate, AngleCheck, RowCheck, ColumnCheck, HomMat2DRotate) affine_trans_pixel (HomMat2DRotate, Rect1Row, Rect1Col, Rect1RowCheck, Rect1ColCheck) ``` ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200713193913956-1790259161.png) 然後,建立測量工具並應用測量。 ``` gen_measure_rectangle2 (Rect1RowCheck, Rect1ColCheck, AngleCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle1) measure_pairs (ImageCheck, MeasureHandle1, 2, 90, 'positive', 'all', RowEdgeFirst1, ColumnEdgeFirst1, AmplitudeFirst1, RowEdgeSecond1, ColumnEdgeSecond1, AmplitudeSecond1, IntraDistance1, InterDistance1) ``` ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200713193921659-1071396918.png) 源程式 ``` * 這個示例程式展示瞭如何使用模式匹配與形狀模型來定位一個物件。 此外,它還展示瞭如何使用檢測到的物體位置和旋轉來構建檢測任務的ROI。在這個例子中,IC上的印刷字元被用來尋找IC。 從找到的位置和旋轉,構建兩個測量矩形來測量IC引線之間的間距。 由於打光的緣故,引線在幾個位置和旋轉處的飽和灰度值為255,這擴大了引線的實際寬度,減小了引線之間的間距。 dev_update_pc ('off') dev_update_window ('off') dev_update_var ('off') open_framegrabber ('File', 1, 1, 0, 0, 0, 0, 'default', -1, 'default', -1, 'default', 'board/board.seq', 'default', -1, 1, FGHandle) grab_image (Image, FGHandle) get_image_size (Image, Width, Height) dev_close_window () dev_open_window (0, 0, Width, Height, 'black', WindowHandle) dev_open_window (Height + 70, 0, Width, 120, 'black', WindowHandleText) dev_set_window (WindowHandle) set_display_font (WindowHandle, 16, 'mono', 'true', 'false') set_display_font (WindowHandleText, 16, 'mono', 'true', 'false') dev_set_color ('red') dev_display (Image) Row1 := 188 Column1 := 182 Row2 := 298 Column2 := 412 gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2) area_center (Rectangle, Area, Row, Column) Rect1Row := -102 Rect1Col := 5 Rect2Row := 107 Rect2Col := 5 RectPhi := 0 RectLength1 := 170 RectLength2 := 5 gen_rectangle2 (Rectangle1, Row + Rect1Row, Column + Rect1Col, RectPhi, RectLength1, RectLength2) gen_rectangle2 (Rectangle2, Row + Rect2Row, Column + Rect2Col, RectPhi, RectLength1, RectLength2) reduce_domain (Image, Rectangle, ImageReduced) create_shape_model (ImageReduced, 4, 0, rad(360), rad(1), 'none', 'use_polarity', 30, 10, ModelID) get_shape_model_contours (ShapeModel, ModelID, 1) hom_mat2d_identity (HomMat2DIdentity) hom_mat2d_translate (HomMat2DIdentity, Row, Column, HomMat2DTranslate) affine_trans_contour_xld (ShapeModel, ShapeModelTrans, HomMat2DTranslate) dev_display (Image) dev_set_color ('green') dev_display (ShapeModelTrans) dev_set_color ('blue') dev_set_draw ('margin') dev_set_line_width (3) dev_display (Rectangle1) dev_display (Rectangle2) dev_set_draw ('fill') dev_set_line_width (1) dev_set_color ('yellow') disp_message (WindowHandle, ['Press left button to start','and stop the demo'], 'window', 12, 12, 'black', 'true') get_mbutton (WindowHandle, Row3, Column3, Button1) wait_seconds (0.5) Button := 0 while (Button != 1) dev_set_window (WindowHandle) dev_set_part (0, 0, Height - 1, Width - 1) grab_image (ImageCheck, FGHandle) dev_display (ImageCheck) count_seconds (S1) find_shape_model (ImageCheck, ModelID, 0, rad(360), 0.7, 1, 0.5, 'least_squares', 4, 0.7, RowCheck, ColumnCheck, AngleCheck, Score) count_seconds (S2) dev_display (ImageCheck) if (|Score| > 0) dev_set_color ('green') hom_mat2d_identity (HomMat2DIdentity) hom_mat2d_translate (HomMat2DIdentity, RowCheck, ColumnCheck, HomMat2DTranslate) hom_mat2d_rotate (HomMat2DTranslate, AngleCheck, RowCheck, ColumnCheck, HomMat2DRotate) affine_trans_contour_xld (ShapeModel, ShapeModelTrans, HomMat2DRotate) dev_display (ShapeModelTrans) affine_trans_pixel (HomMat2DRotate, Rect1Row, Rect1Col, Rect1RowCheck, Rect1ColCheck) affine_trans_pixel (HomMat2DRotate, Rect2Row, Rect2Col, Rect2RowCheck, Rect2ColCheck) gen_rectangle2 (Rectangle1Check, Rect1RowCheck, Rect1ColCheck, AngleCheck, RectLength1, RectLength2) gen_rectangle2 (Rectangle2Check, Rect2RowCheck, Rect2ColCheck, AngleCheck, RectLength1, RectLength2) dev_set_color ('blue') dev_set_draw ('margin') dev_set_line_width (3) dev_display (Rectangle1Check) dev_display (Rectangle2Check) dev_set_draw ('fill') count_seconds (S3) gen_measure_rectangle2 (Rect1RowCheck, Rect1ColCheck, AngleCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle1) gen_measure_rectangle2 (Rect2RowCheck, Rect2ColCheck, AngleCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle2) measure_pairs (ImageCheck, MeasureHandle1, 2, 90, 'positive', 'all', RowEdgeFirst1, ColumnEdgeFirst1, AmplitudeFirst1, RowEdgeSecond1, ColumnEdgeSecond1, AmplitudeSecond1, IntraDistance1, InterDistance1) measure_pairs (ImageCheck, MeasureHandle2, 2, 90, 'positive', 'all', RowEdgeFirst2, ColumnEdgeFirst2, AmplitudeFirst2, RowEdgeSecond2, ColumnEdgeSecond2, AmplitudeSecond2, IntraDistance2, InterDistance2) count_seconds (S4) dev_set_color ('red') disp_line (WindowHandle, RowEdgeFirst1 - RectLength2 * cos(AngleCheck), ColumnEdgeFirst1 - RectLength2 * sin(AngleCheck), RowEdgeFirst1 + RectLength2 * cos(AngleCheck), ColumnEdgeFirst1 + RectLength2 * sin(AngleCheck)) disp_line (WindowHandle, RowEdgeSecond1 - RectLength2 * cos(AngleCheck), ColumnEdgeSecond1 - RectLength2 * sin(AngleCheck), RowEdgeSecond1 + RectLength2 * cos(AngleCheck), ColumnEdgeSecond1 + RectLength2 * sin(AngleCheck)) disp_line (WindowHandle, RowEdgeFirst2 - RectLength2 * cos(AngleCheck), ColumnEdgeFirst2 - RectLength2 * sin(AngleCheck), RowEdgeFirst2 + RectLength2 * cos(AngleCheck), ColumnEdgeFirst2 + RectLength2 * sin(AngleCheck)) disp_line (WindowHandle, RowEdgeSecond2 - RectLength2 * cos(AngleCheck), ColumnEdgeSecond2 - RectLength2 * sin(AngleCheck), RowEdgeSecond2 + RectLength2 * cos(AngleCheck), ColumnEdgeSecond2 + RectLength2 * sin(AngleCheck)) dev_set_line_width (1) NumLeads := |IntraDistance1| + |IntraDistance2| MinDistance := min([InterDistance1,InterDistance2]) dev_set_window (WindowHandleText) dev_set_part (0, 0, 119, Width - 1) dev_clear_window () disp_message (WindowHandleText, 'Matching: Time: ' + ((S2 - S1) * 1000)$'5.2f' + 'ms , Score: ' + Score$'7.5f', 'image', 20, 20, 'green', 'false') disp_message (WindowHandleText, 'Measure: Time: ' + ((S4 - S3) * 1000)$'5.2f' + ' ms, Num. leads: ' + NumLeads$'2d', 'image', 50, 20, 'red', 'false') disp_message (WindowHandleText, ' Min. lead dist: ' + MinDistance$'6.3f', 'image', 80, 20, 'red', 'false') endif dev_error_var (Error, 1) dev_set_check ('~give_error') get_mposition (WindowHandle, R, C, Button) dev_error_var (Error, 0) dev_set_check ('give_error') if (Error != H_MSG_TRUE) Button := 0 endif endwhile dev_set_window (WindowHandleText) dev_close_window () close_framegrabber (FGHandle) ``` # 測量IC-measure_pin 本例的任務是檢查積體電路的主要尺寸。 ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200714120922275-1015758169.png) 第一步,測量每個引線的範圍和引線之間的距離。為此,定義了一個包含引線的矩形用來生成測量物件。這是用來提取垂直於矩形主軸線的直邊對。 ``` gen_measure_rectangle2 (Row, Column, Phi, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle) measure_pairs (Image, MeasureHandle, 1.5, 30, 'negative', 'all', RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, PinWidth, PinDistance) ``` ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200714120932644-1779923987.png) 從提取的直邊對中,得出引線的數量、平均寬度和它們之間的平均距離。 ``` avgPinWidth := sum(PinWidth) / |PinWidth| avgPinDistance := sum(PinDistance) / |PinDistance| numPins := |PinWidth| ``` ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200714120939615-1204911762.png) 第二部分顯示測量工具。儘管每根引線的寬度只有幾個畫素,導線的長度是可以確定的。為此,一個基於包含IC兩邊相對引線的矩形的測量物件生成了。第一個和第二個邊緣之間的距離是上引線的長度,第三個和第四個邊緣之間的距離是下引線的長度。 ``` gen_measure_rectangle2 (Row, Column, Phi, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle) measure_pos (Image, MeasureHandle, 1.5, 30, 'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance) ``` ![](https://img2020.cnblogs.com/blog/1570888/202007/1570888-20200714120946343-670247401.png) 源程式 ``` dev_close_window () read_image (Image, 'ic_pin') get_image_size (Image, Width, Height) dev_open_window (0, 0, Width / 2, Height / 2, 'black', WindowHandle) set_display_font (WindowHandle, 14, 'mono', 'true', 'false') dev_display (Image) disp_continue_message (WindowHandle, 'black', 'true') stop () * draw_rectangle2 (WindowHandle, Row, Column, Phi, Length1, Length2) Row := 47 Column := 485 Phi := 0 Length1 := 420 Length2 := 10 dev_set_color ('green') dev_set_draw ('margin') dev_set_line_width (3) gen_rectangle2 (Rectangle, Row, Column, Phi, Length1, Length2) gen_measure_rectangle2 (Row, Column, Phi, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle) disp_continue_message (WindowHandle, 'black', 'true') stop () dev_update_pc ('off') dev_update_var ('off') n := 100 count_seconds (Seconds1) for i := 1 to n by 1 measure_pairs (Image, MeasureHandle, 1.5, 30, 'negative', 'all', RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, PinWidth, PinDistance) endfor count_seconds (Seconds2) Time := Seconds2 - Seconds1 disp_continue_message (WindowHandle, 'black', 'true') stop () dev_set_color ('red') disp_line (WindowHandle, RowEdgeFirst, ColumnEdgeFirst, RowEdgeSecond, ColumnEdgeSecond) avgPinWidth := sum(PinWidth) / |PinWidth| avgPinDistance := sum(PinDistance) / |PinDistance| numPins := |PinWidth| dev_set_color ('yellow') disp_message (WindowHandle, 'Number of pins: ' + numPins, 'image', 200, 100, 'yellow', 'false') disp_message (WindowHandle, 'Average Pin Width: ' + avgPinWidth, 'image', 260, 100, 'yellow', 'false') disp_message (WindowHandle, 'Average Pin Distance: ' + avgPinDistance, 'image', 320, 100, 'yellow', 'false') * dump_window (WindowHandle, 'tiff_rgb', 'C:\\Temp\\pins_result') disp_continue_message (WindowHandle, 'black', 'true') stop () * draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2) Row1 := 0 Column1 := 600 Row2 := 100 Column2 := 700 dev_set_color ('blue') disp_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2) stop () dev_set_part (Row1, Column1, Row2, Column2) dev_display (Image) dev_set_color ('green') dev_display (Rectangle) dev_set_color ('red') disp_line (WindowHandle, RowEdgeFirst, ColumnEdgeFirst, RowEdgeSecond, ColumnEdgeSecond) disp_continue_message (WindowHandle, 'black', 'true') stop () dev_set_part (0, 0, Height - 1, Width - 1) dev_display (Image) disp_continue_message (WindowHandle, 'black', 'true') stop () dev_set_color ('green') * draw_rectangle2 (WindowHandle, Row, Column, Phi, Length1, Length2) Row := 508 Column := 200 Phi := -1.5708 Length1 := 482 Length2 := 35 gen_rectangle2 (Rectangle, Row, Column, Phi, Length1, Length2) gen_measure_rectangle2 (Row, Column, Phi, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle) stop () measure_pos (Image, MeasureHandle, 1.5, 30, 'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance) PinHeight1 := RowEdge[1] - RowEdge[0] PinHeight2 := RowEdge[3] - RowEdge[2] dev_set_color ('red') disp_line (WindowHandle, RowEdge, ColumnEdge - Length2, RowEdge, ColumnEdge + Length2) disp_message (WindowHandle, 'Pin Height: ' + PinHeight1, 'image', RowEdge[1] + 40, ColumnEdge[1] + 100, 'yellow', 'false') disp_message (WindowHandle, 'Pin Height: ' + PinHeight2, 'image', RowEdge[3] - 120, ColumnEdge[3] + 100, 'yellow', 'false') * dump_window (WindowHandle, 'tiff_rgb', 'C:\\Temp\\pins_height_result') dev_set_draw ('fill') dev_set_line_width