1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > open cv轮廓周围绘制圆形和矩形

open cv轮廓周围绘制圆形和矩形

时间:2020-11-16 14:05:00

相关推荐

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;}

此项目详解

/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多边拟合函数的详解

/u011479336/article/details/91553007

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。