2012年10月19日 星期五

EmguCV Image Process: Transforming Images with Morphological Operations part 1


EmguCV Image Process: Transforming Images with Morphological Operations

參考OpenCV 2 Computer Vision Application Programming Cookbook第五章

介紹內容如下:

Eroding and dilating images using morphological filters

Opening and closing images using morphological filters

Detecting edges and corners using morphological filters

Segmenting images using watersheds

Extracting foreground objects with the GrabCut algorithm

Morphological filtering(形態學)這個理論發展於1960年代

用來做影像分析、影像處理等等

其定義了一系列的運算子(operators)透過預先定義好的形狀元素來對影像作探討

而形狀元素對於鄰點的相交處理會影響結果的呈現

這個章節將會介紹幾種非常重要而且常見的形態學運算子

Eroding and dilating images using morphological filters

Erosion(侵蝕)和Dilation(擴張)是形態學中非常根本的運算子

而形態學的運算子通常都是處理二值化的影像

首先載入一張圖(以首頁這張圖為例)並弄成二值化的影像:

//Read input image
Image<Gray, Byte> image = new Image<Gray, byte>("image.jpg");
//Transform the binary image
image._ThresholdBinary(image.GetAverage(), new Gray(255));
載入image影像

然後這裡使用了一個函數GetAverage來取得影像的平均灰階值

以此值來做二值化的處理

二值化的結果如下:
這是二值化的結果

可以發現在底部黑色的部分有一些白色的雜點

人物上也是黑白相間

這時候如果對影像作侵蝕和擴張會變如何呢?

//Erode the image
Image<Gray, Byte> erode = image.Erode(1);
erode.Save("erode.bmp");
//Dilate the image
Image<Gray, Byte> dilate = image.Dilate(1);
dilate.Save("dilate.bmp");
透過Erode和Dilate對影像作處理

這兩個方法要帶入一個整數,分別表示處理的次數

這裡設定為1來做測試

最後再分別把影像存出來看結果:

Erode(侵蝕)後的結果

Dilate(擴張)後的結果

可以簡單地發現侵蝕後的影像

底部白色的雜點不見了

人物也幾乎呈現黑色的狀態

而擴張的部分

底部白色的雜點變大了

而人物的部分反而有更多白色的區域


這樣透過字面上的意思應該容易了解了

侵蝕就是對影像中白色(值為255)的區塊做侵蝕

所以侵蝕處理完,白色的區塊會變少或變小!

而擴張就正好相反,是對影像中白色(值為255)的區塊做擴張

所以擴張處理完,白色的區塊會變多會變大!


在處理影像時,通常會把影像切成前景和背景

然後習慣把背景設定為黑色,前景設定為白色

在這樣的處理中,有時候背景的黑色會帶有一些白色的雜點

就像是此範例第一張二值化影像的底部這樣

可以透過侵蝕把底部的雜訊去除

而對於前景的部分

有時候會因為與背影的關係而切割的不夠完整,會帶有黑色的雜訊

此時就能夠使用擴張把前景的部分補足,更完整的呈現出來!


而在EmguCV中只提供3X3的形狀元素來做侵蝕和擴張

所能控制的只有執行的次數(帶入的整數值)

//Erode the image
erode = image.Erode(3);
嘗試用三次侵蝕來處理

結果如下:

三次侵蝕的結果,邊緣就會變得沒這麼細緻

而若是要改變形狀元素的控制

就必須使用OpenCV的方法

透過CvInvoke就可以呼叫OpenCV的方法來用

StructuringElementEx EX7x7 = new StructuringElementEx(7, 7, 4, 4, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_RECT);
CvInvoke.cvErode(image, erode, EX7x7, 1);
採用7X7的形狀元素來做侵蝕處理

這裡要先定義形狀元素,型別為:StructuringElementEx

前兩個整數7, 7就是這個形狀元素的大小為7X7

再來兩個整數4, 4指的是這個形狀元素的中心位置

如果設定並非原始的中心位置,則處理後的結果就會有上下偏移

而最後就是帶入形狀元素的形狀,設定為矩形!

結果如下:
利用7X7的形狀元素處理起來和處理三次的結果很接近!

這裡當然也可以切換形狀元素的形狀

Emgu.CV.CvEnum.CV_ELEMENT_SHAPE此列舉中提供了

CV_SHAPE_CROSS

CV_SHAPE_CUSTOM

CV_SHAPE_ELLIPSE

CV_SHAPE_RECT

而測試的結果CV_SHAPE_CUSTOM是無法使用的!

其餘兩種都可以帶入試試看!!

 7X7 CROSS的形狀元素處理結果,可以看到邊緣會有十字交錯的形狀!!

7X7 ELLIPSE的形狀元素處理結果,和上兩張比較來會發現邊緣變得比較圓滑!


是不是很有趣呀!!

趕快來自行體會一下形態學的奧妙吧!!

下一篇將介紹另外兩個常見的運算子:斷開跟閉鎖

沒有留言:

張貼留言