检测PCB板上的走线宽度
對應示例程序:
measure_circuit_width_lines_gauss.hdev
目標:測量pcb板上的走線軌跡的寬度
思路為:
??????1.讀取圖像
??????2.根據(jù)圖像特性,將R,G,B的三通道圖像分成R,G,B的三幅單通道圖像,單獨處理G圖像
??????3.利用形態(tài)學的處理方法,膨脹,開操作等,取出待檢測直線區(qū)域
??????4.利用line_gauss算子,提取出ROI區(qū)域中的直線,并獲取直線上的每個點的寬度
??????5.將寬度的值與容許的閾值進行比較,并顯示
例程相對簡單,但是利用形態(tài)學的方法定位到ROI區(qū)域,以及尋找Tuple中的小于Min和Max的方法,值得學習。
tuple_find (min2(LineWidth,MaxTrackWidth), MaxTrackWidth, IndicesTooBroad)
圖像:
代碼:
//前期準備 開窗口 設(shè)置字體 讀取圖像 dev_update_off () dev_close_window () read_image (Image, 'pcb_color') get_image_size (Image, Width, Height) dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle) set_display_font (WindowHandle, 16, 'mono', 'true', 'false') dev_display (Image) dev_set_draw ('margin') dev_set_color ('yellow') * *設(shè)置寬度的最大、最小閾值 可以調(diào)整 * Define the minimum and maximum width of the pcb tracks MaxTrackWidth := 6.0 MinTrackWidth := 4.0 * //根據(jù)先驗知識,畫個矩形子區(qū)域進行后續(xù)的測量 * Select a sub-region of the image Rectangle := [271,285,528,718] gen_rectangle1 (PcbPart, Rectangle[0], Rectangle[1], Rectangle[2], Rectangle[3]) dev_display (Image) dev_display (PcbPart) disp_message (WindowHandle, 'Measure the width of tracks using lines_gauss', 'window', 12, 12, 'black', 'true') disp_continue_message (WindowHandle, 'black', 'true') stop () //調(diào)整下窗口 把子區(qū)域進行顯示 調(diào)整后的的窗口略大于之前畫的矩形 dev_set_part (Rectangle[0] - 15, Rectangle[1] - 15, Rectangle[2] + 15, Rectangle[3] + 15) dev_display (Image) dev_display (PcbPart) disp_message (WindowHandle, 'Exemplarily shown here for a part of the circuit board', 'window', 12, 12, 'black', 'true') disp_continue_message (WindowHandle, 'black', 'true') stop () * //進行檢測 主要是Blob分析 形態(tài)學處理 把PCB上的軌跡線部分摳出來 這個需要學習 * Extract the tracks //根據(jù)圖像可以發(fā)現(xiàn),圖像的綠色較多,因此把3通道的圖像分成R,G,B三個通道圖 再單獨對G圖像進行處理 decompose3 (Image, ImageR, ImageG, ImageB) //把一個RGB三通道圖像 分成R\G\B三個單通道圖像 reduce_domain (ImageG, PcbPart, ImageReduced) //根據(jù)矩形 從原圖中摳ROI圖像 threshold (ImageReduced, Region, 90, 255) //閾值分割 dilation_circle (Region, RegionDilation, 3.5) //圓形膨脹 opening_rectangle1 (Region, RegionOpening, 8, 8) //矩形開操作 dilation_circle (RegionOpening, RegionDilation1, 3.5) //圓膨脹 difference (Region, RegionDilation1, RegionDifference) //求兩個圖像的差異 得到只剩下線的RegionDifference difference (RegionDilation, RegionDilation1, RegionDifference) //求兩個圖像的差異部分connection (RegionDifference, ConnectedRegions) //連通域分割 select_shape (ConnectedRegions, RegionSelected, 'area', 'and', 260, 4595) //根據(jù)面積進行區(qū)域篩選 union1 (RegionSelected, RegionTracks) //合并符合條件的區(qū)域 reduce_domain (ImageReduced, RegionTracks, ImageReducedTracks) //摳圖 把PCB上的線摳出來 * * Measure the position and the width of the tracks lines_gauss (ImageReducedTracks, Lines, 1.5, 1, 8, 'light', 'true', 'bar-shaped', 'true') //檢測圖像中的線條及其寬度 select_shape_xld (Lines, SelectedXLD, 'contlength', 'and', 20, 99999) //根據(jù) 線長 篩選直線 dev_display (Image) dev_set_color ('yellow') dev_display (PcbPart) dev_set_color ('green') dev_set_line_width (2) dev_display (Lines) disp_message (WindowHandle, 'Extracted tracks', 'window', 12, 12, 'black', 'true') disp_continue_message (WindowHandle, 'black', 'true') stop () * * Compute the width of the tracks //計算提取出的直線的寬度 count_obj (SelectedXLD, NumberL) RowLine := [] ColLine := [] LineWidth := [] for IndexL := 1 to NumberL by 1select_obj (SelectedXLD, Line, IndexL)get_contour_xld (Line, Row, Column) //獲取每條直線上的點坐標get_contour_attrib_xld (Line, 'width_left', WidthL) //得到線上每個點的屬性 (直線區(qū)域上的上邊緣到中心點的距離)get_contour_attrib_xld (Line, 'width_right', WidthR) //直線區(qū)域上的下邊緣到中線點的距離(待驗證)RowLine := [RowLine,Row] //兩個Tuple進行合并 相當于把每個坐標都放在這個Tupe里面ColLine := [ColLine,Column]LineWidth := [LineWidth,WidthR + WidthL] //直線的寬度就是兩個距離的合 endfor * * Detect the tracks with a wrong width //找小于最小閾值 或者大于最大閾值的點 //先把LineWidth中的數(shù)與最大閾值進行比較,如果比最大值大,那么這個值就被替換成了MaxTrackWidth,這時再從LineWidth中找等于MaxTrackWidth的點,那個點就是超過范圍的點,記錄它的ID,放到IndicesTooBroad中沒找到符合條件的點就返回-1 tuple_find (min2(LineWidth,MaxTrackWidth), MaxTrackWidth, IndicesTooBroad) tuple_find (max2(LineWidth,MinTrackWidth), MinTrackWidth, IndicesTooNarrow) if (IndicesTooBroad == -1)IndicesTooBroad := [] //沒找到大于閾值的點 那么太寬的這個Tuple就設(shè)置為空 endif if (IndicesTooNarrow == -1)IndicesTooNarrow := [] endif //將單個像素存儲為圖像區(qū)域 //subset 選取數(shù)組t中的第i個元素 //根據(jù)上一步找出的太寬或者太窄點的ID,進行點 轉(zhuǎn)變成 區(qū)域 gen_region_points (RegionTooBroad, subset(RowLine,IndicesTooBroad), subset(ColLine,IndicesTooBroad)) gen_region_points (RegionTooNarrow, subset(RowLine,IndicesTooNarrow), subset(ColLine,IndicesTooNarrow)) * //顯示測量結(jié)果 * 處理太寬的區(qū)域 connection (RegionTooBroad, RegionTooBroad) //將符合要求的區(qū)域進行連通域分割 gen_contours_skeleton_xld (RegionTooBroad, TracksTooBroad, 1, 'filter') //區(qū)域轉(zhuǎn)化成XLD輪廓 smallest_circle (RegionTooBroad, RowTooBroad, ColumnTooBroad, RadiusTooBroad) //計算它的最小外接圓,用來定位展示 //創(chuàng)建與圓或圓弧相對應的XLD輪廓 其實就是把最小的外接圓 進行放大顯示 便于觀察 gen_circle_contour_xld (CircleTooBroad, RowTooBroad, ColumnTooBroad, min2(RadiusTooBroad + 10,20), 0, 6.28318, 'positive', 1) *處理太窄的區(qū)域 connection (RegionTooNarrow, RegionTooNarrow) //連通域分割 gen_contours_skeleton_xld (RegionTooNarrow, TracksTooNarrow, 1, 'filter') //轉(zhuǎn)化成XLD輪廓 smallest_circle (RegionTooNarrow, RowTooNarrow, ColumnTooNarrow, RadiusTooNarrow) //最小外接圓 gen_circle_contour_xld (CircleTooNarrow, RowTooNarrow, ColumnTooNarrow, min2(RadiusTooNarrow + 10,20), 0, 6.28318, 'positive', 1) dev_clear_window () dev_display (Image) dev_display (ImageReduced) dev_set_line_width (1) dev_set_color ('green') dev_display (Lines) dev_set_line_width (2) dev_set_color ('red') dev_display (TracksTooBroad) //顯示太寬的線 dev_display (CircleTooBroad) //用最小外接圓進行標記定位 dev_set_color ('magenta') dev_display (CircleTooNarrow) //顯示太窄的線 dev_display (TracksTooNarrow) //用最小外接圓進行標記定位 disp_message (WindowHandle, ['Extracted tracks',' - Too broad',' - Too narrow'], 'window', 12, 12, ['black','red','magenta'], 'true')用到的幾個算子:
??????decompose3 --把一個RGB三通道圖像 分成R\G\B三個單通道圖像
??????lines_gauss–檢測圖像中的線條
??????gen_region_points – 將單個像素存儲為圖像區(qū)域
??????subset --選取數(shù)組t中的第i個元素
??????tuple_find–返回一個元組在另一個元組中所有出現(xiàn)的索引 (就是在一個Tuple中找等于另一個Tuple的值,返回它的ID)
參考資料:
[1].https://blog.csdn.net/douglax/article/details/38669941
[2].https://www.cnblogs.com/hu16683845/p/9181344.html
總結(jié)
以上是生活随笔為你收集整理的检测PCB板上的走线宽度的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ansys19.0--联轴器建模
- 下一篇: LPG绘画软件测试自学,广东海洋大学学生