【OpenCV】-查找并绘制轮廓


1 寻找轮廓:findContours()函数

说明:findContours()函数是在二值图像中寻找轮廓

void findContours(InputArray image,OutArrayofArray contours,OutputArray hierarchy,int mode,int method,Point offset=Point())
  • 第一个参数:输入图像,Mat类的二值图像。可以使用compare()、inrange()、threshold()、adaptivethreshold()、canny()等函数把灰度图或者彩色图创建成二值图。

  • 第二个参数:OutArrayofArray类型的contours,检测到的轮廓、函数调用后的运算结果存在这里。每个轮廓存储为一个点向量

  • 第三个参数:输出向量,包含图像的拓扑信息。其作为轮廓数量的表示,包含了许多元素。每个轮廓contours[i]对应4个hierarchy元素:hierarchy[i] [0]~ hierarchy[i] [3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果没有对应项,对应的hierarchy[i]值设为负数

  • 第四个参数:轮廓检索模式
    在这里插入图片描述

  • 第五个参数:int类型的method,为轮廓的近似办法
    在这里插入图片描述

  • 第六个参数:Point类型的offset,每个轮廓点的可选偏移量,有默认值Point()。对ROI图像中找出的轮廓,并要在整个图像中进行分析时,这个参数便可有用

2 绘制轮廓:drawContours()函数

说明:drawContours()函数用于在图像中绘制外部或内部轮廓

void drawContours(InputOutputArray image,InputArrayOfArrays contours,int contourIdx,const Scalar & color,int thickness=1,int lineType=8,InputArrayhierarchy=noArray(),int maxLevel=INT_MAX,Point offset=Point())
  • 第一个参数:目标图像

  • 第二个参数:所有的输入轮廓。每个轮廓存储一个点向量,即用Point类型的vector表示

  • 第三个参数:int 类型的contourIdx,轮廓绘制的指示变量。如果为负数,则绘制所有轮廓

  • 第四个参数:轮廓颜色

  • 第五个参数:int thickness,轮廓线条的粗细度,默认值1.如果为负数值(如thickness=cv_filled),便绘制在轮廓的内部

  • 第六个参数:线条的类型,默认值8
    在这里插入图片描述

  • 第七个参数:可选的层次结构信息,默认值noArray()

  • 第八个参数:int类型的maxLevel,表示用于绘制轮廓的最大等级,有默认值INT_MAX

  • 第九个参数:Point类型的offset,可选的轮廓偏移参数,用指定的偏移量offset=(dx,dy)偏移需要绘制的轮廓。默认值Point()

补充:

opencv中vector类的用法:
 1、文件包含:     
首先在程序开头处加上#include<vector>以包含所需要的类文件vector,还有一定要加上using namespace std。
 2、变量声明:
(1) 例:声明一个int向量以替代一维的数组:vector <int> a;(等于声明了一个int数组a[],大小没有指定,可以动态的向里面添加删除)。
(2)例:用vector代替二维数组.其实只要声明一个一维数组向量即可,而一个数组的名字其实代表的是它的首地址,所以只要声明一个地址的向量即可,即:vector <int *> a。同理想用向量代替三维数组也是一样,vector <int**>a。

3 示例程序

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
    
    
	Mat srcImage = imread("E:\\Pec\\lunk.jpg", 0);
	imshow("【原始图】", srcImage);
	//初始化结果图
	Mat dstImage = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3);
	//srcImage取大于阈值119的部分,取二值图
	srcImage = srcImage > 190;
	imshow("【取阈值后的原始图】", srcImage);
	//定义轮廓和层次结构
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	//查找轮廓
	findContours(srcImage, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);
	//遍历所有顶层的轮廓,以随机颜色绘制出每个连接组件颜色
	int index = 0;
	for (; index >= 0; index = hierarchy[index][0])
	{
    
    
		Scalar color(rand() % 255, rand() % 255, rand() % 255);
		//Scalar color(0, 255, 0);
		//外轮廓
		drawContours(dstImage, contours, index, color, 2, 8, hierarchy);
	}
	imshow("【轮廓图】", dstImage);	
	waitKey(0);
}

在这里插入图片描述

绘制内轮廓:

	for (; index >= 0; index = hierarchy[index][0])
	{
    
    
		Scalar color(rand() % 255, rand() % 255, rand() % 255);
		//Scalar color(0, 255, 0);
		//内轮廓
		drawContours(dstImage, contours, index, color, FILLED, 8, hierarchy);
	}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44859533/article/details/126211268