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

一、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);

  1. 第一个参数:输入的二维点集,可以是vector<>
  2. 第二个参数:圆的输出圆心
  3. 第三个参数:圆的输出半径


四、程序演示

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

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


五、效果展示






  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值