OpenCV實現輪廓檢測與繪制
圖像的輪廓不僅能夠提供物體的邊緣,而且還能提供物體邊緣之間的層次關系以及拓撲關系。
帶有結構關系的邊緣檢測,這種結構關系可以表明圖像中連通域或者某些區域之間的關系。
圖為一個具有4個不連通邊緣的二值化圖像,由外到內依次為0號、1號、2號、3號條邊緣。為瞭描述不同輪廓之間的結構關系,定義由外到內的輪廓級別越來越低,也就是高一層級的輪廓包圍著較低層級的輪廓,被同一個輪廓包圍的多個不互相包含的輪廓是同一層級輪廓。例如在圖中,0號輪廓層級比1號和第2號輪廓的層及都要高,2號輪廓包圍著3號輪廓,因此2號輪廓的層級要高於3號輪廓。
常用4個參數來描述不同層級之間的結構關系:同層下一個輪廓索引、同層上一個輪廓索引、下一層第一個子輪廓索引和上層父輪廓索引。
上圖中0號輪廓沒有同級輪廓和父輪廓需要用-1表示,其第一個子輪廓為1號輪廓,因此可以用描述該輪廓的結構。1號輪廓的下一個同級輪廓為2號輪廓但是沒有上一個同級輪廓用-1表示,父輪廓為0號輪廓,第一個子輪廓為3號輪廓,因此可以用描述該輪廓結構。2號輪廓和3號輪廓同樣可以用這樣的方式構建結構關系描述子。圖中不同輪廓之間的層級關系可以用圖表示。
在二值圖像中檢測圖像中所有輪廓並生成不同輪廓結構關系描述子:
void findContours( InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset = Point());
- image:輸入圖像,數據類型為CV_8U的單通道灰度圖像或者二值化圖像。
- contours:檢測到的輪廓,每個輪廓中存放著像素的坐標。
- hierarchy:輪廓結構關系描述向量。
- mode:輪廓檢測模式標志,可以選擇的參數在表7-2給出。
- method:輪廓逼近方法標志,可以選擇的參數在表7-3給出。
- offset:每個輪廓點移動的可選偏移量。這個參數主要用在從ROI圖像中找出輪廓並基於整個圖像分析輪廓的場景中。
該函數主要用於檢測圖像中的輪廓信息,並輸出各個輪廓之間的結構信息。
函數的第一個參數是待檢測輪廓的輸入圖像,從理論上講檢測圖像輪廓需要是二值化圖像,但是該函數會對非0像素視為1,0像素保持不變,因此該參數能夠接受非二值化的灰度圖像。由於該函數默認二值化操作不能保持圖像主要的內容,因此常需要對圖像進行預處理,利用threshold()函數或者adaptiveThreshold()函數根據需求進行二值化。
第二個參數用於存放檢測到的輪廓,數據類型為vector,每個輪廓中存放著屬於該輪廓的像素坐標。
函數的第三個參數用於存放各個輪廓之間的結構信息,數據類型為vector,數據的尺寸與檢測到的輪廓數目相同,每個輪廓結構信息中第1個數據表示同層下一個輪廓索引、第2個數據表示同層上一個輪廓索引、第3個數據表示下一層第一個子輪廓索引、第4個數據表示上層父輪廓索引。
函數第四個參數是輪廓檢測模式的標志,可以選擇的參數及含義在表7-2給出。
函數第五個參數是選擇輪廓逼近方法的標志,可以選擇的參數及含義在表7-3給出。
函數最後一個參數是每個輪廓點移動的可選偏移量。這個函數主要用在從ROI圖像中找出輪廓並基於整個圖像分析輪廓的場景中。
隻需要檢測圖像的輪廓,並不關心輪廓之間的結構關系信息
void findContours( InputOutputArray image, OutputArrayOfArrays contours, int mode, int method, Point offset = Point());
- image:輸入圖像,數據類型為CV_8U的單通道灰度圖像或者二值化圖像。
- contours:檢測到的輪廓,每個輪廓中存放著像素的坐標。
- mode:輪廓檢測模式標志,可以選擇的參數在表7-2給出。
- method:輪廓逼近方法標志,可以選擇的參數在表7-3給出。
- offset:每個輪廓點移動的可選偏移量。這個函數主要用在從ROI圖像中找出輪廓並基於整個圖像分析輪廓的場景中。
繪制輪廓函數:
void drawContours( InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, int thickness = 1, int lineType = LINE_8, InputArray hierarchy = noArray(), int maxLevel = INT_MAX, Point offset = Point() );
- image:繪制輪廓的目標圖像。
- contours:所有將要繪制的輪廓
- contourIdx:要繪制的輪廓的數目,如果是負數,則繪制所有的輪廓。
- color:繪制輪廓的顏色。
- thickness:繪制輪廓的線條粗細,如果參數為負數,則繪制輪廓的內部,默認參數值為1.
- lineType:邊界線連接的類型,可以選擇參數在表7-4給出,默認參數值為LINE_8。
- hierarchy:可選的結構關系信息,默認值為noArray()。
- maxLevel:表示用於繪制輪廓的最大等級,默認值為INT_MAX。
- offset:可選的輪廓偏移參數,按指定的移動距離繪制所有的輪廓。
該函數用於繪制findContours()函數檢測到的圖像輪廓。
函數的第一個參數為繪制輪廓的圖像,根據需求該參數可以是單通道的灰度圖像或者三通道的彩色圖像。
第二個參數是所有將要繪制的輪廓,數據類型為vector。
第三個參數是要繪制的輪廓數目,該參數的數值與第二個參數相對應,應小於所有輪廓的數目,如果該參數值為負數,則繪制所有的輪廓。
第四個參數是繪制輪廓的顏色,對於單通道的灰度圖像用Scalar(x)賦值,對於三通道的彩色圖像用Scalar(x,y,z)賦值。
第五個參數是邊界線的連接類型,可以選擇的參數在表7-4給出,默認參數值為LINE_8。
第六個參數是可選的結構關系信息,默認值為noArray()。
第七個參數表示繪制輪廓的最大等級,參數值如果為0,則僅繪制指定的輪廓;如果為1,則該函數繪制輪廓和所有嵌套輪廓;如果為2,則該函數繪制輪廓以及所有嵌套輪廓和所有嵌套到嵌套輪廓的輪廓,以此類推,默認值為INT_MAX。函數最後一個參數是可選的輪廓偏移參數,按指定的移動距離繪制所有的輪廓。
簡單示例
// // Created by smallflyfly on 2021/6/22. // #include "opencv2/opencv.hpp" #include <iostream> using namespace std; using namespace cv; int main() { Mat im = imread("rice.jfif"); resize(im, im, Size(0, 0), 0.5, 0.5); Mat gray; cvtColor(im, gray, CV_BGR2GRAY); Mat imBin; threshold(gray, imBin, 125, 255,THRESH_BINARY); vector<vector<Point>> contours; findContours(imBin, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); vector<Vec4i> hierarchy; findContours(imBin, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE); drawContours(im, contours, -1, Scalar(0, 0, 255)); for (auto & i : hierarchy) { cout << i << endl; } imshow("im", im); waitKey(0); destroyAllWindows(); return 0; }
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Python OpenCV 基於圖像邊緣提取的輪廓發現函數
- OpenCV圖像輪廓的繪制方法
- python OpenCV圖像金字塔
- C++ OpenCV實現二維碼檢測功能
- OpenCV實現輪廓外接多邊形