Opencv實現(xiàn)輪廓提取功能
輪廓:一個輪廓代表一系列的點(像素),這一系列的點構(gòu)成一個有序的點集,所以可以把一個輪廓理解為一個有序的點集。
在opencv中,提供了一個函數(shù)返回一個有序的點集或者有序的點集的集合(指多個有序的點集),函數(shù)findContour是從二值圖像中來計算輪廓的,一般使用Canny()函數(shù)處理后的圖像,因為這樣的圖像含有邊緣像素。
尋找輪廓的API函數(shù):
findContours(image,vector<vector<Point>> contours,vector<Vec4i>hierarchy,int mode,int method,Point offset = Point(0,0));
參數(shù)解釋:
(1)image:單通道圖像矩陣,一般是經(jīng)過canny處理后的二值圖像;
(2)contours:vector<vector<Point>>類型,是一個向量,并且是一個雙重向量,向量內(nèi)每個元素保存了一組由連續(xù)的Point點構(gòu)成的點的集合的向量,每一組Point點集就是一個輪廓。有多少輪廓,向量contours就有多少元素;
(3)hierarchy:vector<Vec4i> 類型, 即容器內(nèi)每一個元素都是一個包含了4個int型變量的向量,向量內(nèi)每個元素保存了一個包含4個int整型的數(shù)組。向量hiararchy內(nèi)的元素和輪廓向量contours內(nèi)的元素是一一對應(yīng)的,向量的容量相同。hierarchy向量內(nèi)每一個元素的4個int型變量——hierarchy[i][0] ~hierarchy[i][3],分別表示第i個輪廓的后一個輪廓、前一個輪廓、父輪廓、內(nèi)嵌輪廓的索引編號。如果當前輪廓沒有對應(yīng)的后一個輪廓、前一個輪廓、父輪廓或內(nèi)嵌輪廓的話,則hierarchy[i][0] ~hierarchy[i][3]的相應(yīng)位被設(shè)置為默認值-1;
(4)mode:int類型的,定義輪廓的檢索模式:
- CV_RETR_EXTERNAL只檢測最外圍輪廓,包含在外圍輪廓內(nèi)的內(nèi)圍輪廓被忽略;
- CV_RETR_LIST 檢測所有的輪廓,包括內(nèi)圍、外圍輪廓,但是檢測到的輪廓不建立等級關(guān)系,彼此之間獨立,沒有等級關(guān)系,這就意味著這個檢索模式下不存在父輪廓或內(nèi)嵌輪廓,所以hierarchy向量內(nèi)所有元素的第3、第4個分量都會被置為-1,具體下文會講到;
- CV_RETR_CCOMP 檢測所有的輪廓,但所有輪廓只建立兩個等級關(guān)系,外圍為頂層,若外圍內(nèi)的內(nèi)圍輪廓還包含了其他的輪廓信息,則內(nèi)圍內(nèi)的所有輪廓均歸屬于頂層;
- CV_RETR_TREE, 檢測所有輪廓,所有輪廓建立一個等級樹結(jié)構(gòu)。外層輪廓包含內(nèi)層輪廓,內(nèi)層輪廓還可以繼續(xù)包含內(nèi)嵌輪廓。
(5)method:int類型,定義輪廓的近似方法:
- CV_CHAIN_APPROX_NONE 保存物體邊界上所有連續(xù)的輪廓點到contours向量內(nèi);
- CV_CHAIN_APPROX_SIMPLE 僅保存輪廓的拐點信息,把所有輪廓拐點處的點保存入contours向量內(nèi),拐點與拐點之間直線段上的信息點不予保留;
- CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法;
(6) Point:偏移量,所有的輪廓信息相對于原始圖像對應(yīng)點的偏移量,相當于在每一個檢測出的輪廓點上加上該偏移量,一般不偏移取Point(0,0)。
畫輪廓的API函數(shù):
drawContours(Outputimage,contours,hierarchy,int contourIdx,color,int thickness ,int lineType,hierarchy = noArray(),int maxLevel = INT_MAX,Point offset = Point(0,0))
參數(shù)解釋:
(1)outputimage: 將輪廓畫在該圖上;
(2)contours:前面尋找到的輪廓;
(3)contourIdx:是一個索引,代表繪制contours中的第幾個輪廓;
(4) color:顏色;
(5)thickness: 線寬;
(6)lineType: 線型;
(7)hierarchy:可選層次信息結(jié)構(gòu),這里面是findContours所的到的基于Contours的層級信息;
(8)maxLevel: 繪制輪廓的最大等級。如果等級為0,繪制單獨的輪廓。如果為1,繪制輪廓及在其后的相同的級別下輪廓。如果等級為2,繪制所有同級輪廓及所有低一級輪廓,諸此種種。如果值為負數(shù),函數(shù)不繪制同級輪廓,但會升序繪制直到級別為abs(max_level)-1的子輪廓;
(9)offset:照給出的偏移量移動每一個輪廓點坐標.當輪廓是從某些感興趣區(qū)域(ROI)中提取的然后需要在運算中考慮ROI偏移量時,將會用到這個參數(shù)。
以上定義摘自該篇博客:OpenCV實現(xiàn)輪廓的發(fā)現(xiàn)。
#include<opencv2/opencv.hpp> using namespace cv; using namespace std; int value = 50; Mat src, dst, canny_img; void callback(int, void*); int main(int arc, char** argv) { src = imread("2.jpg"); namedWindow("src",CV_WINDOW_AUTOSIZE); imshow("src", src); cvtColor(src, src, CV_BGR2GRAY); namedWindow("output", CV_WINDOW_AUTOSIZE); createTrackbar("threshold", "output", &value, 255, callback); callback(0, 0); waitKey(0); return 0; } void callback(int, void*) { Canny(src, canny_img, value, 2 * value); imshow("canny", canny_img); vector<vector<Point>>contours; vector<Vec4i>hierarchy; findContours(canny_img, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE,Point(0,0)); dst = Mat::zeros(src.size(), CV_8UC3); RNG rng(1); for (int i = 0; i < contours.size(); i++) { Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point(0, 0)); } imshow("output", dst); }
運行結(jié)果如下:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++實現(xiàn)線性表有序表的合并方式(順序表實現(xiàn)and鏈表實現(xiàn))
這篇文章主要介紹了C++實現(xiàn)線性表有序表的合并方式(順序表實現(xiàn)and鏈表實現(xiàn)),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04C++面試八股文之如何實現(xiàn)strncpy函數(shù)
strncpy函數(shù),主要用做字符串復(fù)制,將于字符從一個位置復(fù)制到另一個位置,那么如何實現(xiàn)一個strncpy函數(shù),下面小編就來和大家簡單講講吧2023-07-07C++實現(xiàn)圖的遍歷算法(DFS,BFS)的示例代碼
本文給大家?guī)淼氖菆D遍歷的算法,DFS(深度優(yōu)先遍歷),BFS(廣度優(yōu)先遍歷)。這兩個算法是比較重要和常用的算法,但是在圖中的實現(xiàn)只是最基本的操作,快跟隨小編一起學(xué)習(xí)一下吧2022-07-07C++之普通成員函數(shù)、虛函數(shù)以及純虛函數(shù)的區(qū)別與用法要點
本篇文章主要介紹了C++中的普通成員函數(shù)、虛函數(shù)以及純虛函數(shù),非常的詳細,有需要的朋友可以參考下2015-07-07openCV4.1.1+VS2019環(huán)境配置詳解
這篇文章主要介紹了openCV4.1.1+VS2019環(huán)境配置詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08