您的位置:首页 > 运维架构

【opencv】最小包围矩形minAreaRect与最小包围圆minEnclosingCircl详解

2018-01-18 19:34 651 查看

一、RotatedRect类

RotatedRect该类表示平面上的旋转矩形,该类对象有三个重要属性:矩形中心点(质心),边长(长和宽),旋转角度。三种构造函数和三种成员操作函数,RotatedRect类定义如下:

class CV_EXPORTS RotatedRect
{
public:
//构造函数
RotatedRect();
RotatedRect(const Point2f& center, const Size2f& size, float angle);
RotatedRect(const CvBox2D& box);

//!返回矩形的4个顶点
void points(Point2f pts[]) const;
//返回包含旋转矩形的最小矩形
Rect boundingRect() const;
//!转换到旧式的cvbox2d结构
operator CvBox2D() const;

Point2f center; //矩形的质心
Size2f size; //矩形的边长
float angle; //旋转角度,当角度为0、90、180、270等时,矩形就成了一个直立的矩形
};
二、minAreaRect(最小包围矩形)

minAreaRect( InputArray points );//返回类型为RotatedRect对象,参数为vector<vector<Point>>点集,作用为计算包围点集的最小旋转矩阵
三、minEnclosingCircle(最小包围圆)

minEnclosingCircle函数功能是利用一种迭代的算法,对给定的2D点集,去寻找面积最小的可包围的她们的面积

void minEnclosingCircle(InputArray point, Point2f¢er, float&radius);


第一个参数:输入的二维点集,可以是vector<>

第二个参数:圆的输出圆心

第三个参数:圆的输出半径

四、程序演示

求随机点的最小包围圆和最小包围矩形

#include<opencv2\opencv.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
void on_ThreshChange(int, void*);
int ThreshValve = 100;
Mat srcImage, srcImage_gray, srcImage_blur, srcImage_thresh;

int main()
{

Mat image(600, 600, CV_8UC3, Scalar::all(255));
//imshow("image", image);
RNG &rng = theRNG();
while (1)
{
char key;
int count = (unsigned)rng % 100; //产生随机数的个数不大于10
cout << "cout为:" << count << endl;

vector<Point>points; //vector容器存放Point坐标
for (int i = 0; i < count; i++)
{
Point point;
point.x = rng.uniform(image.cols / 4, image.rows * 3 / 4);
point.y = rng.uniform(image.cols / 4, image.rows * 3 / 4);
points.push_back(point); //在vector尾部加入一个点向量
cout << "vector容器中存放的个点坐标" << point << endl;

}
cout << "基于Mat类的vector" << Mat(points) << endl; //以矩阵的形式存储
cout << points.size() << endl; //产生随机点的个数

vector<int>hull;
convexHull(points,hull, true); //凸包检测,第三个参数为操作标识符,当为true时,输出凸包为顺时针方向,否则为逆时针方向
//cout << hull.size() << endl; //凸包的边数

image = Scalar::all(0); //Scale::all(0)表示所以点设为0,即全部为黑色的窗口等价于下面
//Mat image(600, 600, CV_8UC3, Scalar::all(255));

/**********************根据给定的随机点集,寻找最小包围盒*******************************/

Point2f center;
float radius = 0;
minEnclosingCircle(Mat(points), center, radius); //求出最小包围圆的圆心与半径

/*********************************绘制随机点的颜色****************/
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)),//用随机数产生随机颜色
2, 8, 0);
}
int hullcount = (int)hull.size();
Point point0 = points[hull[hullcount - 1]];
for (int i = 0; i < hullcount; i++)
{
Point point = points[hull[i]];
line(image, point0, point, Scalar(255, 0, 0), 5, 8, 0);
point0 = point;

}
//imshow("凸包检测图", image);
/***************************************绘制最小包围圆***************/
circle(image, center, radius, Scalar(0, 0, 255), 1, 8, 0);
//imshow("包围圆", image);

/**************************************绘制最小包围矩形*************/
RotatedRect box = minAreaRect(Mat(points));
/**************************RatatedRect类的数据成员************************/
cout <<"矩形的边长为:"<< box.size << endl; //box.size 为矩形的尺寸[长x宽]
cout << "矩形的质心" << box.center << endl;
cout << "矩形的角度" << box.angle << endl;

Point2f four_Point2f[4];
box.points(four_Point2f); //points是旋转矩形RatatedRect类的成员函数,放回矩形的四个顶点
for (int i = 0; i < 3; i++)
{
line(image, four_Point2f[i], four_Point2f[i + 1],Scalar(255,255,0 ),1,8); //此时画的还是矩形的三条边,缺少最后一条边

}
line(image, four_Point2f[3], four_Point2f[0], Scalar(255, 255, 0), 1, 8);
imshow("最小矩形面积包围盒", image);

/********************************************************/
key = (char)waitKey();
if (key == 27 || key == 'q' || key == 'Q')
{
break;

}

}return 0;
}

五、效果展示
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息