1. 程式人生 > >opencv學習(四十)之尋找影象輪廓findContours()

opencv學習(四十)之尋找影象輪廓findContours()

1.概述

在這篇文章中介紹如何使用findContours()函式尋找影象中物體的輪廓,在OpenCV中沒有給出findCountours()函式的原理,如果想了解查詢輪廓原理,可以翻**牆出去Google”Topological structural analysis of digitized binary images by border following”,這裡就不一一翻譯了.

2.API

opencv中提供findContours()函式來尋找影象中物體的輪廓,並結合drawContours()函式將找到的輪廓繪製出。首先看一下findContours(),opencv中提供了兩種定義形式
findContours()


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

引數解釋
image:輸入影象,影象必須為8-bit單通道影象,影象中的非零畫素將被視為1,0畫素保留其畫素值,故載入影象後會自動轉換為二值影象。我們同樣可以使用cv::compare,cv::inRange,cv::threshold,cv::adaptiveThreshold,cv::Canny等函式來建立二值影象,,如果第四個引數為cv::RETR_CCOMP或cv::RETR_FLOODFILL,輸入影象可以是32-bit整型影象(CV_32SC1)
contours:檢測到的輪廓,每個輪廓都是以點向量的形式進行儲存即使用point型別的vector表示
hierarchy:

可選的輸出向量(std::vector),包含了影象的拓撲資訊,作為輪廓數量的表示hierarchy包含了很多元素,每個輪廓contours[i]對應hierarchy中hierarchy[i][0]~hierarchy[i][3],分別表示後一個輪廓,前一個輪廓,父輪廓,內嵌輪廓的索引,如果沒有對應項,則相應的hierarchy[i]設定為負數。
mode輪廓檢索模式,可以通過cv::RetrievalModes()檢視詳細資訊,如下
這裡寫圖片描述
其中
RETR_EXTERNAL:表示只檢測最外層輪廓,對所有輪廓設定hierarchy[i][2]=hierarchy[i][3]=-1
RETR_LIST:提取所有輪廓,並放置在list中,檢測的輪廓不建立等級關係
RETR_CCOMP:提取所有輪廓,並將輪廓組織成雙層結構(two-level hierarchy),頂層為連通域的外圍邊界,次層位內層邊界
RETR_TREE:提取所有輪廓並重新建立網狀輪廓結構
RETR_FLOODFILL:官網沒有介紹,應該是洪水填充法
method:輪廓近似方法可以通過cv::ContourApproximationModes()檢視詳細資訊
這裡寫圖片描述
CHAIN_APPROX_NONE:獲取每個輪廓的每個畫素,相鄰的兩個點的畫素位置差不超過1
CHAIN_APPROX_SIMPLE:壓縮水平方向,垂直方向,對角線方向的元素,值保留該方向的重點座標,如果一個矩形輪廓只需4個點來儲存輪廓資訊
CHAIN_APPROX_TC89_L1和CHAIN_APPROX_TC89_KCOS使用Teh-Chinl鏈逼近演算法中的一種
offset:輪廓點可選偏移量,有預設值Point(),對ROI影象中找出的輪廓並要在整個影象中進行分析時,使用

opencv中提供的另一種定義形式如下:

void cv::findContours   (   InputOutputArray    image,
                            OutputArrayOfArrays     contours,
                            int     mode,
                            int     method,
                            Point   offset = Point() 
                        )   

drawContours()

void cv::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:輸入輸出影象,Mat型別即可
contours:使用findContours檢測到的輪廓資料,每個輪廓以點向量的形式儲存,point型別的vector
contourIdx:繪製輪廓的只是變數,如果為負值則繪製所有輸入輪廓
color:輪廓顏色
thickness:繪製輪廓所用線條粗細度,如果值為負值,則在輪廓內部繪製
lineTpye:線條型別,有預設值LINE_8,有如下可選型別
這裡寫圖片描述
hierarchy:可選層次結構資訊
maxLevel:用於繪製輪廓的最大等級
offset:可選輪廓便宜引數,用制定偏移量offset=(dx, dy)給出繪製輪廓的偏移量

3.示例程式碼

#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <stdlib.h>

using namespace std;
using namespace cv;

int main()
{
    Mat srcImage, grayImage, dstImage;
    srcImage = imread("HappyFish.jpg");

    //判斷影象是否載入成功
    if (srcImage.empty())
    {
        cout << "影象載入失敗" << endl;
        return -1;
    }
    else
    {
        cout << "影象載入成功!" << endl << endl;
    }

    namedWindow("原影象", WINDOW_AUTOSIZE);
    imshow("原影象", srcImage);

    //轉換為灰度圖並平滑濾波
    cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);

    //定義變數
    vector<vector<Point>>contours;
    vector<Vec4i>hierarchy;

    grayImage = grayImage > 100;
    findContours(grayImage, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

    //繪製輪廓圖
    dstImage = Mat::zeros(grayImage.size(), CV_8UC3);
    for (int i = 0; i < hierarchy.size(); i++)
    {
        Scalar color = Scalar(rand() % 255, rand() % 255, rand() % 255);
        drawContours(dstImage, contours, i, color, CV_FILLED, 8, hierarchy);
    }
    imshow("輪廓圖", dstImage);
    waitKey(0);

    return 0;
}

4.執行結果

這裡寫圖片描述

相關推薦

opencv學習()尋找影象輪廓findContours()

1.概述 在這篇文章中介紹如何使用findContours()函式尋找影象中物體的輪廓,在OpenCV中沒有給出findCountours()函式的原理,如果想了解查詢輪廓原理,可以翻**牆出去Google”Topological structural ana

opencv學習(一)尋找凸包convexHull()

1.概述 凸包(Convex Hull)是一個計算幾何(圖形學)中的概念,在一個實數向量空間V中,對於給定集合X,所有包含X的凸集的交集S被稱為X的凸包。 X的凸包可以用X內所有點(x1, x2….xn)的線性組合來構造。在二維歐幾里得空間中,凸包可以想象為

opencv學習()影象角點檢測Harris

1.概述 角點是影象很重要的特徵,對影象圖形的理解和分析有很重要的作用,在保留影象圖形重要特徵的同時,可以有效減少資訊的資料量,使資訊的含量很高,有效提高計算速度,有利於影象的可靠匹配,使得實時處理成為可能。在物體識別、影象匹配、視覺跟蹤和三維重建等方面有很重

opencv學習章 估算影象之間的投影關係

opencv學習 第十章 估算影象之間的投影關係 10.2 計算影象對的基礎矩陣 #include"stdafx.h" #include<iostream> #include<opencv2/core/core.hpp> #include<ope

opencv學習(二)高斯濾波GaussianBlur()

高斯濾波是一種線性平滑濾波,對於除去高斯噪聲有很好的效果。在其官方文件中形容高斯濾波為”Probably the most useful filter”,同時也指出高斯濾波並不是效率最高的濾波演算法。高斯演算法在官方文件給出的解釋是高斯濾波是通過對輸入陣列的每個

python實現opencv學習一:影象的開閉操作

作用:刪除影象的小的干擾項原始碼如下:# -*- coding=GBK -*- import cv2 as cv #影象的開閉操作 def open_image(image): gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY

opencv學習影象顏色通道分離和融合

在影象處理時,我們接觸到的彩色以RGB居多,為了分析影象在某一通道上的特性,需要將影象的顏色通道進行分離,或者是在對某一顏色通道處理後重新進行融合。opencv提供了split()函式來進行顏色通道的分離,提供了merge()函式來進行顏色通道的融合。 1.s

OpenCV學習筆記】影象輪廓特徵與影象的矩

轉載: https://blog.csdn.net/zhu_hongji/article/details/81699736   一、影象的輪廓(Contours of Image)        輪廓可以說是一個很好的影象目標的

opencv學習五)影象傅立葉變換dft

在學習訊號與系統或通訊原理等課程裡面可能對傅立葉變換有了一定的瞭解。我們知道傅立葉變換是把一個訊號從時域變換到其對應的頻域進行分析。如果有小夥伴還對傅立葉變換處於很迷糊的狀態,請戳這裡,非常通俗易懂。而在影象處理中也有傅立葉分析的概念,我這裡給出在其官方指導檔案

opencv學習(二)腐蝕與膨脹

腐蝕和膨脹是對二維圖片的進行操作的形態學運算,簡單來講形態學操作就是基於形狀的一系列影象處理操作,通過將結構元素作用於輸入影象來產生輸出影象。腐蝕(Erosion)和膨脹(Dilation)是最基本的形態學操作,他們運用廣泛主要有: . 消除噪聲

opencv學習(三)重對映remap

重對映就是把一個影象中一個為之的畫素放置到另一個圖片指定位置過程。為了完成重對映過程有必要獲得一些插值作為非整數畫素座標,因為原影象與目標影象的畫素座標不是一一對應的。我們通過重對映來表達每個畫素的位置(x, y): g(x, y)=f(h(x,y)) 這裡

opencv學習(二八)基本影象閾值操作threshold

在二維數字影象中,其每個畫素點對應了不同的畫素值,其畫素值各不相同。可以對畫素值特定範圍內的影象影象進行操作,劃分這個範圍的值就被稱為影象閾值,它不是一個固定的量級,是根據每幅影象和處理要求動態改變。例如我們可以從影象中利用閾值分割出我們需要的部分,利用其畫素值

python學習天(前端HTML標簽)

增加 engine 區域 什麽 公司 交叉 頭標簽 pad 問題  今日主要內容:   web標準   瀏覽器內核   HTML介紹,規範,結構詳解   字體標簽   排版標簽   超鏈接   圖片標簽 1.web標準 web準備介紹: w3c:萬維網聯盟組織,用來制

opencv學習八):影象梯度

程式程式碼: #匯入cv模組 # -*- coding=utf-8 -*- import cv2 as cv import numpy as np #lapalian運算元 def lapalian_demo(image): # dst=cv.Laplacian(image,cv.CV

opencv學習七):影象金子塔

邊緣檢測運算元 參考學習連結:https://blog.csdn.net/xiaowei_cqu/article/details/7829481 影象金子塔 參考學習連結:https://www.cnblogs.com/Matrix420/p/4214123.html open

opencv學習六):超大影象二值化

超大影象二值化的方法         1.可以採用分塊方法;2.先縮放處理就行二值化,然後還原大小。 一:分塊處理超大影象的二值化問題 #匯入cv模組 import cv2 as cv import numpy as np #超大影象二值化 de

opencv學習六):影象的二值化

影象二值化介紹:https://blog.csdn.net/qq_30490125/article/details/80458500                       &nbs

opencv學習):直方圖的反向投影

目標:  直方圖反向投影 原理:  反向投影可以用來做影象分割,尋找感興趣區間。它會輸出與輸入影象大小相同的影象,每一個畫素值代表了輸入影象上對應點屬於目標物件的概率,簡言之,輸出影象中畫素值越高的點越可能代表想要查詢的目標。直方圖投影經常與camshift(追蹤演

OpenCV學習:watershed 分水嶺演算法

1. watershed  void watershed( InputArray image, InputOutputArray markers ); 第一個引數 image,必須是一個8bit 3通道彩色影象矩陣序列,第一個引數沒什麼要說的。 關鍵是第二個引數 mar

【Python+OpenCV入門學習二、影象的幾何變換

本篇文章介紹影象處理的幾何變換,幾何變換有平移、縮放、旋轉等。 主要學習resize()、warpAffine()等函式的使用。 環境:Windows 7(64)   Python 3.6    OpenCV3.4.2 一、縮放 1.1 resize()函式介紹 r