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

一简介

1、凸包

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

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>>类型, 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("E://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 }

原文地址:https://www.cnblogs.com/Long-w/p/9668271.html

时间: 2024-08-10 00:38:34

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

opencv学习之路(25)、轮廓查找与绘制(四)——正外接矩形

一.简介 二.外接矩形的查找绘制 1 #include "opencv2/opencv.hpp" 2 using namespace cv; 3 void main() 4 { 5 //外接矩形的查找绘制 6 Mat srcImg =imread("E://12.jpg"); 7 imshow("src",srcImg); 8 Mat dstImg = srcImg.clone(); //原图备份 9 cvtColor(srcImg, srcIm

26、【opencv入门】轮廓查找与绘制(4)——正外接矩形

一.简介 1.使用特定形状的轮廓包围 在实际应用中, 经常会有将检测到的轮廓用多边形表示出来的需求, 提取包围轮廓的多边形也方便我们做进一步分析, 轮廓包围主要有一下几种: 轮廓外接矩形.轮廓最小外接矩形(旋转).轮廓最小包围圆形.轮廓拟合椭圆.轮廓逼近多边形曲线 2.轮廓外接矩形 --- boundingRect() 1 CV_EXPORTS_W Rect boundingRect(InputArray points); points: 输入的二维点集, 可以填Mat类型或std::vecto

30、【opencv入门】轮廓查找与绘制(8)——轮廓特征属性及应用

一.简介 1.HSV颜色空间(hue色调,saturation饱和度,value亮度) HSV颜色空间与人眼所看色彩较接近, 故常用于颜色检测与识别.其中H(色调).S(饱和度).V(亮度) H---不同的颜色(红色/绿色/蓝色)---范围: 0~360 S---颜色深浅(浅红/深红)---范围: 0.0~1.0 V---颜色亮暗(暗红/亮红)---范围: 0.0~1.0 OpenCV默认的HSV范围分别是: H: 0~180,  S: 0~255,  V: 0~255 2.相关知识点 颜色空间

opencv学习之路(24)、轮廓查找与绘制(三)——凸包

一.简介 二.绘制点集的凸包 1 #include<opencv2/opencv.hpp> 2 using namespace cv; 3 4 void main() 5 { 6 //---绘制点集的凸包 7 Mat img(400, 400, CV_8UC3, Scalar::all(0)); //定义绘制图像 8 RNG rng; //定义随机数对象 9 while(1) 10 { 11 char key; 12 int count = (unsigned int)rng % 100; /

opencv学习之路(27)、轮廓查找与绘制(六)——外接圆

一.最小外接圆 1 #include "opencv2/opencv.hpp" 2 #include<iostream> 3 using namespace std; 4 using namespace cv; 5 6 void main() { 7 Mat srcImg = imread("E://10.png"); 8 imshow("src", srcImg); 9 Mat dstImg = srcImg.clone(); 10

opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形

一.简介 二.轮廓最小外接矩形的绘制 1 #include "opencv2/opencv.hpp" 2 using namespace cv; 3 4 void main() 5 { 6 //轮廓最小外接矩形的绘制 7 Mat srcImg = imread("E://00.png"); 8 Mat dstImg = srcImg.clone(); 9 cvtColor(srcImg, srcImg, CV_BGR2GRAY); 10 threshold(srcI

查找并绘制轮廓

1 寻找轮廓:findContours()函数 void findContours(InputOutputArray image,OutputArrayOfArrays contours,OutputArray hierarchy,int mode,int method,Point offset=Point()) 2 绘制轮廓:drawContours()函数 void drawContours(InputOutputArray image,InoutArrayOfArrays contours

[转载]转载,opencv轮廓查找,匹配以及特征提取,实例

已有 9450 次阅读 2012-3-15 20:50 |系统分类:科研笔记|关键词:opencv 轮廓 轮廓的查找.表达.绘制.特性及匹配(How to Use Contour? Find, Component, Construct, Features & Match) 作者:王先荣 前言    轮廓是构成任何一个形状的边界或外形线.前面讲了如何根据色彩及色彩的分布(直方图对比和模板匹配)来进行匹配,现在我们来看看如何利用物体的轮廓.包括以下内容:轮廓的查找.表达方式.组织方式.绘制.特性.匹

【OpenCV入门指南】第六篇 轮廓检测 下

<OpenCV入门指南>系列文章地址:http://blog.csdn.net/morewindows/article/category/863841 上一篇<[OpenCV入门指南]第五篇轮廓检测上>介绍了cvFindContours函数和cvDrawContours函数,并作了一个简单的使用示范.本篇将展示一个实例,让大家对轮廓检测有个更加深入的认识. 代码如下: //图像的轮廓检测下 //By MoreWindows (http://blog.csdn.net/MoreWin