Halcon实例分析——autobahn.hdev快速检测道路标志
這是運行代碼的結果,下面我們每條代碼過一遍,下面的代碼路徑為打開halcon,瀏覽實例程序,方法中的Blob分析,
?
?
有些重點代碼會詳細講解,
* autobahn.hdev: Fast detection of lane markers * dev_update_window ('off') dev_close_window () dev_open_window (0, 0, 768, 575, 'black', WindowID) MinSize := 30 get_system ('init_new_image', Information) set_system ('init_new_image', 'false') gen_grid_region (Grid, MinSize, MinSize, 'lines', 512, 512) clip_region (Grid, StreetGrid, 130, 10, 450, 502) dev_set_line_width (3) dev_set_color ('green') read_image (ActualImage, 'autobahn/scene_00') dev_display (ActualImage) stop () dev_display (StreetGrid) stop () for i := 0 to 28 by 1read_image (ActualImage, 'autobahn/scene_' + (i$'02'))reduce_domain (ActualImage, StreetGrid, Mask)sobel_amp (Mask, Gradient, 'sum_abs', 3)threshold (Gradient, Points, 20, 255)dilation_rectangle1 (Points, RegionDilation, MinSize, MinSize)reduce_domain (ActualImage, RegionDilation, StripGray)threshold (StripGray, Strip, 190, 255)fill_up (Strip, RegionFillUp)dev_display (ActualImage)dev_display (RegionFillUp) endfor dev_set_line_width (1) dev_update_window ('on') set_system ('init_new_image', Information)簡介,這里還是使用了常規的blob分析法,只不過使用了一個?更高效的網格方法
?* autobahn.hdev: Fast detection of lane markers
autobahn.hdev:道路標志快速檢測
dev_update_window ('off')
?dev_update_window — 指定是否每一步都去刷新顯示圖形到窗口上,單步去執行算子的時候,無論關閉還是打開都沒有什么影響;要是連續執行的時候我們需要看連續執行的時間,最好關閉。關閉后,我們若要顯示需要顯示的圖形后者ROI時,需要使用dev_display算子去顯示
當然在導出到C#后,是不需要使用這個算子的,僅僅在HALCON中使用,在C#中我們必須使用顯示函數去顯示圖形。
在這個例子中設為off,關閉自動刷新顯示圖形
dev_close_window ()
dev_open_window (0, 0, 768, 575, 'black', WindowID)
先關閉窗口再從新以新的尺寸打開窗口;
在導出到C#中的時候,因為我們的窗口都是固定,都是使用算子得到圖片的大小,然后讓圖片去適應窗口,一般我寫代碼就沒有使用這兩個算子;當然也可以使用,就是在程序第一次打開的時候,使用固定大小打開窗口;
在HALCON中沒有去使用圖片適應窗口,而是讓窗口去適應圖片所以很多例子中都是先把窗口關閉再打開。
MinSize := 30
?創建變量并賦值
get_system ('init_new_image', Information)
set_system ('init_new_image', 'false')
?先獲取屬性值,再設置屬性值
get_system獲取當前系統參數的當前值
set_system設置當前系統參數的值
系統默認的參數很多,這些參數只是適用于HDevolop這個編程環境,如果導入到C#中使用,很多halcon的設置屬性和獲取屬性是沒法使用的,這里我們需要注意。
這里設置的是init_new_Image鍵盤按F6單步運行get_system我們發現返回的值是true,按鍵盤F1可以查詢到這個算子的部分屬性
?有只讀的有讀寫的,感興趣的可以看一看。
我們查詢下set_system
?
?
?找到init_new_image
大致翻譯是這樣說的,確定在使用過濾器之前是否應將新圖像設置為0,從而確保在具有相同配置的系統上重復執行程序時,過濾返回的值是一致的。請注意,如果始終對整個圖像進行過濾,或者如果未過濾圖像區域的數據不重要,則不需要這樣做。
這里提供這樣一個思路,如果你對于一個算子有疑問,那就注釋掉這段代碼,運行程序,看有什么區別,再去理解概念,就會體會深刻。
gen_grid_region (Grid, MinSize, MinSize, 'lines', 512, 512)
生成 網格,網格的類型我們按F1可以查詢到,有線類型和點類型,當然點類型也就是橫豎線的交點。這里是線類型,網格之間的橫豎距離就是MinSize的大小,下面是RowSteps的取值范圍
?ColumnSteps同理
?512是網格的最大橫縱坐標,取值范圍如下,這個例子中也就是從ROW=0到ROW=512,COLUMN=0到COLUMN=512
?clip_region (Grid, StreetGrid, 130, 10, 450, 502)
?剪切區域算子,根據官方文檔描述,使用這個算子的原因是這個算子的效率比使用交集的效率要高
?在這個例子中,因為生成網格時是從(0,0)開始生成到(512,512)結束,我們并不需要這么到,需要剪切掉不需要的部分,所以這里使用剪切算子
運行算子到這里,就可以生成一個如下圖的網格
?后面的代碼就是不斷在這個網格的基礎上執行blob分析運算,使用了一個for循環,循環讀取29張圖片
for i := 0 to 28 by 1
? ? read_image (ActualImage, 'autobahn/scene_' + (i$'02'))
? ? reduce_domain (ActualImage, StreetGrid, Mask)
? ? sobel_amp (Mask, Gradient, 'sum_abs', 3)
? ? threshold (Gradient, Points, 20, 255)
? ? dilation_rectangle1 (Points, RegionDilation, MinSize, MinSize)
? ? reduce_domain (ActualImage, RegionDilation, StripGray)
? ? threshold (StripGray, Strip, 190, 255)
? ? fill_up (Strip, RegionFillUp)
? ? dev_display (ActualImage)
? ? dev_display (RegionFillUp)
endfor
? read_image (ActualImage, 'autobahn/scene_' + (i$'02'))
? ? reduce_domain (ActualImage, StreetGrid, Mask)
按順序讀取本地圖片,我們導出到C#中的時候,如果手上沒有相機,也可以使用這種方式,循環讀取本地一系列的圖片來驗證我們的算法。
第二行是剪切函數, 很多檢測都會用到剪切函數,因為我們在檢測的時候,不是所以的區域都是我們感興趣和需要去處理的,處理的區域也是越小越好,這樣才能保證處理的速度很快。
我們單獨顯示剪切后的區域如下
?可以看到剪切的結果就是圖像和線條的重合部分,鏤空部分并沒有剪切過來,通過這樣單步的去執行算子,然后看結果,我們就能更好的理解算子的作用。
sobel_amp (Mask, Gradient, 'sum_abs', 3)
?這里使用邊緣檢測算子找到重合的邊緣部分,所謂邊緣也就是圖片上明暗有變化的地方就會有邊緣,這里使用的FilterType官方提供了一些值如下
?這些值大家可以找到一張圖片,分別使用這些值去測試,就大致會知道在什么樣的情況下使用什么方法
?找到邊緣之后,再使用閾值算子提取這些點,這里我當時有個疑問為什么不直接使用閾值呢,直接提取亮的點不也可以嗎?后來我想了想,這些亮的區域的灰度值是不確定的,我們沒辦法使用一個固定的范圍去提取,即使大部分情況下能提取到,總歸會有提取不到的時候,使用邊緣,是一個相對提取法,邊緣相對于其他地方是亮的,所以更穩定。
可以簡單這樣理解
閾值是一個絕對提取,
邊緣是一個相對提取
提取結果如下
?dilation_rectangle1 (Points, RegionDilation, MinSize, MinSize)
?使用膨脹算子使得提取的點變大
?? reduce_domain (ActualImage, RegionDilation, StripGray)
?再次剪切出關注的區域
??threshold (StripGray, Strip, 190, 255)
再次使用閾值算子提取道路標志
?fill_up (Strip, RegionFillUp)
? ? dev_display (ActualImage)
? ? dev_display (RegionFillUp)
?填充空洞,在閾值的時候,可能部分地方的灰度值不在我們設定的范圍,我們認為填充上
?看到這里,我的總結是,這里只是提供一個思路,就是使用網格去提取檢測區域的形式,我們沒必要照搬不誤的去使用,這里其實我們提前生成三個矩形區域也是沒有問題,把三個舉行區域合并成一個區域,然后去循環剪切關注區域,再使用閾值計算也是可以的。
我們在看例程的時候,一定要注意,所有例程最核心的都是提供思路,同一中缺陷檢測有很多中檢測思路,我們要根據實際情況靈活使用
?
總結
以上是生活随笔為你收集整理的Halcon实例分析——autobahn.hdev快速检测道路标志的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 互联网情报屋
- 下一篇: Ae501 100+图形拼接马赛克过渡效