2013年2月6日 星期三

EmguCV Image Process: Extracting Lines, Contours, and Components part 1

轉戰新時代廣場
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來做線段偵測

2 則留言:

  1. 謝謝您的blog
    最近在學習EMGUCV,發現您的blog
    收穫很多,很多EMGUCV的資料常實用
    之後若是有一些問題,能否跟您請教?
    先謝謝了~

    回覆刪除
    回覆
    1. 你好,

      歡迎有問題提出來一起討論,

      大家互相交流交流嘍~!!

      刪除