• APIapproxPolyDP(精简多边形轮廓点数)

作用是把一个很多点的多边形变成一个点数适中的多边形
在这个多边形里面找它的最小连接矩形和最小的圆

approxPolyDP
(
InputArray curve,//输入一个多边形(点)
OutputArray approxCurve, //输出一个处理后的多边形(点)
double epsilon,//表示两点之间的最小距离,小于这个距离舍去,大于这个距离保留
bool closed//判断是否封闭(形成的多边形是否闭合 多边形分为凸多边形和凹多边形)

)

approxPolyDP算法基于RDP算法实现 目的是减少多边形的轮廓点数

什么是RDP算法?


绘制矩形和旋转矩形API

cv::boundingRect(InputArray points)得到每一个轮廓周围最小矩形左上角点坐标和右下角点坐标
cv::AreaRect(InputArray points)得到一个旋转矩形,返回旋转矩形

轮廓周围绘制圆和旋转椭圆API

绘制圆cv::minEnclosingCircle
minEnclosingCircle
(
InputArray points,//找到最小区域圆形
Point2f& center,//圆心坐标
float& radius//圆的半径
)

绘制椭圆cv::fitEllipse(InputArray points)得到最小椭圆

步骤
转灰度图像cvtColor
首先将图像变为二值图像threshold
发现轮廓,找到图像轮廓findContours
减少多边形轮廓点数approxPolyDP
通过相关API在轮廓点上找到最小包含矩形和圆
绘制

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
#include <math.h>using namespace cv;
using namespace std;Mat src, dst,srcGray,Drawimg;int thre = 0;
int threMAX = 255;
int epsilon = 4;void DrawContours(int, void*);int main()
{src = imread("D:/实验台/机器视觉/测试图片/凸包.jpg");if (src.empty())//如果src这个数据库属性为空{cout << "无法打开" << endl;return -1;}imshow("原图", src);cvtColor(src, srcGray, CV_BGR2GRAY);blur(srcGray, srcGray,Size(3,3),Point(-1,-1));imshow("预处理", srcGray);namedWindow("二值化", CV_WINDOW_AUTOSIZE);createTrackbar("二值化","二值化",&thre,threMAX,DrawContours);createTrackbar("多变拟合", "二值化", &epsilon,100, DrawContours);DrawContours(0, 0);waitKey(0);return 0;
}void DrawContours(int, void*)
{Mat bin;//二值化 binarythreshold(srcGray,bin,thre,threMAX,THRESH_BINARY);imshow("二值化", bin);vector<vector<Point>>contours;vector<Vec4i>hierachy;findContours(bin, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));vector<vector<Point>>PLOYcontours(contours.size());//存放多边形逼近处理后的轮廓点vector<Rect>PLOYrects(contours.size());//存放矩形框的坐标 (四个参数 1.左上顶点坐标位置X 2.左上顶点坐标位置Y  3.像素width  4.height )vector<Point2f>ccs(contours.size());//存放圆形轮廓圆心坐标 ccs-CircelCenterpointS(两个参数 圆心的 1.坐标位置X  2.坐标位置Y)vector<float>radius(contours.size());//存放圆形轮廓的半径 radius-半径(一个参数 浮点型的圆形半径0)vector<RotatedRect>minRects(contours.size());//存放旋转矩形的信息vector<RotatedRect>myellipse(contours.size());//存放椭圆的信息//关于RotatedRect类型 它表示平面上的旋转图形信息 有三个属性//1.矩形的中心点(质心)   2.边长(长和宽)  3.旋转角度(当角度为0、90、180、270等时,矩形就成了一个直立的矩形)Point2f pts[4];//定义二维坐标浮点型数组存放旋转矩形点集合minRects的四个矩形顶点坐标信息(两个参数 1.旋转矩形左上顶点位置 2.右下顶点位置)//遍历原轮廓所有点集合 for (size_t i = 0; i < contours.size(); i++){//当需要对图像进行形状分析时,需要使用多边形逼近一个轮廓,使得顶点数目变少approxPolyDP(Mat(contours[i]), PLOYcontours[i], epsilon,true);//approxPolyDP多边形逼近//curve:图像的轮廓点组成的点集(存储在std::vector或Mat中的2D曲线点集)//approxCurve:类型为坐标的输出多边形的点集(逼近的曲线,其类型需要与输入曲线的类型匹配)//epsilon:用于指定逼近精度的参数,就是两个轮廓点之间最大距离数(值越大边越少 用来过滤不需要的小型输出多边形点集合)//closed :若为true,则说明近似曲线是闭合的,它的首位都是相连,反之,若为false,则断开//当我们得到进行逼近后的轮廓后,可用boundingRect()得到包覆此轮廓的最小正矩形大小及其坐标信息-PLOYrects[i]PLOYrects[i] = boundingRect(PLOYcontours[i]);//读入的参数必须是vector或者Mat点集 //获得矩形包围框(适合所有点集)   筛选出矩形框的信息(两个角点坐标)//minEnclosingCircle()得到包覆此轮廓的最小圆形相关信息minEnclosingCircle(PLOYcontours[i], ccs[i], radius[i]);//筛选出圆形框的信息(圆心、半径)//包覆轮廓的最小圆形(输入点集序列,输出的圆心坐标,输出的半径大小)if(PLOYcontours[i].size()>5)//因为API的参数要求 只有逼近后的顶点集合数量大于5 才能绘制椭圆旋转矩形{ myellipse[i] = fitEllipse(PLOYcontours[i]);//筛选出椭圆信息//因为boundingRect()函式返回的是正矩形,所以如果对象有倾斜的情形//返回的可能不是我们想要的结果,所以我们需要旋转矩形minRects[i] = minAreaRect(PLOYcontours[i]);//筛选出旋转矩形的信息//minAreaRect() 获取最小矩形框,得到包覆轮廓的最小斜矩形 }}src.copyTo(Drawimg);//在原图中绘制//Drawimg = Mat::zeros(src.size(), src.type());//在黑色背景图片中绘制RNG rng(12345);for (size_t t = 0; t < contours.size();t++){Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));//drawContours(Drawimg, PLOYcontours, t, color, 2, 8);  //直接绘制逼近轮廓 用于显示轮廓逼近函数在精度参数对逼近效果的影响 //rectangle(Drawimg, PLOYrects[t], color, 2, 8);//绘制矩形框//绘制矩形(目标图片,(左上顶点X坐标,左上顶点Y坐标,矩形宽度,矩形高度),颜色,线粗,线类型)//circle(Drawimg, ccs[t], radius[t], color, 2, 8);//绘制圆形框//绘制圆形(目标图片,圆心坐标,圆半径,颜色,线粗,线类型)if (PLOYcontours[t].size() > 5){ellipse(Drawimg, myellipse[t], color, 2, 8);//绘制旋转椭圆形框  //绘制椭圆(目标图片,(椭圆中心点坐标X,椭圆中心点坐标Y,椭圆相对于水平的旋转角度,椭圆轴径大小),颜色,线粗,线类型)minRects[t].points(pts);//把minRests旋转矩形存储的四个顶点坐标信息传递个数组pts pts有四个顶点 但是我们绘制矩形只需要两个顶点for (int j = 0; j < 4; j++){line(Drawimg, pts[j], pts[(j + 1) % 4], color, 2, 8);//由于是旋转矩形,所以只能通过画线构成旋转矩形//画线(目标图片,起点坐标,线段终点坐标,颜色,线粗,线类型)}}}for (int i = 0; i < contours.size(); i++){/*cout << "输出的第" << i + 1 << "个逼近多边形点集为" << endl << PLOYcontours[i] << endl;cout << "输出的第" << i + 1 << "个逼近矩形框坐标为" << endl << PLOYrects[i] << endl;cout << "输出的第" << i + 1 << "个逼近圆形圆心坐标为" << endl << ccs[i] << endl;cout << "输出的第" << i + 1 << "个逼近圆形半径为" << endl << radius[i] << endl;*/    cout << "输出的第" << i + 1 << "个旋转矩形的旋转角度angle为" << minRects[i].angle << "质心坐标为" << minRects[i].center << "矩形大小为" << minRects[i].size <<endl;cout << "输出的第" << i + 1 << "个椭圆的旋转角度angle为" << myellipse[i].angle << "质心坐标为" << myellipse[i].center << "椭圆大小为" << myellipse[i].size << endl;cout << "输出的第" << i + 1 << "个矩形角点信息为" <<pts[i]<< endl;}//计算轮廓周长或者曲线长度(不适用于非轮廓的点集)for (size_t i = 0; i < contours.size(); i++){double PLOYcontourLen = arcLength(PLOYcontours[i], true);double contourLen = arcLength(contours[i], true);//双浮点型参数=轮廓周长(输入的图像轮廓点集合序列或数组,曲线是否闭合)//则最后一点到第一点的距离计入总弧长 函数 arcLength 通过依次计算序列点之间的线段长度,并求和来得到曲线的长度printf("原始轮廓周长为%f  逼近曲线围成的轮廓周长为%f\r", PLOYcontourLen,contourLen);}imshow("轮廓绘制",Drawimg);return;
}

此项目详解
https://blog.csdn.net/qq_30815237/article/details/86901728?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
关于approxPolyDP多边拟合函数的详解
https://blog.csdn.net/u011479336/article/details/91553007

open cv轮廓周围绘制圆形和矩形相关推荐

  1. qt绘制一圈圆_Qt绘制圆形,矩形等图形   绘制同心圆

    原来Qt也可以绘制图形啊. 利用QPainter类来绘制,再辅以其他类,诸如QPen来说明绘制的画笔,QPoint来说明某个点,QPaletee来说明绘制的颜料等等.在QWidget类中来实现虚拟函数 ...

  2. H5画布 canvas(一)canvas简介、绘制圆形矩形、案例饼状图绘制

    目录 1. canvas 简介 2. canvas 标签介绍 3. canvas 上下文 Context 4. 案例:在 canvas 画布中绘制表格 5. canvas 的 beginPath 状态 ...

  3. H5画布 canvas(一)canvas简介、绘制圆形/矩形、案例饼状图绘制

    目录 1. canvas 简介 2. canvas 标签介绍 3. canvas 上下文 Context 4. 案例:在 canvas 画布中绘制表格 5. canvas 的 beginPath 状态 ...

  4. Opencv(六)模板匹配、轮廓检测、轮廓周围绘制矩形框和圆形框

    模板匹配介绍 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域. 所以模板匹配首先需要一个模板图像T(给定的子图像) 另外需要一个待检测的图像-源图像S 工作方法,在带检测图像上,从左到右,从 ...

  5. H5canvas(绘制矩形,绘制圆形,绘制线段,绘制文字,绘制曲线)

    Canvas简介 canvas 最早由Apple引入WebKit,用于Mac OS X 的 Dashboard,后来又在Safari和Google Chrome被实现. 基于 Gecko 1.8的浏览 ...

  6. html5实现圆圈里带一个三角形,Fabric.js - 详细使用教程1(绘制图形:矩形、圆形、三角形、不规则图形)...

    一.绘制图形 1,绘制矩形 下面代码在画布上绘制一个红色圆角矩形,并带有橙色边框. canvas { border: 1px dashed black; } window.onload = funct ...

  7. HTML5系列代码:绘制一个圆形和矩形叠加的图形

    一个画布在网页中是一个矩形框,通过 元素来绘制. 注意: 默认情况下 元素没有边框和内容. <!DOCTYPE HTML> <html> <head> <me ...

  8. HTML5画布(canvas)绘制三角形,矩形,圆形

    canvas标签: <canvas id="cavsElem" width="400" height="300">您的浏览器不支 ...

  9. 圆 最小外包矩形_【OpenCV3图像处理】提取轮廓的凸包、外包矩形、最小外包矩形、最小外包圆...

    1.提取轮廓的凸包 convexhull()函数(点我看OpenCV3.2帮助文档) 函数调用形式: void convexhul(InputArray points,OutputArray hull ...

最新文章

  1. mpu 配置内存空间_mpu内存保护单元功能及工作原理
  2. python配置环境是干啥的_Python配置环境
  3. WebService服务发布与使用(JDK自带WebService)
  4. 【重构笔记04】重新组织数据(2)
  5. java poi读取excel日期格式数据
  6. 设计模式(2)——观察者模式
  7. 27 构造连续的ICMP数据包
  8. 【深入浅出图像算法】图像处理算法入门好文
  9. eclipse安装翻译插件(通用)
  10. 笔记本wife功能丢失,网络适配器代码56错误
  11. Unity3D中的对齐
  12. Floyd是咋求图的最短路径?
  13. WannaCry爆发一年后,EternalBlue的威胁仍然存在
  14. 如何将每日新闻添加到自己博客中,发送到微信群中
  15. 微信公众号聊天机器人
  16. 大数据:Hadoop集群测试
  17. 进程通信实例之父子进程通信
  18. vue-cli生成的模板各个文件详解(转)
  19. 2022年基础设施行业10大技术应用趋势
  20. DataWhale_Matplotlib_艺术画笔见乾坤

热门文章

  1. java 倍数_Java硬币翻转倍数递增试算实例
  2. ArrayList源码解读
  3. deepin 系统 微信登录提示版本过低解决方法
  4. 互联网金融牌照有哪些?金融牌照一览表
  5. Docker提交天池比赛流程
  6. python中取余%
  7. 【轮子1】造一个炫酷的DEBUG输出
  8. Microsoft Exchange Server邮箱管理
  9. 直击|ofo测试折扣商城 押金可转换为金币消费
  10. android 放大缩小命令,Android TV开发中常用命令