zoukankan      html  css  js  c++  java
  • OpenCV 提取轮廓的凸包、外包矩形、最小外包矩形、最小外包圆

    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 }

    效果图:

    这里写图片描述

  • 相关阅读:
    有用的sql语句积累
    spring boot sso 学习资源
    notepad++ 常用快捷键
    artTemplate的使用总结
    ajax完整请求
    03 Mybatis框架---学习笔记1--框架的概念及优势
    02 Struts2框架----学习笔记2(了解一下,已过时)
    IDEA 获取类的相对路径和绝对路径
    01 Struts2框架学习(了解一下,已过时)
    喜马拉雅 FM 已购付费音频下载
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/14334234.html
Copyright © 2011-2022 走看看