opencv之 drawContours() 函数说明应用

这篇具有很好参考价值的文章主要介绍了opencv之 drawContours() 函数说明应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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区域然后绘制,不仅慢,而且调用复杂。

opencv之 drawContours() 函数说明应用

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:文章来源地址https://www.toymoban.com/news/detail-455715.html

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

到了这里,关于opencv之 drawContours() 函数说明应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 我在Vscode学OpenCV 图像处理四(轮廓查找 cv2.findContours() cv2.drawContours())-- 待补充

    在OpenCV中,边缘检测和轮廓查找是两个不同的图像处理任务,它们有不同的目标和应用。 1.1.1 边缘检测: 定义: 边缘检测是指寻找图像中灰度级别变化明显的地方,即图像中物体之间的界限。这些变化通常表示图像中的边缘或轮廓。 方法: 常用的边缘检测算法包括Sobel、

    2024年02月03日
    浏览(61)
  • 入门指南:深入解析OpenCV的copyTo函数及其与rect的应用场景

    OpenCV是一个功能强大的开源计算机视觉库,广泛应用于图像处理和计算机视觉任务。在OpenCV中,copyTo函数是一个重要的图像处理函数,它允许我们在不同的图像之间复制像素数据,同时结合rect(矩形)的使用,可以实现更多有趣的功能。本文将深入讲解copyTo函数的用法,并提

    2024年02月15日
    浏览(44)
  • 【Python从入门到人工智能】16个必会的Python内置函数(4)——数据转换与计算 (详细语法参考+参数说明+具体示例) | 求和、四舍五入、幂运算的综合应用

      成长的标准就是,拒绝别人以后,没有任何的愧疚感。——萨特     🎯作者主页: 追光者♂🔥          🌸个人简介:   💖[1] 计算机专业硕士研究生💖   🌟[2] 2022年度博客之星人工智能领域TOP4🌟   🏅[3] 阿里云社区特邀专家博主🏅   🏆[4] CSDN-人工智能领域优质

    2024年02月15日
    浏览(74)
  • OpenCV函数应用:基于二值图像的三种孔洞填充方法记录(附python,C++代码)

    函数系列: OpenCV函数简记_第一章数字图像的基本概念(邻域,连通,色彩空间) OpenCV函数简记_第二章数字图像的基本操作(图像读写,图像像素获取,图像ROI获取,图像混合,图形绘制) OpenCV函数简记_第三章数字图像的滤波处理(方框,均值,高斯,中值和双边滤波) OpenC

    2024年02月05日
    浏览(54)
  • OpenCV中的normalize函数以及NORM_MINMAX、NORM_INF、NORM_L1、NORM_L2具体应用介绍

    在OpenCV中,normalize函数用于将图像或矩阵的值规范化到一个特定的范围内。这在图像处理中非常有用,比如在调整图像的对比度、准备数据进行机器学习处理时。规范化可以提高不同图像之间的可比性,或是为了满足特定算法对数据范围的要求。 src:输入数组(可以是图像)

    2024年02月22日
    浏览(46)
  • cv2.drawContours的参数

    cv2.drawContours() 函数有以下参数: image:输入图像,一般是二值图像或彩色图像; contours:要绘制的轮廓,是一个 Python 列表,每个列表元素都是一个 Numpy 数组,代表一个轮廓; contourIdx:要绘制的轮廓的索引,默认为 -1,代表绘制所有轮廓; color:轮廓的颜色,是一个三元组

    2024年02月14日
    浏览(78)
  • 关于opencv无损保存图片的说明

    结论: 选择无损压缩格式(如.png)就能无损保存图片,可选压缩程度 选择有损压缩格式(如.jpg)只能有损保存图片,可选损失程度 opencv使用函数 cv2.imwrite() 用于将图像保存到指定的文件 函数说明: cv2.imwrite() 将 OpenCV 图像保存到指定的文件。 cv2.imwrite() 基于保存文件的扩

    2024年02月06日
    浏览(46)
  • 相机的畸变矫正与opencv代码说明

    图像算法中会经常用到摄像机的畸变校正,有必要总结分析OpenCV中畸变校正方法,其中包括普通针孔相机模型和鱼眼相机模型fisheye两种畸变校正方法。普通相机模型畸变校正函数针对OpenCV中的cv::initUndistortRectifyMap(),鱼眼相机模型畸变校正函数对应OpenCV中的cv::fisheye::initUndi

    2024年02月14日
    浏览(42)
  • PyTorch中view()函数用法说明

    首先,view( ) 是对 PyTorch 中的 Tensor 操作的,若非 Tensor 类型,可使用 data = torch.tensor(data)来进行转换。 (1) 作用:该函数返回一个有相同数据但不同维度大小的 Tensor。也就是说该函数的功能是改变矩阵维度,相当于 Numpy 中的 resize() 或者 Tensorflow 中的 reshape() 。 (2) 参数:view

    2024年04月09日
    浏览(39)
  • eval()函数功能介绍及弊端说明

    eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。 eval(string) string 必需,要计算的字符串,其中含有要计算的 JavaScript 表达式或要执行的语句。 返回值:返回计算string的值,如果有的话 (没有则不做任何改变返回) eval(“x=10;y=20;document.write(x*y)”); //output为200 d

    2024年02月10日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包