欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

OpenCV中findContours函數(shù)參數(shù)詳解

 更新時(shí)間:2022年08月02日 09:53:32   作者:-牧野-  
Opencv中通過(guò)使用findContours函數(shù),簡(jiǎn)單幾個(gè)的步驟就可以檢測(cè)出物體的輪廓,很方便。本文將和大家一起探討一下findContours方法中各參數(shù)的含義及用法,感興趣的可以了解一下

注: 這篇文章用的OpenCV版本是2.4.10, 3以上的OpenCV版本相關(guān)函數(shù)可能有改動(dòng)

Opencv中通過(guò)使用findContours函數(shù),簡(jiǎn)單幾個(gè)的步驟就可以檢測(cè)出物體的輪廓,很方便。這些準(zhǔn)備繼續(xù)探討一下findContours方法中各參數(shù)的含義及用法,比如要求只檢測(cè)最外層輪廓該怎么辦?contours里邊的數(shù)據(jù)結(jié)構(gòu)是怎樣的?hierarchy到底是什么鬼?Point()有什么用?

先從findContours函數(shù)原型看起:

findContours( InputOutputArray image, OutputArrayOfArrays contours,
                              OutputArray hierarchy, int mode,
                              int method, Point offset=Point());

第一個(gè)參數(shù):image,單通道圖像矩陣,可以是灰度圖,但更常用的是二值圖像,一般是經(jīng)過(guò)Canny、拉普拉斯等邊緣檢測(cè)算子處理過(guò)的二值圖像;

第二個(gè)參數(shù):contours,定義為“vector<vector<Point>> contours”,是一個(gè)向量,并且是一個(gè)雙重向量,向量?jī)?nèi)每個(gè)元素保存了一組由連續(xù)的Point點(diǎn)構(gòu)成的點(diǎn)的集合的向量,每一組Point點(diǎn)集就是一個(gè)輪廓。  

有多少輪廓,向量contours就有多少元素。

第三個(gè)參數(shù):hierarchy,定義為“vector<Vec4i> hierarchy”,先來(lái)看一下Vec4i的定義:

typedef    Vec<int, 4>   Vec4i;;

Vec4i是Vec<int,4>的別名,定義了一個(gè)“向量?jī)?nèi)每一個(gè)元素包含了4個(gè)int型變量”的向量。

所以從定義上看,hierarchy也是一個(gè)向量,向量?jī)?nèi)每個(gè)元素保存了一個(gè)包含4個(gè)int整型的數(shù)組。

向量hiararchy內(nèi)的元素和輪廓向量contours內(nèi)的元素是一一對(duì)應(yīng)的,向量的容量相同。

hierarchy向量?jī)?nèi)每一個(gè)元素的4個(gè)int型變量——hierarchy[i][0] ~hierarchy[i][3],分別表示第i個(gè)輪廓的后一個(gè)輪廓、前一個(gè)輪廓、父輪廓、內(nèi)嵌輪廓的索引編號(hào)。如果當(dāng)前輪廓沒(méi)有對(duì)應(yīng)的后一個(gè)輪廓、前一個(gè)輪廓、父輪廓或內(nèi)嵌輪廓的話,則hierarchy[i][0] ~hierarchy[i][3]的相應(yīng)位被設(shè)置為默認(rèn)值-1。

第四個(gè)參數(shù):int型的mode,定義輪廓的檢索模式:

取值一:CV_RETR_EXTERNAL只檢測(cè)最外圍輪廓,包含在外圍輪廓內(nèi)的內(nèi)圍輪廓被忽略

取值二:CV_RETR_LIST   檢測(cè)所有的輪廓,包括內(nèi)圍、外圍輪廓,但是檢測(cè)到的輪廓不建立等級(jí)關(guān)系,彼此之間獨(dú)立,沒(méi)有等級(jí)關(guān)系,這就意味著這個(gè)檢索模式下不存在父輪廓或內(nèi)嵌輪廓,所以hierarchy向量?jī)?nèi)所有元素的第3、第4個(gè)分量都會(huì)被置為-1,具體下文會(huì)講到

取值三:CV_RETR_CCOMP  檢測(cè)所有的輪廓,但所有輪廓只建立兩個(gè)等級(jí)關(guān)系,外圍為頂層,若外圍內(nèi)的內(nèi)圍輪廓還包含了其他的輪廓信息,則內(nèi)圍內(nèi)的所有輪廓均歸屬于頂層

取值四:CV_RETR_TREE, 檢測(cè)所有輪廓,所有輪廓建立一個(gè)等級(jí)樹結(jié)構(gòu)。外層輪廓包含內(nèi)層輪廓,內(nèi)層輪廓還可以繼續(xù)包含內(nèi)嵌輪廓。

第五個(gè)參數(shù):int型的method,定義輪廓的近似方法:

取值一:CV_CHAIN_APPROX_NONE 保存物體邊界上所有連續(xù)的輪廓點(diǎn)到contours向量?jī)?nèi)

取值二:CV_CHAIN_APPROX_SIMPLE 僅保存輪廓的拐點(diǎn)信息,把所有輪廓拐點(diǎn)處的點(diǎn)保存入contours向量?jī)?nèi),拐點(diǎn)與拐點(diǎn)之間直線段上的信息點(diǎn)不予保留

取值三和四:CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法

第六個(gè)參數(shù):Point偏移量,所有的輪廓信息相對(duì)于原始圖像對(duì)應(yīng)點(diǎn)的偏移量,相當(dāng)于在每一個(gè)檢測(cè)出的輪廓點(diǎn)上加上該偏移量,并且Point還可以是負(fù)值!

下邊用效果圖對(duì)比一下findContours函數(shù)中各參數(shù)取不同值時(shí),向量contours和hierarchy的內(nèi)容如何變化,有何異同。

主體程序如下:

#include "core/core.hpp"  
#include "highgui/highgui.hpp"  
#include "imgproc/imgproc.hpp"  
#include "iostream"
 
using namespace std; 
using namespace cv;  
 
int main(int argc,char *argv[])  
{
    Mat imageSource=imread(argv[1],0);
    imshow("Source Image",imageSource);
    Mat image;
    GaussianBlur(imageSource,image,Size(3,3),0);
    Canny(image,image,100,250);
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(image,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point());
    Mat imageContours=Mat::zeros(image.size(),CV_8UC1);
    Mat Contours=Mat::zeros(image.size(),CV_8UC1);  //繪制
    for(int i=0;i<contours.size();i++)
    {
        //contours[i]代表的是第i個(gè)輪廓,contours[i].size()代表的是第i個(gè)輪廓上所有的像素點(diǎn)數(shù)
        for(int j=0;j<contours[i].size();j++) 
        {
            //繪制出contours向量?jī)?nèi)所有的像素點(diǎn)
            Point P=Point(contours[i][j].x,contours[i][j].y);
            Contours.at<uchar>(P)=255;
        }
 
        //輸出hierarchy向量?jī)?nèi)容
        char ch[256];
        sprintf(ch,"%d",i);
        string str=ch;
        cout<<"向量hierarchy的第" <<str<<" 個(gè)元素內(nèi)容為:"<<endl<<hierarchy[i]<<endl<<endl;
 
        //繪制輪廓
        drawContours(imageContours,contours,i,Scalar(255),1,8,hierarchy);
    }
    imshow("Contours Image",imageContours); //輪廓
    imshow("Point of Contours",Contours);   //向量contours內(nèi)保存的所有輪廓點(diǎn)集
    waitKey(0);
    return 0;
}

程序中所用原始圖像如下:

通過(guò)調(diào)整第四個(gè)參數(shù)mode——輪廓的檢索模式、第五個(gè)參數(shù)method——輪廓的近似方式和不同的偏移量Point(),就可以得到以下效果。

一、mode取值“CV_RETR_EXTERNAL”

method取值“CV_CHAIN_APPROX_NONE”,即只檢測(cè)最外層輪廓,并且保存輪廓上所有點(diǎn):

輪廓:

只有最外層的輪廓被檢測(cè)到,內(nèi)層的輪廓被忽略

contours向量?jī)?nèi)所有點(diǎn)集:

保存了所有輪廓上的所有點(diǎn),圖像表現(xiàn)跟輪廓一致

hierarchy向量:

重溫一下hierarchy向量————向量中每個(gè)元素的4個(gè)整形分別對(duì)應(yīng)當(dāng)前輪廓的后一個(gè)輪廓、前一個(gè)輪廓、父輪廓、內(nèi)嵌輪廓的索引編號(hào)。

本次參數(shù)配置下,hierarchy向量?jī)?nèi)有3個(gè)元素,分別對(duì)應(yīng)于3個(gè)輪廓。以第2個(gè)輪廓(對(duì)應(yīng)向量?jī)?nèi)第1個(gè)元素)為例,內(nèi)容為[2,0,-1,-1], “2”表示當(dāng)前輪廓的后一個(gè)輪廓的編號(hào)為2,“0”表示當(dāng)前輪廓的前一個(gè)輪廓編號(hào)為0,其后2個(gè)“-1”表示為空,因?yàn)橹挥凶钔鈱虞喞@一個(gè)等級(jí),所以不存在父輪廓和內(nèi)嵌輪廓。

二、 mode取值“CV_RETR_LIST”

method取值“CV_CHAIN_APPROX_SIMPLE”,即檢測(cè)所有輪廓,但各輪廓之間彼此獨(dú)立,不建立等級(jí)關(guān)系,并且僅保存輪廓上拐點(diǎn)信息:

檢測(cè)到的輪廓跟上文“一”中是一致的,不再顯示。

contours向量?jī)?nèi)所有點(diǎn)集:

contours向量中所有的拐點(diǎn)信息得到了保留,但是拐點(diǎn)與拐點(diǎn)之間直線段的部分省略掉了。

hierarchy向量(截取一部分):

本次參數(shù)配置下,檢測(cè)出了較多輪廓。第1、第2個(gè)整形值分別指向上一個(gè)和下一個(gè)輪廓編號(hào),由于本次配置mode取

值“RETR_LIST”,各輪廓間各自獨(dú)立,不建立等級(jí)關(guān)系,所以第3、第4個(gè)整形參數(shù)為空,設(shè)為值-1。

三、mode取值“CV_RETR_TREE”

method取值“CV_CHAIN_APPROX_NONE”,即檢測(cè)所有輪廓,輪廓間建立外層、內(nèi)層的等級(jí)關(guān)系,并且保存輪廓上所有點(diǎn)。

contours向量?jī)?nèi)所有點(diǎn)集:

所有內(nèi)外層輪廓都被檢測(cè)到,contours點(diǎn)集組成的圖形跟輪廓表現(xiàn)一致。

hierarchy向量(截取一部分)

本次參數(shù)配置要求檢測(cè)所有輪廓,每個(gè)輪廓都被劃分等級(jí),最外圍、第一內(nèi)圍、第二內(nèi)圍等等,所以除第1個(gè)最后一個(gè)輪廓外,其他輪廓都具有不為-1的第3、第4個(gè)整形參數(shù),分別指向當(dāng)前輪廓的父輪廓、內(nèi)嵌輪廓索引編號(hào)。

四、Point()偏移量設(shè)置

使用三中的參數(shù)配置,設(shè)置偏移量Point為Point(45,30)。

此時(shí)輪廓圖像為:

可以看到輪廓圖像整體向右下角有一個(gè)偏轉(zhuǎn),偏轉(zhuǎn)量就是設(shè)置的(45,30)。

這個(gè)偏移量的設(shè)置不能過(guò)大或過(guò)?。ㄘ?fù)方向上的過(guò)小),若圖像上任一點(diǎn)加上該偏移量后超出圖像邊界,程序會(huì)內(nèi)存溢出報(bào)錯(cuò)。

findContours函數(shù)的各參數(shù)就探討到此,其他參數(shù)配置的情況大同小異。值得關(guān)注一下的是繪制輪廓的函數(shù)drawContours中最后一個(gè)參數(shù)是一個(gè)Point類型的offset,這個(gè)offset跟findContours函數(shù)中的offset含義一致,設(shè)置之后所繪制的輪廓是原始輪廓上所有像素點(diǎn)加上該偏移量offset后的效果。

當(dāng)所分析圖像是另外一個(gè)圖像的ROI的時(shí)候,這個(gè)offset偏移量就可以大顯身手了。通過(guò)加減這個(gè)偏移量,就可以把ROI圖像的檢測(cè)結(jié)果投影到原始圖像對(duì)應(yīng)位置上。

到此這篇關(guān)于OpenCV中findContours函數(shù)參數(shù)詳解的文章就介紹到這了,更多相關(guān)OpenCV findContours內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 編寫C++程序使DirectShow進(jìn)行視頻捕捉

    編寫C++程序使DirectShow進(jìn)行視頻捕捉

    這篇文章主要介紹了如何編寫C++程序來(lái)使DirectShow進(jìn)行視頻捕捉的方法,DirectShow是微軟公司在ActiveMovie和Video for Windows的基礎(chǔ)上推出的新一代基于COM(Component Object Model)的流媒體處理的開發(fā)包,要的朋友可以參考下
    2016-03-03
  • 深入解析int(*p)[]和int(**p)[]

    深入解析int(*p)[]和int(**p)[]

    以下是對(duì)int(*p)[]和int(**p)[]的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下
    2013-07-07
  • 在1個(gè)Matlab m文件中定義多個(gè)函數(shù)直接運(yùn)行的操作方法

    在1個(gè)Matlab m文件中定義多個(gè)函數(shù)直接運(yùn)行的操作方法

    這篇文章主要介紹了如何在1個(gè)Matlab m文件中定義多個(gè)函數(shù)直接運(yùn)行,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • 基于WTL中使用雙緩沖避免閃爍的解決方法

    基于WTL中使用雙緩沖避免閃爍的解決方法

    本篇文章是對(duì)WTL中使用雙緩沖避免閃爍的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 深入淺析 C++ 調(diào)用 Python 模塊

    深入淺析 C++ 調(diào)用 Python 模塊

    Python 提供了 C++ 庫(kù),使得開發(fā)者能很方便地從 C++ 程序中調(diào)用 Python 模塊。接下來(lái)通過(guò)本文給大家介紹 C++ 調(diào)用 Python 模塊的相關(guān)知識(shí),需要的朋友參考下吧
    2016-03-03
  • 關(guān)于C++虛繼承的內(nèi)存模型問(wèn)題

    關(guān)于C++虛繼承的內(nèi)存模型問(wèn)題

    C++虛繼承的內(nèi)存模型是一個(gè)老生常談的話題,實(shí)現(xiàn)方法主要依賴于編譯器,本文從多個(gè)角度通過(guò)代碼詳解C++中虛繼承的內(nèi)存模型知識(shí),感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • Opencv光流運(yùn)動(dòng)物體追蹤詳解

    Opencv光流運(yùn)動(dòng)物體追蹤詳解

    這篇文章主要為大家詳細(xì)介紹了Opencv光流運(yùn)動(dòng)物體追蹤的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++繼承詳細(xì)介紹

    C++繼承詳細(xì)介紹

    我們都知道面向?qū)ο笳Z(yǔ)言的三大特點(diǎn)是:**封裝,繼承,多態(tài)。**之前在類和對(duì)象部分,我們提到了C++中的封裝,那么今天呢,我們來(lái)學(xué)習(xí)一下C++中的繼承
    2022-10-10
  • C語(yǔ)言實(shí)現(xiàn)財(cái)務(wù)管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)財(cái)務(wù)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)財(cái)務(wù)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 《C++ primer plus》讀書筆記(三)

    《C++ primer plus》讀書筆記(三)

    本文是C++讀書筆記系列的第三篇,是讀完《C++ primer plus》一書第九、十兩章記錄下來(lái)的筆記,學(xué)習(xí)C++的同學(xué)可以看看參考下。
    2014-10-10

最新評(píng)論