1、提取轮廓的凸包
CONVEXHULL()函数(点我看OPENCV3.2帮助文档)
函数调用形式:
void convexhul(InputArray points,OutputArray hull,bool clockwise=false,bool returnPoints=true)
输入:
第一个参数是要求凸包的点集
第二个参数是输出的凸包点,可以为vector,此时返回的是凸包点在原轮廓点集中的索引,也可以为vector,此时存放的是凸包点的位置
第三个参数是一个bool变量,表示求得的凸包是顺时针方向还是逆时针方向,true是顺时针方向。
第四个参数,第二个参数的返回类型是vector还是vector,可以忽略
示例:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<iostream> 3 #include<vector> 4 #include<opencv2/opencv.hpp> 5 6 using namespace cv; 7 using namespace std; 8 9 int main() 10 { 11 Mat srcImage(Size(500, 500), CV_8UC3, Scalar(0)); 12 13 // 随机类RNG,默认的构造函数初始化为固定的值,随机“种子”也是固定的,还有一个带参数的构造函数,你可以指定“种子”, 14 // 用系统时间来指定,以确保每次执行都是“不同的种子” 从而得到不同的随机序列 15 RNG rng((unsigned)time(NULL)); 16 17 char key; 18 while (1) 19 { 20 //随机生成一些点 21 //首先就是随机生成点的总数量 22 int g_nPointCount = rng.uniform(10, 30); 23 //接下来就是随机生成一些点的坐标 24 vector<Point> points; 25 for (int i = 0; i < g_nPointCount; i++) 26 { 27 Point midPoint; 28 29 midPoint.x = rng.uniform(srcImage.cols / 4, srcImage.cols * 3 / 4); 30 midPoint.y = rng.uniform(srcImage.rows / 4, srcImage.rows * 3 / 4); 31 32 points.push_back(midPoint); 33 } 34 35 //显示刚刚随机生成的那些点 36 for (int i = 0; i < g_nPointCount; i++) 37 { 38 circle(srcImage, points[i], 0, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); 39 } 40 41 //计算凸包 42 vector<int> hull; 43 convexHull(Mat(points), hull, true); 44 //绘制凸包 45 int hullcount = (int)hull.size(); 46 Point pt0 = points[hull[hullcount - 1]]; 47 for (int i = 0;i < hullcount;i++) 48 { 49 Point pt = points[hull[i]]; 50 line(srcImage, pt0, pt, Scalar(0, 255, 0), 1, LINE_AA); 51 pt0 = pt; 52 } 53 54 imshow("效果图", srcImage); 55 56 key = waitKey(); 57 if (key == 27) 58 break; 59 else 60 srcImage = Scalar::all(0); 61 } 62 63 return 0; 64 }
效果:
2、提取轮廓的外包矩形
BOUNDINGRECT()函数(点我看OPENCV3.2帮助文档)
函数作用:
计算轮廓的外包矩形,矩形是与图像上下边界平行的
函数调用形式:
Rect boundingRect(InputArray points)
输入:二维点集,点的序列或向量 (Mat)
返回:Rect
示例:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<iostream> 3 #include<vector> 4 #include<opencv2/opencv.hpp> 5 6 using namespace cv; 7 using namespace std; 8 9 int main() 10 { 11 Mat srcImage(Size(500, 500), CV_8UC3, Scalar(0)); 12 13 // 随机类RNG,默认的构造函数初始化为固定的值,随机“种子”也是固定的,还有一个带参数的构造函数,你可以指定“种子”, 14 // 用系统时间来指定,以确保每次执行都是“不同的种子” 从而得到不同的随机序列 15 RNG rng((unsigned)time(NULL)); 16 17 char key; 18 while (1) 19 { 20 //随机生成一些点 21 //首先就是随机生成点的总数量 22 int g_nPointCount = rng.uniform(10, 30); 23 //接下来就是随机生成一些点的坐标 24 vector<Point> points; 25 for (int i = 0; i < g_nPointCount; i++) 26 { 27 Point midPoint; 28 29 midPoint.x = rng.uniform(srcImage.cols / 4, srcImage.cols * 3 / 4); 30 midPoint.y = rng.uniform(srcImage.rows / 4, srcImage.rows * 3 / 4); 31 32 points.push_back(midPoint); 33 } 34 35 //显示刚刚随机生成的那些点 36 for (int i = 0; i < g_nPointCount; i++) 37 { 38 circle(srcImage, points[i], 0, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); 39 } 40 //寻找外包矩阵 41 Rect maxRect = boundingRect(points); 42 //绘制外包矩阵 43 rectangle(srcImage, maxRect, Scalar(0, 255, 0)); 44 45 imshow("效果图", srcImage); 46 47 key = waitKey(); 48 if (key == 27) 49 break; 50 else 51 srcImage = Scalar::all(0); 52 } 53 54 return 0; 55 }
效果图:
3、提取轮廓的最小外包矩形
MINAREARECT()函数(点我看OPENCV3帮助文档)
函数作用:
主要求得包含点集最小面积的矩形,这个矩形是可以有偏转角度的,可以与图像的边界不平行
函数调用形式:
RotatedRect minAreaRect(InputArray points)
输入:二维点集,点的序列或向量 (Mat)
返回:RotatedRect
示例:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<iostream> 3 #include<vector> 4 #include<opencv2/opencv.hpp> 5 6 using namespace cv; 7 using namespace std; 8 9 int main() 10 { 11 Mat srcImage(Size(500, 500), CV_8UC3, Scalar(0)); 12 13 // 随机类RNG,默认的构造函数初始化为固定的值,随机“种子”也是固定的,还有一个带参数的构造函数,你可以指定“种子”, 14 // 用系统时间来指定,以确保每次执行都是“不同的种子” 从而得到不同的随机序列 15 RNG rng((unsigned)time(NULL)); 16 17 char key; 18 while (1) 19 { 20 //随机生成一些点 21 //首先就是随机生成点的总数量 22 int g_nPointCount = rng.uniform(10, 30); 23 //接下来就是随机生成一些点的坐标 24 vector<Point> points; 25 for (int i = 0; i < g_nPointCount; i++) 26 { 27 Point midPoint; 28 29 midPoint.x = rng.uniform(srcImage.cols / 4, srcImage.cols * 3 / 4); 30 midPoint.y = rng.uniform(srcImage.rows / 4, srcImage.rows * 3 / 4); 31 32 points.push_back(midPoint); 33 } 34 35 //显示刚刚随机生成的那些点 36 for (int i = 0; i < g_nPointCount; i++) 37 { 38 circle(srcImage, points[i], 0, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); 39 } 40 41 //寻找最小外包矩形 42 RotatedRect minRect = minAreaRect(points); 43 44 Point2f fourPoint2f[4]; 45 //将minRect的四个顶点坐标值放到fourPoint的数组中 46 minRect.points(fourPoint2f); 47 48 //根据得到的四个点的坐标 绘制矩形 49 for (int i = 0; i < 3; i++) 50 { 51 line(srcImage, fourPoint2f[i], fourPoint2f[i + 1], Scalar(0,0,255), 3); 52 } 53 line(srcImage, fourPoint2f[0], fourPoint2f[3], Scalar(0, 0, 255), 3); 54 55 imshow("效果图", srcImage); 56 57 key = waitKey(); 58 if (key == 27) 59 break; 60 else 61 srcImage = Scalar::all(0); 62 } 63 64 return 0; 65 }
效果图:
ROTATEDRECT类的详解,参见我另一篇博客:【OPENCV3学习笔记】ROTATEDRECT类 详解
4、提取轮廓的最小外包圆
minEnclosingcircle()(点我看OpenCV3帮助文档)
函数调用形式:
void minEnclosingcircle(InputArray points,Point2f& center,float& radius)
输入:二维点集,点的序列vector< point >或向量 (Mat) ,圆心坐标,半径
示例:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<iostream> 3 #include<vector> 4 #include<opencv2/opencv.hpp> 5 6 using namespace cv; 7 using namespace std; 8 9 int main() 10 { 11 Mat srcImage(Size(500, 500), CV_8UC3, Scalar(0)); 12 13 // 随机类RNG,默认的构造函数初始化为固定的值,随机“种子”也是固定的,还有一个带参数的构造函数,你可以指定“种子”, 14 // 用系统时间来指定,以确保每次执行都是“不同的种子” 从而得到不同的随机序列 15 RNG rng((unsigned)time(NULL)); 16 17 char key; 18 while (1) 19 { 20 //随机生成一些点 21 //首先就是随机生成点的总数量 22 int g_nPointCount = rng.uniform(10, 30); 23 //接下来就是随机生成一些点的坐标 24 vector<Point> points; 25 for (int i = 0; i < g_nPointCount; i++) 26 { 27 Point midPoint; 28 29 midPoint.x = rng.uniform(srcImage.cols / 4, srcImage.cols * 3 / 4); 30 midPoint.y = rng.uniform(srcImage.rows / 4, srcImage.rows * 3 / 4); 31 32 points.push_back(midPoint); 33 } 34 35 //显示刚刚随机生成的那些点 36 for (int i = 0; i < g_nPointCount; i++) 37 { 38 circle(srcImage, points[i], 0, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); 39 } 40 41 42 //在生成的那些随机点中寻找最小包围圆形 43 Point2f center; //圆心 44 float radius; //半径 45 minEnclosingCircle(points, center, radius); 46 47 //根据得到的圆形和半径 绘制圆形 48 circle(srcImage, static_cast<Point>(center), (int)radius, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3); 49 50 imshow("效果图", srcImage); 51 52 key = waitKey(); 53 if (key == 27) 54 break; 55 else 56 srcImage = Scalar::all(0); 57 } 58 59 return 0; 60 }