opencv —— findContours、drawContours 尋找並繪制輪廓


輪廓圖像與 Canny 圖像的區別

一個輪廓一般對應一系列的點,也就是圖像中的一條曲線。輪廓圖像和 Canny 圖像乍看起來表現幾乎是一致的,但其實組成兩者的數據結構差別很大:

  • Canny 邊緣圖像是一個點的集合,點與點之間沒有聯系。

  •  輪廓圖像是一個點集的集合,每個點集(即輪廓)內的點都是相鄰的,點集與點集之間也存在前后、父內等關系。

 

尋找輪廓:findContours 函數

findContours 函數用於在二值圖像中尋找輪廓。

void findContours(InputArray image, OutputArrays contours, OutputArray hierarchy, int mode, int method, Point offset = Point());

  • image,輸入圖像,即源圖像,填 Mat 類的對象即可,可以是灰度圖(非零像素被視為 1),但更常用的是二值圖像,一般是經過Canny、拉普拉斯等邊緣檢測算子處理過的二值圖像。
  • contours,檢測到的所有輪廓均會被存在這里。每個輪廓為一個點集,用 Point 類型的 vector 表示。所以會被定義為

vector<vector<Point> > contours

  • hierarchy,每個輪廓 contours[i] 對應四個 hierarchy[i][0] ~ hierarchy[i][3],分別表示與當前輪廓平級的后一個輪廓的的索引編號、與當前輪廓平級的前一個輪廓的索引編號、當前輪廓的子輪廓的索引編號、當前輪廓的父輪廓的索引編號。如果沒有對應項,hierarchy[i][x] = -1。
  • mode,輪廓檢索模式,取值如下:

標識符 含義
RETR_EXTERNAL

只檢測最外層輪廓,包含在外圍輪廓內的內圍輪廓被忽略。不存在父輪廓或內嵌輪廓

(hierarchy[i][2] = hierarchy[i][3] = -1)。

RETR_LIST

提取所有輪廓,並且放置在 list 中。不存在父輪廓或內嵌輪廓

(hierarchy[i][2] = hierarchy[i][3] = -1)。

再舉個例子:

 

RETR_CCOMP

提取所有輪廓,無論嵌套個數多少,都將其組織為雙層結構(外層、內層)。

再舉個例子:

RETR_TREE

提取所有輪廓,並建立網狀的輪廓結構(最外層輪廓為根)。

再舉個例子:

 

  • method,輪廓的近似辦法,取值如下:
標識符 含義
CHAIN_APPROX_NONE 獲取每個輪廓的每個像素,相鄰的兩個像素位差不超過 1 像素。
CHAIN_APPROX_SIMPLE 僅保存輪廓的拐點信息,拐點與拐點之間直線段上的信息點不予保留。例如一個矩形輪廓只需 4 個點來保留輪廓信息。

CHAIN_APPROX_TC89_L1

CHAIN_APPROX_TC89_KCOS

使用 teh-Chinl chain 近似算法。
  • offset,所有的輪廓信息相對於原始圖像對應點的偏移量,相當於在每一個檢測出的輪廓點上加上該偏移量,有默認值 Point() 。對 ROI 區域(感興趣區域)中找出的輪廓,並要在整個圖像中進行分析時,這個參數便可派上用場。

 

繪制輪廓:drawContours 函數

void drawContours(InputOutputArray image, InputOutputArrays contours, int contourIdx, const Scalar& color, int thickness = 1, int lineType = 8, InputArray hierarchy = noArray(), int maxLevel = INT_MAX, Point offset = Point());

  • image,目標圖像,填 Mat 類對象即可。
  • contours,輸入的輪廓,每個輪廓都是一組點集,可用 Point 類型的 vector 表示。
  • contourIdx,輪廓的索引編號。若為負值,則繪制所有輪廓。
  • color,輪廓顏色。
  • thickness,輪廓線條的粗細程度,有默認值 1。若其為負值,便會填充輪廓內部空間。
  • lineType,線條的類型,有默認值 8。可去類型如下:
類型 含義
8 8 連通線型
4 4 連通線型
LINE_AA 抗鋸齒線型
  • hierarchy,可選的層次結構信息,有默認值 noArray()。
  • maxLevel,用於繪制輪廓的最大等級,有默認值 INT_MAX。
  • offset,輪廓信息相對於目標圖像對應點的偏移量,相當於在每一個輪廓點上加上該偏移量,有默認值 Point() 。在 ROI 區域(感興趣區域)繪制輪廓時,這個參數便可派上用場。

 

代碼示例:

#include<opencv.hpp> #include<iostream> #include<vector>
using namespace std; using namespace cv; int main() { Mat src = imread("C:/Users/齊明洋/Desktop/3.jpg"); imshow("src", src); Mat canny_img; Canny(src, canny_img, 55, 110, 3); //閉操作,先膨脹后腐蝕,可消除小黑點
    Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3)); morphologyEx(canny_img, canny_img, MORPH_CLOSE, kernel); imshow("canny_img", canny_img); Mat dst = Mat(src.rows, src.cols, CV_8UC3, Scalar(0, 0, 0)); vector<vector<Point> >contours; ////寫法一
    //vector<Vec4i>hierarchy; //findContours(canny_img, contours,hierarchy, RETR_TREE, CHAIN_APPROX_NONE); //for (int i = 0; i < contours.size(); i++) { // drawContours(dst, contours, i, Scalar(0, 0, 255), 1, 8, hierarchy); //} //寫法二
 findContours(canny_img, contours, RETR_TREE, CHAIN_APPROX_NONE); drawContours(dst, contours, -1, Scalar(0, 255, 0), 1); imshow("dst", dst); waitKey(0); }

效果演示:

 

借鑒博客:https://www.cnblogs.com/GaloisY/p/11062065.html

https://blog.csdn.net/qq_35239859/article/details/99676501

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM