OpenCV與EmguCV中的映像輪廓提取

來源:互聯網
上載者:User

標籤:

輪廓是映像中表示邊界的一系列點的集合。雖然邊緣檢測演算法可以根據像素間的差異檢查出輪廓邊界的像素,但是它並沒有把輪廓做為一個整體表示出來。所以下一步工作是把這些邊緣檢測出來的像素組裝成輪廓。
openCV中可以用findContours()函數來從二值映像中提取輪廓。openCV中一般用序列來儲存輪廓資訊。序列中的每一個元素是曲線中一個點的位置。
函數findContours()從二值映像中尋找輪廓。findContours()處理的映像可以是Canny()後得到的有邊緣像素的的映像,也可以是Threshold()後得到的映像,這時的邊緣是正負地區之間的邊界。
在介紹函數原型之前,我們還需要簡單瞭解下輪廓樹的概念。openCV允許得到的輪廓被彙總成一個輪廓樹,從而把包含的關係編碼到輪廓樹中。輪廓中直接包含的輪廓成為了它們的子節點。以此類推。

OpenCV3.0中的函數原型如下:

void findContours(InputOutArray image, OutputArrayOfArrays contours,  OutputArray hierarchy, int mode, int method, Point offset = Point())
  • 第一個參數,InputOutArray類型的image,源映像,應為8位單通道的Mat類型。映像的非零像素被認為是1,0像素被保留為0。此函數會在提取圖線輪廓的同時修改映像的內容。
  • 第二個參數,OutputArrayOfArrays類型的contours。函數調用後的運算結果儲存在這裡,即為檢測到的輪廓,每一個輪廓儲存為一個點向量,即用Point類型的vector表示。
  • 第三個參數,OutputArray類型的hierarchy,可選的輸出向量,包含映像的拓撲資訊。其作為輪廓數量的表示,包含了許多元素。每個輪廓contours[i]對應4個hierarchy元素hierarchy[i][0]~hierarchy[i][3],分別表示後一個輪廓、前一個輪廓、父輪廓、內嵌輪廓的索引編號。如果沒有對應的項,該hierarchy[i]值對應的設為負數。
  • 第四個參數,int類型的mode,輪廓檢索模式。
            RETR_EXTERNAL - 只提取最外層的輪廓 。對於所有輪廓設定hierarchy[i][2] = hierarchy[i][3] = -1。
            RETR_LIST - 提取所有輪廓,並且放置在 list 中 
            RETR_CCOMP - 提取所有輪廓,並且將其組織為兩層的 hierarchy: 頂層為連通域的外圍邊界,次層為洞的內層邊界。 
            RETR_TREE - 提取所有輪廓,並且重構嵌套輪廓的全部 hierarchy 
  • 第五個參數,int類型的method,輪廓逼近的方法。           
            CHAIN_APPROX_NONE - 將所有點由鏈碼形式翻譯(轉化)為點序列形式 
            CHAIN_APPROX_SIMPLE - 壓縮水平、垂直和對角分割,即函數只保留末端的象素點; 
            CHAIN_APPROX_TC89_L1, CHAIN_APPROX_TC89_KCOS - 應用 Teh-Chin 鏈逼近演算法。
  • 第六個參數,Point類型的offset,每個輪廓點的可選位移量,有預設值Point()。當輪廓是從映像 ROI 中提取出來的時候,這個參數就可以排上用場了,因為可以從整個映像上下文來對輪廓做分析。

eg。
Mat srcImage = imread("M:/影像處理實驗/輪廓提取/test-1.bmp",1);cvtColor(srcImage, srcImage, COLOR_BGR2GRAY);adaptiveThreshold(srcImage,srcImage,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY, 35, 10);Mat result = Mat::zeros(srcImage.size(), CV_8UC3);  srcImage.copyTo(result);Canny(srcImage,srcImage,3,6,3);vector<vector<Point> > contours;vector<Vec4i> hierarchy;findContours(srcImage, contours, hierarchy, CV_RETR_TREE, CHAIN_APPROX_SIMPLE);int areaMin  = srcImage.cols * srcImage.rows;for (int i = 0; i < contours.size(); i++ ){    double area = contourArea(((contours)._Myfirst)[i]);    if (area > srcImage.rows * srcImage.cols/3){        //選取滿足條件的最小的面積。認為改輪廓為答題卡的邊框。        if (areaMin > area){            areaMin = area;        }else{            continue;        }        double area = contourArea(((contours)._Myfirst)[i]);        Scalar color(rand() & 255, rand() & 255, rand() & 255);        drawContours(result, contours, i, color, CV_FILLED, 8, hierarchy, 0, Point());    }            }imwrite("M:/影像處理實驗/輪廓提取/test-1-result.bmp", result);


以下為原圖及輪廓提取後的結果:

EmguCV3.0中的函數原型如下:

Public Shared Sub FindContours(image As Emgu.CV.IInputOutputArray, contours As Emgu.CV.IOutputArray, hierarchy As Emgu.CV.IOutputArray, mode As Emgu.CV.CvEnum.RetrType, method As Emgu.CV.CvEnum.ChainApproxMethod, Optional offset As System.Drawing.Point = Nothing)
  • 第一個參數,Emgu.CV.IInputOutputArray類型的image,源映像。映像的非零像素被認為是1,0像素被保留為0。此函數會在提取圖線輪廓的同時修改映像的內容。
  • 第二個參數,Emgu.CV.IOutputArray類型的contours。函數調用後的運算結果儲存在這裡,即為檢測到的輪廓,每一個輪廓儲存為一個點向量,即用Point類型的vector表示。
  • 第三個參數,Emgu.CV.IOutputArray類型的hierarchy,可選的輸出向量,包含映像的拓撲資訊。
  • 第四個參數,Emgu.CV.CvEnum.RetrType類型的mode,輪廓檢索模式。
            Emgu.CV.CvEnum.RetrType.External- 只提取最外層的輪廓 。
            Emgu.CV.CvEnum.RetrType.List- 提取所有輪廓,並且放置在 list 中 
            Emgu.CV.CvEnum.RetrType.Ccomp - 提取所有輪廓,並且將其組織為兩層的 hierarchy: 頂層為連通域的外圍邊界,次層為洞的內層邊界。 
            Emgu.CV.CvEnum.RetrType.Tree- 提取所有輪廓,並且重構嵌套輪廓的全部 hierarchy 
  • 第五個參數,Emgu.CV.CvEnum.ChainApproxMethod類型的method,輪廓逼近的方法。           
            Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxNone- 將所有點由鏈碼形式翻譯(轉化)為點序列形式 
            Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple- 壓縮水平、垂直和對角分割,即函數只保留末端的象素點; 
            Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxTC89L1, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxTC89KCOS - 應用 Teh-Chin 鏈逼近演算法。
  • 第六個參數,Point類型的offset,每個輪廓點的可選位移量,有預設值。當輪廓是從映像 ROI 中提取出來的時候,這個參數就可以排上用場了,因為可以從整個映像上下文來對輪廓做分析。

eg。
Dim bkGrayWhite As New Gray(255)Dim img As Image(Of Gray, Byte) = New Image(Of Gray, Byte)("M:\影像處理實驗\輪廓提取\test-2.bmp")Dim img_threshold As Image(Of Gray, Byte) = New Image(Of Gray, Byte)(img.Width, img.Height, bkGrayWhite)Dim imgresult As Image(Of Rgb, Byte) = New Image(Of Rgb, Byte)(img.Width, img.Height, New Rgb(255, 255, 255))img.CopyTo(img_threshold)CvInvoke.AdaptiveThreshold(img_threshold, img, 255, CvEnum.AdaptiveThresholdType.MeanC, CvEnum.ThresholdType.Binary, 35, 10)Dim imgCanny As Image(Of Gray, Byte) = New Image(Of Gray, Byte)(img.Width, img.Height, bkGrayWhite)CvInvoke.Canny(img, imgCanny, 25, 25 * 2, 3)Dim contours As Emgu.CV.Util.VectorOfVectorOfPoint = New Emgu.CV.Util.VectorOfVectorOfPoint()Dim hierarchy As Emgu.CV.IOutputArray = New Image(Of Gray, Byte)(img.Width, img.Height, bkGrayWhite)CvInvoke.FindContours(imgCanny,                                     contours,                                     hierarchy,                                     Emgu.CV.CvEnum.RetrType.External,                                     Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple                                      )Dim areaMax As Integer = img.Width * img.Height    For i = 0 To contours.Size - 1            Dim area As Integer = CvInvoke.ContourArea(contours(i))            ‘篩選輪廓面積大於三分之一整體圖片面積的輪廓            If area < areaMax / 3 Then                Continue For            End If            CvInvoke.DrawContours(imgresult, contours, i, New MCvScalar(0, 0, 0), 2, CvEnum.LineType.EightConnected, hierarchy, 2147483647)    Nextimgresult.Save("M:\影像處理實驗\輪廓提取\test-2-result.bmp")





OpenCV與EmguCV中的映像輪廓提取

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.