25、【opencv入门】轮廓查找与绘制(3)——凸包

Stella981
• 阅读 844

一简介

1、凸包

凸包(Convex Hull)是一个计算机几何图形学中的概念, 简单来说, 给定二维平面点集, 凸包就是能够将最外层的点连接起来构成的凸多边形, 它能够包含点集中所有的点。物体的凸包检测场应用在物体识别、手势识别及边界检测等领域。

25、【opencv入门】轮廓查找与绘制(3)——凸包

A-H是被标出的凸包缺陷

2、寻找凸包---convexHull()

1 CV_EXPORTS_W void convexHull(InputArray points, OutputArray hull, bool clockwise=false, bool returnPoints = true);

  points: 输入的二维点集, 可以填Mat类型或std::vector

  hull: 函数调用后找到的凸包

  clockwise: 操作方向标志符, 当为true时, 输出的凸包为顺时针方向, false为逆时针方向(假定坐标系x轴指向右,y轴指向上方)

  returnPoints: 操作标志符, 默认值true. 当标志符为true时, 函数返回凸包各个点, 否则返回凸包各点的指数, 当输出数组是std::vector时, 此标志被忽略

 示例:

1 vector<int> hull;
2 convexHull(Mat(points), hull, true);

1 vector<vector<Point>> hull(contours.size());
2 for(int i = 0; i < contours.size(); i++)
3 {
4     convexHull(Mat(contours[i]), hull[i], true);
5 }

3、凸包缺陷分析---convexityDefects()

1 CV_EXPORTS_W void convexityDefects(InputArray contour, InputArray convexhull, OutputArray convexityDefects);

  contour: 表示输入参数检测到的轮廓, 可以用findContours函数获得

  convexhull: 输入参数表示检测到的凸包, 可以用convexHull函数获得

  convexityDefects: 检测到的最终结果, 应为vector<vector>类型, Vec4i存储了起始点、结束点、距离及最远点到凸包的距离

二、绘制点集的凸包

 1 //绘制点集的凸包
 2 #include<opencv2/opencv.hpp>
 3 
 4 using namespace cv;
 5 
 6 int main()
 7 {
 8     //---绘制点集的凸包
 9     Mat img(400, 400, CV_8UC3, Scalar::all(0));  //定义绘制图像
10     RNG rng;  //定义随机数对象
11     while(1)
12     {
13         char key;
14         int count = (unsigned int)rng % 100;  //定义点的个数  
15         vector<Point> points;  //定义点集
16         for(int i=0; i<count; i++)
17         {
18             Point pt;
19             pt.x = rng.uniform(img.cols/4, img.cols*3/4);  //设定点的x范围
20             pt.y = rng.uniform(img.rows/4, img.rows*3/4);  //设定点的y范围
21             points.push_back(pt);
22         }
23 
24         //检测凸包
25         vector<int> hull;
26         convexHull(Mat(points), hull, true);
27 
28         img = Scalar::all(0);
29         for(int i = 0; i < count; i++ )
30             circle(img, points[i], 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), CV_FILLED, CV_AA);
31 
32         //准备参数
33         int hullcount = (int)hull.size(); //凸包的边数
34         Point point0 = points[hull[hullcount-1]]; //连接凸包边的坐标点
35 
36         //绘制凸包的边
37         for(int  i = 0; i < hullcount; i++ )
38         {
39             Point point = points[hull[i]];
40             circle(img, point, 8, Scalar(0, 255, 0), 2, 8);
41             line(img, point0, point, Scalar(255, 255, 255), 2, CV_AA);
42             point0 = point;
43         }
44 
45         //显示效果图
46         imshow("img", img);
47 
48         //按下ESC,Q,或者q,程序退出
49         key = (char)waitKey();
50         if( key == 27 || key == 'q' || key == 'Q' ) 
51             break;
52     }
53     return 0;
54 }

三、绘制轮廓的凸包

 1 //绘制轮廓的凸包
 2 #include<opencv2/opencv.hpp>
 3 
 4 using namespace cv;
 5 
 6 int main()
 7 {
 8     Mat srcImg = imread("12.jpg");
 9     imshow("src", srcImg);
10     Mat dstImg2 = srcImg.clone();
11     Mat tempImg(srcImg.rows, srcImg.cols, CV_8UC3, Scalar::all(0));  //用于绘制凸包
12     Mat dstImg(srcImg.rows, srcImg.cols, CV_8UC3, Scalar::all(0));  //用于绘制轮廓
13     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
14     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY); //二值化
15     
16     vector<vector<Point>> contours;
17     vector<Vec4i> hierarcy;
18     findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
19     vector<vector<Point>> hull(contours.size());
20     for(int i=0; i<contours.size(); i++)
21     {
22         convexHull(Mat(contours[i]), hull[i], true);     //查找凸包
23         drawContours(dstImg, contours, i, Scalar(255, 255, 255), -1, 8);  //绘制轮廓
24         //drawContours(dstImg, hull, i, Scalar(rand()%255, rand()%255, rand()%255), 2, 8);
25         drawContours(tempImg, hull, i, Scalar(255, 255, 255), -1, 8);
26     }
27     imshow("hull", tempImg);
28     imshow("contours", dstImg);
29 
30     Mat diffImg;
31     absdiff(tempImg, dstImg, diffImg);  //图像相减
32     Mat element = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
33     erode(diffImg, diffImg, element);
34     imshow("diff", diffImg);
35 
36     vector<vector<Point>> contours2;
37     vector<Vec4i> hierarcy2;
38     cvtColor(diffImg, diffImg, CV_BGR2GRAY); //转为灰度图
39     threshold(diffImg, diffImg, 100, 255, CV_THRESH_BINARY); //二值化
40     findContours(diffImg, contours2, hierarcy2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
41     drawContours(dstImg2, contours2, -1, Scalar(0, 0, 255), 2, 8);  //红色绘制缺陷轮廓
42     imshow("defects", dstImg2);
43     waitKey(0);
44     return 0;
45 }
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
ACM计算几何
本文出自:http://blog.csdn.net/svitter(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fblog.csdn.net%2Fsvitter)北大ACM计算几何:线与线求交,线与面求交,求凸包,半平面求交等(https://www.oschin
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Nginx反向代理upstream模块介绍
!(https://oscimg.oschina.net/oscnet/1e67c46e359a4d6c8f36b590a372961f.gif)!(https://oscimg.oschina.net/oscnet/819eda5e7de54c23b54b04cfc00d3206.jpg)1.Nginx反
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这