8.3 使用多边形将轮廓包围

8.3.1 将轮廓包围的多边形函数

1.返回外部边界:boundingRect()函数
(1)作用:返回指定点集最外面的边界矩形(四个顶点)
(2)函数原型:Rect boundingRect(InputArray points)
2.寻找最小包围矩形:minAreaRect()函数
(1)作用:返回指定点集可旋转的最小面积的包围矩形(四个顶点)
(2)函数原型:RotatedRect minAreaRect(InputArray points)
3.寻找最小包围圆形:minEnclosingCircle()函数
(1)作用:利用一种迭代算法,返回指定点集的最小面积的包围圆形(圆心,半径)
(2)函数原型:void minEnclosingCircle(InputArray points, Point2f& center, float& radius)
(3)参数说明:输入二维点集,输出圆心,输出半径
4.用椭圆拟合二维点集:fitEllipse()函数
(1)作用:椭圆拟合二维点集
(2)函数原型:RotatedRect fitEllipse(InputArray points)
5.逼近多边形曲线:approxPolyDP()函数
(1)作用:用指定精度逼近多边形曲线
(2)函数原型:void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)
(3)参数说明:
  1)输入的二维点集
  2)多边形逼近的结果
  3)逼近的精度,为原始曲线和近似曲线间的最大值
  4)取真时,近似的曲线为封闭曲线,取假时不封闭

8.3.2 综合示例

1.随机生成彩色点,调用多边形包围函数

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;int main()
{//初始化变量和随机值Mat image(600, 600, CV_8UC3);Mat dstImage1, dstImage2, dstImage3, dstImage4;RNG& rng = theRNG();//循环,按下ESC键程序退出,否则一直更新while (1){//参数初始化int count = rng.uniform(3, 103);//随机生成点的数量vector<Point> points;//点值//随机生成点坐标for (int i = 0; i < count; i++){Point point;point.x = rng.uniform(image.rows / 4, image.rows * 3 / 4);point.y = rng.uniform(image.cols / 4, image.cols * 3 / 4);points.push_back(point);}//绘制出随机颜色的点image = Scalar::all(0);for (int i = 0; i < count; i++){circle(image, points[i], 3, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), FILLED, LINE_AA);}//【1】对指定点集寻找边界矩形Rect rect = boundingRect(Mat(points));//绘制边界矩形image.copyTo(dstImage1);rectangle(dstImage1, rect, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);//显示窗口imshow("【1】边界矩形窗口", dstImage1);//【2】对指定点集寻找最小面积的包围矩形RotatedRect box1 = minAreaRect(Mat(points));Point2f vertex2[4];box1.points(vertex2);//绘制最小面积的包围矩形image.copyTo(dstImage2);for (int i = 0; i < 4; i++){line(dstImage2, vertex2[i], vertex2[(i + 1) % 4], Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);}//显示窗口imshow("【2】最小面积包围矩形窗口", dstImage2);//【3】对指定点集寻找最小面积的包围圆形Point2f center;float radius;minEnclosingCircle(Mat(points),center,radius);//绘制最小面积的圆形image.copyTo(dstImage3);circle(dstImage3, center, cvRound(radius), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);//显示窗口imshow("【3】最小面积包围圆形窗口",dstImage3);//【4】椭圆拟合指定点集RotatedRect box2 = fitEllipse(Mat(points));//绘制椭圆image.copyTo(dstImage4);ellipse(dstImage4, box2, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);//显示窗口imshow("【4】椭圆形拟合窗口", dstImage4);char key = (char)waitKey();if(key == 27) break; }return 0;
}

运行效果:

2.载入图像,调用多边形包围函数

#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
//定义辅助宏
#define WINDOW_NAME1 "【原始图窗口】"
#define WINDOW_NAME2 "【效果图窗口】"
//全局变量
Mat g_srcImage, g_grayImage;
int g_nThresh = 50;//阈值
int g_nMaxThresh = 255;//阈值最大值
RNG g_rng(12345);//随机数生成器
//全局函数
void on_ContoursChange(int, void*);int main()
{   //【1】载入原图g_srcImage = imread("Google.jpg");if (!g_srcImage.data){printf("载入原图失败~!\n");return false;}//【2】创建原始图窗口并显示namedWindow(WINDOW_NAME1,WINDOW_AUTOSIZE);imshow(WINDOW_NAME1, g_srcImage);//【3】得到原图的灰度图像并进行平滑cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);blur(g_grayImage, g_grayImage, Size(3, 3));//【4】设置滚动条并调用一次回调函数createTrackbar("阈值:", WINDOW_NAME1, &g_nThresh, g_nMaxThresh, on_ContoursChange);on_ContoursChange(0, 0);waitKey(0);return 0;
}
void on_ContoursChange(int, void*)
{//定义一些参数Mat threshold_output;vector<vector<Point>> contours;vector<Vec4i> hierarchy;//使用Threshold检测边缘threshold(g_grayImage, threshold_output, g_nThresh, 255, THRESH_BINARY);//找出轮廓findContours(threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));//多边形逼近轮廓+获取矩形和圆形边界框vector<vector<Point>> contours_poly(contours.size());vector<Rect> boundRect(contours.size());vector<Point2f> center(contours.size());vector<float> radius(contours.size());//一个循环,遍历所有部分,进行本程序最核心的操作for (int i = 0; i < contours.size(); i++){approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);//用指定精度逼近多边形曲线boundRect[i] = boundingRect(Mat(contours_poly[i]));//计算点集的最外面矩形边界minEnclosingCircle(contours_poly[i], center[i], radius[i]);//对给定点集寻找最小面积的包围圆形}//绘制多边形轮廓+包围的矩形框+圆形框Mat dstImage = Mat::zeros(threshold_output.size(), CV_8UC3);for (int i = 0; i < contours.size(); i++){Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//随即设置颜色drawContours(dstImage, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point());//绘制轮廓rectangle(dstImage, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);//绘制矩形circle(dstImage, center[i], (int)radius[i], color, 2, 8, 0);}//显示效果图窗口namedWindow(WINDOW_NAME2,WINDOW_AUTOSIZE);imshow(WINDOW_NAME2, dstImage);
}

运行效果:


《OpenCV3编程入门》学习笔记8 图像轮廓与图像分割修复(三)使用多边形将轮廓包围相关推荐

  1. 原创 OpenCV3编程入门 学习笔记(总)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_36163358/article/ ...

  2. OpenCV3编程入门 学习笔记(总)

    OpenCV3编程入门 学习笔记 2018.12.12-2018.12.29 此博客为在看过毛星云版<OpenCV3编程入门>后所总结的一本笔记,可供复习使用. 文章目录 OpenCV3编 ...

  3. Opencv3编程入门学习笔记(五)之通道分离(split)与合并(merge)

    若要对Opencv中(BGR)颜色通道进行单一处理,那必然会涉及到通道分离(split)与合并(merge).那么本篇博客笔者记录了两个方法的使用方法和案例.案例来源于<Opencv3编程入门学 ...

  4. Opencv3编程入门学习笔记(三)之访问图像像素的三种方法

    访问图像像素的三种方法:指针访问,迭代器访问,动态地址访问.访问最快的为指针访问,以下算法在几毫秒,但指针访问容易造成内存泄漏:其次为迭代器访问:最后为动态地址访问. 以下程序是根据<OpenC ...

  5. 【OpenCV3编程入门学习笔记】——第1章 邂逅OpenCV

    邂逅OpenCV 文章目录 邂逅OpenCV 前言 1.1 OpenCV周边概念认知 1.1.1 图像处理.计算机视觉与OpenCV 1.1.2 OpenCV概述 1.1.3 起源及发展 1.1.4 ...

  6. 【OpenCV3编程入门学习笔记】——第3章 HighGUI图形用户界面初步

    文章目录 前言 3.1 图形的载入.显示和输出到文件 3.1.1 OpenCV的命名空间 3.1.2 Mat类简析 3.1.3 图像的载入与显示概述 3.1.4 图像的载入:imread()函数 3. ...

  7. Opencv3编程入门学习笔记(四)之split通道分离Debug过程中0xC0000005内存访问冲突问题

    这是笔者学习<Opencv3编程入门>的第四篇博客,这篇博客主要是解决在Windows系统下VS 2013中Debug含有split分离通道色彩函数时报出的0xC0000005内存访问冲突 ...

  8. Opencv3编程入门学习笔记(二)之显式创建Mat对象

    以下总结是基于<Opencv3编程入门>一书4.1节总结的内容进行验证与总结,验证环境均为Windows10 ---VS2013 C++环境,验证Opencv3.0提供的开发包. 1. 方 ...

  9. 01.Java 编程入门学习笔记20210307

    Java 编程入门学习笔记-day01 第0章:编程入门 1.计算机的概述 计算机 = 硬件 + 软件 1.1硬件:冯诺依曼体系 CPU: CPU的衡量标准:速度的计量单位是赫兹(Hz),1Hz相当于 ...

  10. Python快速编程入门#学习笔记01# |第一章 :Python基础知识 (Python发展历程、常见的开发工具、import模块导入)

    全文目录 ==先导知识== 1 认识Python 1.1.1 Python的发展历程 1.1.2 Python语言的特点 2. Python解释器的安装与Python程序运行 1.2.1 安装Pyth ...

最新文章

  1. flask源码学习-helloworld与本地启动流程
  2. Python实例浅谈之五Python守护进程和脚本单例运行
  3. jradiobutton设置默认选项_JRadioButton(单选按钮)添加事件监听
  4. leetcode 497, 528. Random Point in Non-overlapping Rectangles | 497. 非重叠矩形中的随机点(Java)
  5. 记录一个相当好用的反编译工具下载地址
  6. 苹果CMS10 资源网模板
  7. php flush 逐行显示_PHP逐行输出(ob_flush与flush的组合)
  8. clock函数,计算程序运行时间
  9. GPCP全球月降水量数据下载与读取
  10. 旅行商问题(TSP) 中国34个城市 经纬度平面坐标
  11. PDF转HTML常用方法分享
  12. 网络神偷 v7.6 免费
  13. 备份手机相册----syncthing (一劳永逸式解决方案)
  14. 电脑扬声器耳机已拔出
  15. 计算机网络存在的漏洞,常见的计算机网络安全漏洞有哪些
  16. 跨域请求传递Cookie
  17. xnio-nio解决方法
  18. TCP/IP 协议详解内容总结
  19. 酒醉之后你最思念谁?
  20. java学习日记-接口

热门文章

  1. 2021-2027年中国医联体(医疗联合体)建设深度调研及投资前景预测报告
  2. Docker入门六部曲——Swarm
  3. 数据结构与算法——线性结构——线性表及其表示
  4. Windows中配置java变量环境
  5. Python __call__详解
  6. PyTorch之前向传播函数自动调用forward
  7. LeetCode简单题之检查两个字符串数组是否相等
  8. 无人驾驶汽车开发平台,加速无人驾驶汽车的商业化
  9. 管理多供应商物联网项目的10个关键步骤
  10. CVPR2020:4D点云语义分割网络(SpSequenceNet)