halcon視覺入門鋼珠識別
halcon視覺入門鋼珠識別
經過入門篇,我們有了基礎的視覺識別知識。現在加以應用。
有如下圖片:
我們需要識別圖片中比較明亮的中間區域,有黑色的鋼珠,我們需要知道他的位置和面積。
-
分析如何識別
-
編寫程式碼實現識別
實現程式碼如下:
* Image Acquisition 01: Code generated by Image Acquisition 01
read_image (Image, 'D:/temp/cir.png')
dev_close_window ()
get_image_size (Image, Width, Height)
dev_open_window_fit_size (0, 0, Width, Width, -1, -1, WindowHandle)
*二值化
binary_threshold (Image, Region, 'max_separability', 'dark', UsedThreshold)
*反向裁剪
complement (Region, RegionComplement)
*截斷選區
connection (RegionComplement, ConnectedRegions)
*過濾底部干涉
select_shape (ConnectedRegions, SelectedRegions1, 'rectangularity', 'and', 0, 0.9)
*合併選區
union1 (SelectedRegions1, RegionUnion)
*轉換為規則的形狀(外接圓)
shape_trans (RegionUnion, RegionTrans, 'outer_circle')
*裁剪出感興趣區域
reduce_domain (Image, RegionTrans, ImageReduced)
*對裁剪出來的區域二值化
binary_threshold (ImageReduced, Region1, 'max_separability', 'dark', UsedThreshold1)
*開操作
opening_circle (Region1, RegionOpening1, 50)
*開操作
opening_circle (Region1, RegionOpening2, 80)
*對比不同
difference (RegionOpening1, RegionOpening2, RegionDifference)
*分割區域
connection (RegionDifference, ConnectedRegions1)
shape_trans (ConnectedRegions1, RegionTrans1, 'outer_circle')
*重新排序
sort_region (RegionTrans1, SortedRegions, 'first_point', 'true', 'row')
*計算除面積和圓心
area_center (SortedRegions, Area, Row, Column)
dev_set_draw ('margin')
dev_set_color ('green')
dev_display (Image)
dev_display (SortedRegions)
for Index := 0 to |Area| -1 by 1
dev_set_draw ('margin')
dev_set_color ('red')
dev_set_line_width (5)
set_tposition (WindowHandle, Row[Index], Column[Index])
write_string (WindowHandle, 'Area:' + Area[Index] +',origin:'+Row[Index] + ',' + Column[Index])
endfor
count_obj (SortedRegions,Number)
set_tposition (WindowHandle, 10,10)
write_string (WindowHandle, 'Total Number:' +Number)
以下是分析
分析
我們需要識別的內容在如圖標註的內容上:
首先,按照上次講的內容:
- 打開圖片(OpenImage)
- 將圖片分解成3通道圖片,或是轉成灰度圖(GrayImage)。
- 二值化或動態二值化(Region)。
- 聯通區域。
- 特徵篩選。
- 如果區域有干擾,一般會進行一下操作:
- 腐蝕
- 膨脹
- 形狀轉換
- 以上步驟重複,或組合重複。
- 根據需要,還可以合併區域,並重複4-6,從而達到目的。
- 輸出區域並標註。
運算元使用規則
我們通過三個例子來理解它:
Image 是輸出參數,也就是我們的結果
‘D:/temp/cir.png’ 字元串常量 是出入參數,在Halcon中叫 控制參數
read_image (Image, 'D:/temp/cir.png')
Image是輸入參數
Region 是輸出參數
‘max_separability’ 是控制參數
‘dark’ 是控制參數
UsedThreshold 輸出控制參數
binary_threshold (Image, Region, 'max_separability', 'dark', UsedThreshold)
Image是輸入參數
Regions是輸出參數
0 是輸入控制
71 是輸入控制
threshold (Image, Regions, 0, 71)
以下是實現思路跟結果講解
* 讀取圖片
read_image (Image, 'D:/temp/cir.png')
得到結果
在進行動態二值化,或手動二值化也可以。
*動態二值化
binary_threshold (Image, Region, 'max_separability', 'dark', UsedThreshold)
* 手動二值化
threshold (Image, Regions, 0, 71)
得到結果
*反向裁剪
complement (Region, RegionComplement)
得到結果
*聯通區域
connection (RegionComplement, ConnectedRegions)
該步驟講以上區域分割成一個一個零散區域。
*過濾底部干涉
select_shape (ConnectedRegions, SelectedRegions1, 'rectangularity', 'and', 0, 0.9)
我們可以在上一步的結果中看到,下面有一條線,這條線在外形上跟矩形很類似,我們通過矩形選取去過濾掉它。
得到結果
*合併選區
union1 (SelectedRegions1, RegionUnion)
合併區域跟聯通區域是一個相反的操作,合併區域的目的是將零散區域合併成一個整體,這樣,我們就可以給它做外接圓,旋轉整個需要識別的區域。
*轉換為規則的形狀(外接圓)
shape_trans (RegionUnion, RegionTrans, 'outer_circle')
得到結果
*裁剪出感興趣區域
reduce_domain (Image, RegionTrans, ImageReduced)
以上的所有步驟,都是為了得到感興趣區域。
為什麼要得到感興趣區域呢,因為我們需要識別的內容,就在這個區域內,其他外部區域都是干擾,我們不需要關心。所以,在得到外接圓之後,我們用這個外接圓對原圖進行裁剪,就得到了我們感興趣的區域,到了現在,我們才真正準備開始對鋼珠進行識別。
按照套路,我們要進行二值化,所以下面的程式碼就是動態二值化。當然也可以通過特徵進行手動二值化。
*對裁剪出來的區域二值化
binary_threshold (ImageReduced, Region1, 'max_separability', 'dark', UsedThreshold1)
得到結果
接下來進行 腐蝕和膨脹 —–> 開操作(腐蝕和膨脹等同開操作):
Region1 輸入區域
RegionOpening1 輸出區域
50 開操作控制參數,這個參數是需要嘗試得到的,由小到大,最終符合要求。
*開操作
opening_circle (Region1, RegionOpening1, 50)
得到結果
然後再次進行開操作,得到一個沒有選取的結果。然後對比兩個結果,取差值。
解釋:假設第一次開操作得到了6個球,第二次一個都沒有,那麼兩個取差值,就一定有6個球。
*開操作
opening_circle (Region1, RegionOpening2, 80)
*對比不同,兩次開操作,的結果進行對比。得到不同區域。
difference (RegionOpening1, RegionOpening2, RegionDifference)
實則這裡不進行對比也是可以的。
得到結果
接下來分割區域,做形狀轉換。就是我們要的結果了。因為,我們上述操作,操作的是一個整體,但我們需要將這些結果進行分割,所以需要進行聯通區域,得到區域後,因為區域形狀不規則,所以我們需要將形狀轉化為規則的圓。所以需要進行性轉轉換。
*分割區域
connection (RegionDifference, ConnectedRegions1)
*對分割的區域,做最小外接圓。
shape_trans (ConnectedRegions1, RegionTrans1, 'outer_circle')
以上就是我們需要的結果了
得到結果
接下來就是排序,並計算圓心,畫出坐標和面積了,程式碼比較簡單就不截圖了,直接給結果:
*重新排序
sort_region (RegionTrans1, SortedRegions, 'first_point', 'true', 'row')
*計算面積和圓心
area_center (SortedRegions, Area, Row, Column)
dev_set_draw ('margin')
dev_set_color ('green')
dev_display (Image)
dev_display (SortedRegions)
for Index := 0 to |Area| -1 by 1
dev_set_draw ('margin')
dev_set_color ('red')
dev_set_line_width (5)
set_tposition (WindowHandle, Row[Index], Column[Index])
write_string (WindowHandle, 'Area:' + Area[Index] +',origin:'+Row[Index] + ',' + Column[Index])
endfor
count_obj (SortedRegions,Number)
set_tposition (WindowHandle, 10,10)
write_string (WindowHandle, 'Total Number:' +Number)
得到結果
總結
初學者怎麼知道這些運算元有什麼作用呢,這些參數該如何使用呢,需要使用哪些特徵呢?
在開發環境中 HDevelop中 按F1 可以看到幫助,多使用幫助,也可以在網上看影片,多看自帶的例子。動手寫,才能有進步。
選中運算元按F1可以看到幫助
在HDevelop中按 Ctrl + E 可以打開示常式序