opencv之 drawContours() 函数说明应用

news2025/2/28 10:21:00

drawContours

之前使用mask图还进行了连通域有无status分析,然后才进行的绘制。
今天发现直接使用mask图进行绘制,然后通过设置drawContours的参数可以进行不同层次上缺陷的绘制,然后通过这个事情也说明,有问题可以直接找opencv官网源码进行查看和分析说明。
方法1:

    cv::RNG rng(12345);
    cv::Mat cc_out;

    std::vector<std::vector<cv::Point>> contours;
    std::vector<cv::Vec4i> hierarcy;
    cv::findContours(mask, contours, hierarcy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
    //绘制全部轮廓,直接绘制全部会很快 9ms 10ms  8ms
//    drawContours(out, contours, -1, cv::Scalar(rng.uniform(0,256), rng.uniform(0, 256), rng.uniform(0, 256)), 2);

    for (int k = 0; k < contours.size(); k++) {
        cv::Scalar colors = cv::Scalar(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
        if (contourArea(contours[k]) < 50)
            continue;
        if(isFilled)
            drawContours(out, contours, k, colors, cv::FILLED, 8, hierarcy);
        else
            drawContours(out, contours, k, colors, 2);
    }

cv::FILLED 第五个参数设置成这个,可以以填充的方式进行绘制缺陷区域。之前是通过遍历整个mask区域然后绘制,不仅慢,而且调用复杂。

在这里插入图片描述

Parameters
image Destination image.
contours All the input contours. Each contour is stored as a point vector.
contourIdx Parameter indicating a contour to draw. If it is negative, all the contours are drawn.
color Color of the contours.
thickness Thickness of lines the contours are drawn with. If it is negative (for example, thickness=FILLED ), the contour interiors are drawn.
lineType Line connectivity. See LineTypes
hierarchy Optional information about hierarchy. It is only needed if you want to draw only some of the contours (see maxLevel ).
maxLevel Maximal level for drawn contours. If it is 0, only the specified contour is drawn. If it is 1, the function draws the contour(s) and all the nested contours. If it is 2, the function draws the contours, all the nested contours, all the nested-to-nested contours, and so on. This parameter is only taken into account when there is hierarchy available.
offset Optional contour shift parameter. Shift all the drawn contours by the specified offset=(dx,dy) .
Note
When thickness=FILLED, the function is designed to handle connected components with holes correctly even when no hierarchy data is provided. This is done by analyzing all the outlines together using even-odd rule. This may give incorrect results if you have a joint collection of separately retrieved contours. In order to solve this problem, you need to call drawContours separately for each sub-group of contours, or iterate over the collection using contourIdx parameter.
百度翻译后:
当厚度=填充时,该函数设计用于正确处理带孔的连接部件,即使未提供层次结构数据。这是通过使用奇偶规则一起分析所有轮廓来完成的。如果您有单独检索的等高线的联合集合,这可能会给出错误的结果。为了解决这个问题,您需要为每个等高线子组分别调用drawContours,或者使用contourIdx参数遍历集合。
其实大致的写法应该就是上述那样,每个轮廓都挑选出来进行一个绘制。

如果进行一个连通域的分析,可以调用如下的代码进行尝试。
注意:使用下述connectedComponentsWithStats代码进行分析时比较费时的,可按需看是否需要。
方法2:

		cv::Mat labels, stats, centroids, img_color;
		int nccomps = cv::connectedComponentsWithStats(rsp_pair.second.mask, labels, stats, centroids);//轮廓个数

		std::cout << "label.size : " << labels.size() << " , nccomps : " << nccomps << std::endl;
		std::vector<cv::Vec3b> colors(nccomps + 1);
		colors[0] = cv::Vec3b(0, 0, 0); // background pixels remain black.
		int area_1 = 0;
		for (int i = 1; i < nccomps; i++) {
			colors[i] = cv::Vec3b(rand() % 256, rand() % 256, rand() % 256);
			std::cout << "area : " << stats.at<int>(i, cv::CC_STAT_AREA) << std::endl;
			area_1 += stats.at<int>(i, cv::CC_STAT_AREA);
			//cv::CC_STAT_AREA更换这个参数可以找出该轮廓的x y width height area 

			int cx = centroids.at<double>(i, 0);
			int cy = centroids.at<double>(i, 1);
			// rectangle and area
			int x = stats.at<int>(i, CC_STAT_LEFT);
			int y = stats.at<int>(i, CC_STAT_TOP);
			int width = stats.at<int>(i, CC_STAT_WIDTH);
			int height = stats.at<int>(i, CC_STAT_HEIGHT);
			int area = stats.at<int>(i, CC_STAT_AREA);
			putText(g_image, format("%d", area), Point(x, y), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 1);

		}


		std::vector<std::vector<cv::Point>> contours;
		std::vector<cv::Vec4i> hierarcy;
		cv::findContours(rsp_pair.second.mask, contours, hierarcy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
		绘制全部轮廓,直接绘制全部会很快 9ms 10ms  8ms
		//drawContours(g_image, contours, -1, cv::Scalar(rng.uniform(0,256), rng.uniform(0, 256), rng.uniform(0, 256)), 2);

		std::cout << "size of contours: " << contours.size() << std::endl;
		for (int k = 0; k < contours.size(); k++) {
			cv::Scalar colors = cv::Scalar(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
			if (contourArea(contours[k]) < 50)
				continue;

			drawContours(g_image, contours, k, colors, FILLED, 8, hierarcy);
		}

另一种通过创建一个同等类型大小,并且全部为0的图然后重新进行绘制,这样会时间更长
方法3:

		//59ms  64ms 61ms
		cv::Mat labels, stats, centroids, img_color;
		int nccomps = cv::connectedComponentsWithStats(rsp_pair.second.mask, labels, stats, centroids);//轮廓个数

		std::cout << "label.size : " << labels.size() << " , nccomps : " << nccomps << std::endl;
		std::vector<cv::Vec3b> colors(nccomps + 1);
		colors[0] = cv::Vec3b(0, 0, 0); // background pixels remain black.
		int area_1 = 0;
		for (int i = 1; i < nccomps; i++) {
			colors[i] = cv::Vec3b(rand() % 256, rand() % 256, rand() % 256);
			std::cout << "area : " << stats.at<int>(i, cv::CC_STAT_AREA) << std::endl;
			area_1 += stats.at<int>(i, cv::CC_STAT_AREA);
			//cv::CC_STAT_AREA更换这个参数可以找出该轮廓的x y width height area 

			int cx = centroids.at<double>(i, 0);
			int cy = centroids.at<double>(i, 1);
			// rectangle and area
			int x = stats.at<int>(i, CC_STAT_LEFT);
			int y = stats.at<int>(i, CC_STAT_TOP);
			int width = stats.at<int>(i, CC_STAT_WIDTH);
			int height = stats.at<int>(i, CC_STAT_HEIGHT);
			int area = stats.at<int>(i, CC_STAT_AREA);
			putText(g_image, format("%d", area), Point(x, y), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 1);

		}


		for (int i = 0; i < rsp_pair.second.mask.rows; i++)
			for (int j = 0; j < rsp_pair.second.mask.cols; j++)
			{
				int label = labels.at<int>(i, j);
				if (label >= 1 && nccomps > 0)
				{
					//label表示当前像素第几个轮廓
					//tmp.mask.at<cv::Vec3b>(i, j) = colors[label];
					g_image.at<cv::Vec3b>(i, j) = colors[label];
				}
			}

这种其实就是写法的稍微不一样点,和方法1基本上一样,除了带上了一个连通域分析,但是耗时都差不多的。
方法4:

		cv::Mat cc_out;
		int cc_num = cv::connectedComponents(rsp_pair.second.mask, cc_out, 8);
		std::cout << "cc_num : " << cc_num << std::endl;
	
		Mat dst = Mat::zeros(cc_out.rows, cc_out.cols, CV_8UC3);
		vector<vector<Point> > contours;
		vector<Vec4i> hierarchy;
		findContours(cc_out, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
		// iterate through all the top-level contours,
		// draw each connected component with its own random color
		int idx = 0;
		for (; idx >= 0; idx = hierarchy[idx][0])
		{
			Scalar color(rand() & 255, rand() & 255, rand() & 255);
			//drawContours(g_image, contours, idx, color, FILLED, 8, hierarchy);
			drawContours(g_image, contours, idx, color, 2);
		}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/9518.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“综合”web项目编写------手把手0基础教学(一)

我们平常看到的项目代码一般都是分段单独的功能&#xff0c;但如何将功能汇总成一个完整的项目呢&#xff0c;下面我将利用IDEA来介绍一个基础的综合web项目 目录 一.创建项目 二.为项目建包 1.了解构建项目的思路 &#xff08;1&#xff09;构建模型&#xff08;模型包括数…

集线器与交换机、虚拟局域网(3.3)

集线器与交换机 传输门&#xff1a;b站湖科大教书匠 集线器 使用集线器的以太网或者局域网其实本质还是一个总线网 工作方式 集线器只工作在物理层&#xff0c;每个接口仅仅用来转发比特&#xff0c;不进行碰撞检测&#xff08;不使用CSMA/CD协议&#xff09;&#xff0c;由…

如何自定义代码生成器(上)

1 概述 1.1 介绍 ​ 在项目开发过程中&#xff0c;有很多业务模块的代码是具有一定规律性的&#xff0c;例如controller控制器、service接口、service实现类、mapper接口、model实体类等等&#xff0c;这部分代码可以使用代码生成器生成&#xff0c;我们就可以将更多的时间放…

深度学习中激活函数的用途

深度学习中激活函数的概念 激活函数&#xff0c;即Activation Function,有时候也称作激励函数。它是为了解决线性不可分的问题引出的。但是也不是说线性可分就不能用激活函数&#xff0c;也是可以的。它的目的是为了使数据更好的展现出我们想要的效果。激活函数是一种非线性的…

SAP UI5 SmartTable 控件本地运行时进行 Excel 导出的单步调试

点击 SmartTable 控件生成的表格控件的 Export to Excel 时&#xff0c;遇到如下错误消息&#xff1a; The following error has occurred during export: Unexpected server response: SmartTable 基于的是 OData V4 的模型了&#xff1a; Excel export 操作&#xff0c;触发的…

接口(上)

&#x1f437;1.接口的概念 &#x1f431;‍&#x1f680;2.接口的语法规则 &#x1f49a;3.接口的使用 &#x1f680;4.接口的特性 &#x1f386;5.实现多个接口 &#x1f436;6.接口间的继承 &#x1f38a;7.接口使用的实例 1.什么是接口呢&#xff1f;&#xff1f;&a…

【https】lighttpd增加https支持及openssl生成CA(Certificate Authority)和使用CA来制作签名证书操作说明

环境说明 ubuntu18.04.1、openssl指令需要支持 openssl生成CA&#xff08;Certificate Authority&#xff09; 生成RSA Private Key openssl genrsa -out ca.key 输出信息 $ openssl genrsa -out ca.key Generating RSA private key, 2048 bit long modulus (2 primes) ...…

Scala008--Scala中的数据结构【集合】

目录 一&#xff0c;概述 二&#xff0c;set的声明 1,不可变set集合 1)向不可变集合中添加元素 【需要新的set集合接收】 2&#xff09;对两个set集合进行合并 【需要新的set集合接收】 2&#xff0c;不可变的HashSet集合 2&#xff0c;可变HashSet集合 1&…

http-only原理与防御XSS实践

目录预备知识XSS攻击实验目的实验环境实验步骤一触发XSS漏洞实验步骤二引入Http-only实验步骤三验证http–only在防御XSS攻击时的作用预备知识 XSS攻击 http-only的设计主要是用来防御XSS攻击&#xff0c;所以学习本实验的读者应首先了解XSS攻击的相关原理内容。 跨站点脚本攻…

Vue 2 如何添加 register-service-worker 以实现缓存请求的目的

Vue 2 如何添加 register-service-worker 以实现缓存请求的目的 一、问题描述 现在 vue 3 的模板中是自带 register-service-worker 的。 用这个的好处是&#xff0c;它会自动将项目中的所有文件请求缓存到 service-worker 中&#xff0c;以实现再次打开网站的时候会非常非常…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java校园二手物品交易系统051x4

做毕业设计一定要选好题目。毕设想简单&#xff0c;其实很简单。这里给几点建议&#xff1a; 1&#xff1a;首先&#xff0c;学会收集整理&#xff0c;年年专业都一样&#xff0c;岁岁毕业人不同。很多人在做毕业设计的时候&#xff0c;都犯了一个错误&#xff0c;那就是不借鉴…

HTB-Tier1

HTB-Tier1 Appointment Task 1 What does the acronym SQL stand for? ********** ***** *******e Structured Query Language Hide Answer Task 2 What is one of the most common type of SQL vulnerabilities? *** ********n sql injection Hide Answer Task …

汉字风格迁移篇----EasyFont:一个基于风格学习的系统,可以轻松构建大规模手写字体

文章目录abstract1 INTRODUCTION2 RELATED WORK3 METHOD DESCRIPTION3.1 Selecting Input Character Set3.2 Learning Font Skeleton Manifold3.2.1 Character Matching.3.2.2 Training the GP-LVM3.3 Text Segmentation3.4 Stroke Extraction3.5 Overall Style Learning3.5.1 …

UNet - 数据加载 Dataset

目录 1. 介绍 2. 数据处理 dataset 2.1 预处理 2.2 加载数据 2.2.1 初始化 2.2.2 返回数据 2.2.3 样本数量 3. 测试一下 4. 完整代码 1. 介绍 之前介绍完了Unet网络的搭建&#xff0c;接下来说一下要解决的任务。 本章介绍的是&#xff1a;数据的加载处理 下面是整…

hadoop 3.3大数据集群搭建系列1-安装hadoop

文章目录一. 软硬件配置1.1 主机配置及规划1.2 软件配置1.3 安装常用的工具二. 安装前准备2.1 设置主机名2.2 设置hosts2.3 关闭防火墙2.4 ssh免密登陆2.5 ntpdate时间同步三. 安装3.1 安装hadoop3.1.1 下载hadoop并解压3.1.2 配置hadoop_home环境变量3.1.3 编辑etc/hadoop/had…

【毕业设计】图像识别垃圾分类系统 - python 深度学习

文章目录0 前言1 简介2 识别效果3 实现3.1 数据集3.2 实现原理和方法3.3 网络结构4 最后0 前言 &#x1f525; Hi&#xff0c;大家好&#xff0c;这里是丹成学长的毕设系列文章&#xff01; &#x1f525; 对毕设有任何疑问都可以问学长哦! 这两年开始&#xff0c;各个学校对…

信息熵,交叉熵,KL散度,互信息一网打尽

talk 一直以来都是自己有时候 想去搞明白就搜搜博客看&#xff0c;模棱两可&#xff0c;记忆也比较模糊&#xff0c;这次直接较为系统的记录一下&#xff0c;之后忘了也能看看~ 1. 信息熵 这个概念是从信息论出现的&#xff0c;是香农定义的&#xff0c;根据事件发生的概率进…

excel怎么设置密码?加密文件这么做!

我们都知道&#xff0c;很多时候需要我们在电脑上保存很多excel文件。为了避免在工作中出现意外&#xff0c;我们需要在文件中设置一个安全密码。那么&#xff0c;电子表格excel怎么设置密码呢&#xff1f;如果我们设置了密码&#xff0c;想要取消原本的密码或者重新设置一个密…

Windows无法启动这个硬件设备(代码19)怎么办?

在我们使用电脑的过程中&#xff0c;遇到“由于其配置信息(注册表中的)不完整或已损坏&#xff0c;Windows无法启动这个硬件设备&#xff08;代码19&#xff09;”的提示时该如何解决呢&#xff1f; Windows无法启动这个硬件设备&#xff08;代码19&#xff09;&#xff0c;如何…

干货整理| 深度学习入门知识

一、深度学习的定义 深度学习&#xff08;Deep Learning&#xff09;&#xff0c;简称&#xff1a;DL&#xff0c;是一种实现机器学习的技术。 人工智能&#xff08;AI&#xff09;的概念是在1955 年提出的&#xff1b;机器学习&#xff08;ML&#xff09;概念是在1990 年提出…