• 【OpenCV】-查找并绘制轮廓



    1 寻找轮廓:findContours()函数

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

    void findContours(InputArray image,OutArrayofArray contours,OutputArray hierarchy,int mode,int method,Point offset=Point())
    
    • 1
    • 第一个参数:输入图像,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())
    
    • 1
    • 第一个参数:目标图像

    • 第二个参数:所有的输入轮廓。每个轮廓存储一个点向量,即用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,还有一定要加上using namespace std。
     2、变量声明:
    (1) 例:声明一个int向量以替代一维的数组:vector  a;(等于声明了一个int数组a[],大小没有指定,可以动态的向里面添加删除)。
    (2)例:用vector代替二维数组.其实只要声明一个一维数组向量即可,而一个数组的名字其实代表的是它的首地址,所以只要声明一个地址的向量即可,即:vector  a。同理想用向量代替三维数组也是一样,vector a。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3 示例程序

    #include
    #include
    #include
    #include
    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    绘制内轮廓:

    	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);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

  • 相关阅读:
    Docker监控方案(TIG)的研究与实践之Influxdb
    SQL注入
    每个设计师都应该有的五个性格,你具备几个?
    CentOS 7 防火墙
    基于关联规则的多样化推荐技术应用研究
    joomscan工具使用(针对joomla扫描)
    Vue.js 加入高德地图的实现方法
    Go基础面经大全(持续补充中)
    nodejs+vue 校园通勤车-计算机毕业设计
    数据仓库为什么要分层建设?每一层的作用是什么?
  • 原文地址:https://blog.csdn.net/qq_44859533/article/details/126211268