open cv轮廓周围绘制圆形和矩形
- 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轮廓周围绘制圆形和矩形相关推荐
- qt绘制一圈圆_Qt绘制圆形,矩形等图形 绘制同心圆
原来Qt也可以绘制图形啊. 利用QPainter类来绘制,再辅以其他类,诸如QPen来说明绘制的画笔,QPoint来说明某个点,QPaletee来说明绘制的颜料等等.在QWidget类中来实现虚拟函数 ...
- H5画布 canvas(一)canvas简介、绘制圆形矩形、案例饼状图绘制
目录 1. canvas 简介 2. canvas 标签介绍 3. canvas 上下文 Context 4. 案例:在 canvas 画布中绘制表格 5. canvas 的 beginPath 状态 ...
- H5画布 canvas(一)canvas简介、绘制圆形/矩形、案例饼状图绘制
目录 1. canvas 简介 2. canvas 标签介绍 3. canvas 上下文 Context 4. 案例:在 canvas 画布中绘制表格 5. canvas 的 beginPath 状态 ...
- Opencv(六)模板匹配、轮廓检测、轮廓周围绘制矩形框和圆形框
模板匹配介绍 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域. 所以模板匹配首先需要一个模板图像T(给定的子图像) 另外需要一个待检测的图像-源图像S 工作方法,在带检测图像上,从左到右,从 ...
- H5canvas(绘制矩形,绘制圆形,绘制线段,绘制文字,绘制曲线)
Canvas简介 canvas 最早由Apple引入WebKit,用于Mac OS X 的 Dashboard,后来又在Safari和Google Chrome被实现. 基于 Gecko 1.8的浏览 ...
- html5实现圆圈里带一个三角形,Fabric.js - 详细使用教程1(绘制图形:矩形、圆形、三角形、不规则图形)...
一.绘制图形 1,绘制矩形 下面代码在画布上绘制一个红色圆角矩形,并带有橙色边框. canvas { border: 1px dashed black; } window.onload = funct ...
- HTML5系列代码:绘制一个圆形和矩形叠加的图形
一个画布在网页中是一个矩形框,通过 元素来绘制. 注意: 默认情况下 元素没有边框和内容. <!DOCTYPE HTML> <html> <head> <me ...
- HTML5画布(canvas)绘制三角形,矩形,圆形
canvas标签: <canvas id="cavsElem" width="400" height="300">您的浏览器不支 ...
- 圆 最小外包矩形_【OpenCV3图像处理】提取轮廓的凸包、外包矩形、最小外包矩形、最小外包圆...
1.提取轮廓的凸包 convexhull()函数(点我看OpenCV3.2帮助文档) 函数调用形式: void convexhul(InputArray points,OutputArray hull ...
最新文章
- mpu 配置内存空间_mpu内存保护单元功能及工作原理
- python配置环境是干啥的_Python配置环境
- WebService服务发布与使用(JDK自带WebService)
- 【重构笔记04】重新组织数据(2)
- java poi读取excel日期格式数据
- 设计模式(2)——观察者模式
- 27 构造连续的ICMP数据包
- 【深入浅出图像算法】图像处理算法入门好文
- eclipse安装翻译插件(通用)
- 笔记本wife功能丢失,网络适配器代码56错误
- Unity3D中的对齐
- Floyd是咋求图的最短路径?
- WannaCry爆发一年后,EternalBlue的威胁仍然存在
- 如何将每日新闻添加到自己博客中,发送到微信群中
- 微信公众号聊天机器人
- 大数据:Hadoop集群测试
- 进程通信实例之父子进程通信
- vue-cli生成的模板各个文件详解(转)
- 2022年基础设施行业10大技术应用趋势
- DataWhale_Matplotlib_艺术画笔见乾坤