OpenCV-寻找轮廓cv::findContours&绘制轮廓cv::drawContours

Posted 翟大宝Steven

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV-寻找轮廓cv::findContours&绘制轮廓cv::drawContours相关的知识,希望对你有一定的参考价值。

函数原型

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

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() );

参数说明

       findContours:

  1. InputArray类型的image,输入图像,需是8位单通道图像。非零像素视为1,0像素为0,二进制表示。
  2. OutputArrayOfArrays类型的contours,检测到的轮廓结果存放在此,每个轮廓存储为一个点向量,用point类型的vetor表示。
  3. OutputArray类型的hierarchy,可选的输出向量,包含图像的拓扑信息。其作为轮廓数量的表示,包括多个元素。每个轮廓contours[i]有4个hierarchy元素——hierarchy[i][0]~hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,对应值设为负数。
  4. int类型的mode,轮廓检索模式。RETR_EXTERNAL表示只检测最外围轮廓;RETR_LIST表示提取所有轮廓并放置在list中,无等级关系;RETR_CCOMP表示提取所有轮廓,并将其组织为双层结构;RETR_TREE表示提取所有轮廓,并重新建立网状的轮廓结构。
  5. int类型的method,轮廓近似方法。CHAIN_APPROX_NONE表示获取每个轮廓的每个像素;CHAIN_APPROX_SIMPLE表示压缩水平方向、垂直方向、对角方向的元素,只保留该方向的终点坐标;CHAIN_APPROX_TC89_L1和CHAIN_APPROX_TC89——KCOS表示Teh-Chinl链逼近算法。
  6. Point类型的offset,每个轮廓点的可选偏移量。

       drawContours:

  1. InputArray类型的image,输入图像。
  2. OutputArrayOfArrays类型的contours,检测到的轮廓结果存放在此,每个轮廓存储为一个点向量,用point类型的vetor表示。
  3. int类型的contourIdx,轮廓绘制的指示变量。如果其为负值,则绘制所有轮廓。
  4. const Scalar&类型的color,轮廓的颜色。
  5. int类型的thickness,轮廓线条的粗细度,有默认值1。如果其为负值,则会绘制在轮廓的内部。可选为FILLED。
  6. int类型的lineType,线条的类型,默认值为8。可取8(8连通线型)、4、LINE_AA(抗锯齿线型)。
  7. InputArray类型的hierarchy,可选的层次结构信息。
  8. int类型的maxLevel,表示用于绘制轮廓的最大等级,默认为INT_MAX。
  9. Point类型的offset,可选的轮廓偏移参数。

测试代码

#include<iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<ctime>
using namespace std;
using namespace cv;
int main(void)
{
	// 输入测试图片
	Mat in = imread("tangsan.jpg", 0);
	imshow("original", in);

	// 初始化结果矩阵
	Mat out = Mat::zeros(in.size(), in.type());
	Mat temp= Mat::zeros(in.size(), in.type());

	// 阈值计算,最大类间方差法
	threshold(in, temp, 0, 255, cv::THRESH_OTSU);      
	imshow("thresh", temp);

	// 寻找轮廓
	vector<vector<Point>> contour;
	vector<Vec4i> hierarchy;
	// RETR_TREE以网状结构提取所有轮廓,CHAIN_APPROX_NONE获取轮廓的每个像素
	findContours(temp, contour, hierarchy, RETR_TREE, CHAIN_APPROX_NONE);

	// 随机选择一个颜色,并绘制轮廓
	Scalar color( rand() % 255, rand() % 255, rand() % 255);
	drawContours(out, contour, -1,color, FILLED, 8, hierarchy);
	imshow("result", out);

	waitKey(0);
	system("pause");
	return 0;
}

测试效果

图1 效果图

       不难看出,轮廓结果图中间少了些东西,这是因为提取轮廓选用的是最外圈提取法,外圈轮廓的内嵌轮廓都被清除了~

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

以上是关于OpenCV-寻找轮廓cv::findContours&绘制轮廓cv::drawContours的主要内容,如果未能解决你的问题,请参考以下文章

youcans 的 OpenCV 例程200篇194.寻找图像轮廓(cv.findContours)

使用Python,OpenCV沿着轮廓寻找极值点

使用Python,OpenCV沿着轮廓寻找极值点

计算机视觉OpenCV篇 - 轮廓(寻找/绘制轮廓)

OpenCV寻找复杂背景下物体的轮廓

OpenCV-寻找轮廓cv::findContours&绘制轮廓cv::drawContours