2013年4月10日 星期三

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

20060907001.jpg
EmguCV Image Process: Extracting Lines, Contours, and Components

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

介紹內容如下:

Detecting image contours with the Canny operator

Detecting circles in images with the Hough transform

Fitting a line to a set of points

Extracting the components' contours

Computing components' shape descriptors

在上一篇提到如何擷取物件的輪廓

對於這些輪廓

可以利用一些方法來描述這些形狀

這裡介紹幾種常用的形狀描述方法

利用與前一篇相同的圖

只是為了方便做測試

把目標鎖定在中間這個人物輪廓上

Image<Gray, Byte> image = new Image<Gray, Byte>("binary.bmp");

Contour<Point> contours = image.FindContours(
    //all pixels of each contours
    Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
    //retrieve the external contours
    Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL);

Contour<Point> contour = null;
for (; contours != null; contours = contours.HNext)
{
    if (contours.Total==532)
    {
        contour = contours;
    }
}

Image<Gray, Byte> blackImage = image.CopyBlank();
//Draw white contours on a black image
blackImage.Draw(contour, new Gray(255), 1);

利用輪廓的點的總數

把目標輪廓選出來

其結果如下:

目標輪廓

之後就是針對這個輪廓來做處理

(接下來介紹的程式碼都是直接接續上面那段程式碼)

最常用的描述方法有幾個

在EmguCV上有直接實作的包含下列三種:

輪廓的邊界矩形

輪廓的近似多邊形

輪廓的近似凸多邊形

下面就直接實作看結果

邊界矩形:

//Draw the bounding box
blackImage.Draw(contour.BoundingRectangle, new Gray(150), 2);

這裡故意把顏色改成灰階150,寬度設為2

方便視覺觀看

結果如下:

邊界矩形


近似多邊形(approximate polygon)

//Draw the approximate polygon
blackImage.Draw(contour.ApproxPoly(5), new Gray(150), 2);

近似多邊形的準確率設為5

結果如下:

近似多邊形


近似凸多邊形(convex hull)

//Draw the convex hull
blackImage.Draw(
    contour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE), 
    new Gray(150), 2);

凸多邊形可以選擇偵測的方向是順時針還是逆時針

結果如下:

近似凸多邊形


而在OpenCV中還有實做另外一種

包含輪廓的最小圓形(enclosing circle)

由於EmguCV未直接實作

因此必須使用CvInvoke的方法

PointF center;
float radius;
//Testing the enclosing circle
CvInvoke.cvMinEnclosingCircle(contour, out center,out radius);
//Draw the enclosing circle
blackImage.Draw(new CircleF(center, radius), new Gray(150), 2);

將輪廓傳入,並帶入圓的中心位置、直徑長度

便可取得該圓形

結果如下:

包含輪廓最小圓形


利用這些方法

可以方便找出目標輪廓的一些特性

透過輪廓的上、下、左、右的極點來找出bounding box

輪廓的位置、大小來逼近enclosing circle

利用準確度的參數來逼近一個簡易的近似多邊形(approximate polygon)

和最小的凸多邊形(convex hull)


這些可以幫助你更加了解、更方便運用所擷取的輪廓

不妨自己來試試看吧!!

沒有留言:

張貼留言