EmguCV Image Process: Extracting Lines, Contours, and Components
參考OpenCV 2 Computer Vision Application Programming Cookbook第七章
介紹內容如下:
Detecting image contours with the Canny operator
Detecting lines in images with the Hough transform
Fitting a line to a set of points
Extracting the components' contours
Computing components' shape descriptors
為了實作基於影像內容的分析
必須從由許多點所構成的影像中擷取出有意義的特徵
這些特徵包含:輪廓、線、斑點...等等
這些影像的基本元素定義了影像的內容
本章節就來介紹如何擷取出影像中重要的特徵
在前一個章節
提到了如何做邊緣偵測
並在影像的梯度中採用一個閥值作為二值化的依據
此二值化影像就包含了主要的邊緣線段
而這在物件的識別中是很有用的
但這樣的方式有兩大缺點:
常常被偵測出來的邊緣非常的粗
(因為為了要把該有的邊緣都偵測出來,閥值會設定的較低)
這意味著被偵測的物件會有所限制
另一個重要的問題就是
很難找到一個閥值,使其盡可能包含所有重要的邊緣
並盡可能的不包含那些微不足道的邊緣
而Canny algorithm就是嘗試來解決這樣的問題!!
Canny algorithm在EmguCV中的實作非常簡單
在Image的類別中就提供了方法:
Image<Gray, Byte> image = new Image<Gray, Byte>("image.jpg"); Image<Gray, Byte> cannyImage = image.Canny(new Gray(125), new Gray(255)); cannyImage._ThresholdBinary(new Gray(128), new Gray(350));
這裡要注意的是
回傳的結果影像cannyImage,依舊要透過二值化來取得黑白的邊緣影像
只是這二值化的方式比較單純
就是以Gray level(0~255)的中間值128
來做為閥值,結果如下:
儘管Canny algorithm採用了其他grdient operator
但其實主要也是基於Sobel operator
而這中間的關鍵就是Canny algorithm採用了兩個閥值!!
以此來決定某個點是不是屬於輪廓
這裡可以嘗試施作Sobel operator
並以剛剛設定較低的閥值和較高的閥值來做測試:
//horizontal filter Image<Gray, float> sobelX = image.Sobel(1, 0, 3); //vertical filter Image<Gray, float> sobelY = image.Sobel(0, 1, 3); //Convert negative values to positive valus sobelX = sobelX.AbsDiff(new Gray(0)); sobelY = sobelY.AbsDiff(new Gray(0)); Image<Gray, float> sobel = sobelX + sobelY; Image<Gray, float> sobelLow = sobel.ThresholdBinary(new Gray(125), new Gray(255)); Image<Gray, float> sobelHigh = sobel.ThresholdBinary(new Gray(255), new Gray(255));
先來看sobelLow結果:
可以發現結果影像得到了較顯著的影像輪廓
若是以較高的閥值來做Sobel operator:
sobelHigh結果如下:
這裡的閥值只試著把重要的邊緣留下
因此大部分的邊緣便無法被偵測出來
因此取得的結果影像包含了許多斷裂的邊緣線段
而Canny algorithm結合了這兩張結果影像
並試著產出最佳的結果影像
其演算法會保留由高閥值產出的所有邊緣
並以此邊緣為基本,在低閥值結果中
找出能夠相連的連續邊緣出來
而其餘非連續邊緣-獨立邊緣,就予以捨去
這樣的方法只要透過適當的閥值便能夠取得品質良好的邊緣輪廓
這樣的策略
就是基於兩個閥值的方式來處理
而這樣的方法稱為:hysteresis thresholding
(中文翻為:遲滯閾值...非常難理解)
這種策略方法對於需要透過閥值設定的方法來說非常有幫助
而唯一要注意的是:這會增加很多的運算量!!
而事實上
Canny algorithm採用了更進階的策略來增進取得結果的品質
這裡只是簡略的介紹其策略
更詳細的內容可以參見wiki上的解說
下一篇延伸討論利用Hough transform來做線段偵測
謝謝您的blog
回覆刪除最近在學習EMGUCV,發現您的blog
收穫很多,很多EMGUCV的資料常實用
之後若是有一些問題,能否跟您請教?
先謝謝了~
你好,
刪除歡迎有問題提出來一起討論,
大家互相交流交流嘍~!!