一、属性

1.成员变量

  • float angle

  • Point2f center

  • Size2f size

2.构造函数

  • 默认构造:
    RotatedRect ()
    default constructor More…

  • 角度构造:
    RotatedRect (const Point2f &center, const Size2f &size, float angle)
    center:矩形的中心点
    angle:顺时针的角度,0-360°
    size可以是负的:x正沿x正方向(向右),y正沿y正方向(向下)

  • 三个点构造:
    RotatedRect (const Point2f &point1, const Point2f &point2, const Point2f &point3)
    矩形的任意三个点。注意必须遵从逆时针或顺时针的顺序

3.成员函数

  • Rect boundingRect () const
    returns the minimal up-right integer rectangle containing the rotated rectangle

  • Rect_< float > boundingRect2f () const
    returns the minimal (exact) floating point rectangle containing the rotated rectangle, not intended for use with images

  • void points (Point2f pts[]) const
    returns 4 vertices of the rectangle。返回矩形四个顶点的Point2f类位置信息给pts数组

4.例子

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{
	Mat test_image(200, 200, CV_8UC3, Scalar(0));
	RotatedRect rRect = RotatedRect(Point2f(100, 100), Size2f(100, 50), 30);

	/*获得角度*/
	cout << rRect.angle << endl;
	//角度30度

	/*获得中心点*/
	cout << rRect.center << endl;
	//中心点[100, 100]

	/*获得宽×高*/
	cout << rRect.size << endl;
	//宽×高[100 x 50]

	/*获得宽*/
	cout << rRect.size.width << endl;
	// 100

	/*获得高*/
	cout << rRect.size.height << endl;
	// 50

	/*获得面积*/
	cout << rRect.size.area() << endl;
	//5000

	//绘制旋转矩形
	Point2f vertices[4];
	rRect.points(vertices);
	for (int i = 0; i < 4; i++)
		line(test_image, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0), 2);

	//圈中这个旋转矩形的外矩形
	Rect brect = rRect.boundingRect();
	rectangle(test_image, brect, Scalar(255, 0, 0), 2);

	imshow("rectangles", test_image);
	waitKey(0);
	return 0;
}

在这里插入图片描述

二、类成员变量探究

1.用角度构造和用三个点构造

(1)用角度构造

  • angle范围任意值(就是指定的angle)
  • width和height就是指定的值(不会随角度变化)
  • 机制:初始图像(宽就是给的width值,高就是给的height值,以向上为轴,现在为0°),然后以角度angle旋转图形(正顺时针,负逆时针),现在表示的是33°
    在这里插入图片描述
    在这里插入图片描述

(2)用三个点构造

  • angle范围[-45°,45°]
  • width就是角度接触的那一边,height就是另一边(会变化)
  • 判定机制:找到最下面的顶点,设定水平轴,左边(正)和右边(负)分别得到一个角度,以绝对值小的那个角度为angle,接触的边为width。比如下图,就是左边的角为angle,正值,其边为width。
    在这里插入图片描述

(3)验证

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;

int main()
{
	Mat src(400,400,CV_8UC1,Scalar::all(0));
	for(float angle=0;angle<=720;angle++)
	{
		RotatedRect angle_rotatedRect(Point2f(200,200),Size2f(50,100),angle);
		Point2f vertices[4];
		angle_rotatedRect.points(vertices);
		for (int i = 0; i < 4; i++)
		{
			line(src, vertices[i], vertices[(i+1)%4], Scalar::all(255), 2);
		}
		
		RotatedRect points_RotatedRect(vertices[3],vertices[2],vertices[1]);
	    
	    // 角度,用角度构造的旋转矩形的角度,用点构造的旋转矩形的角度
		cout<<"angle:"<<angle<<" , "<<"angle_rotatedRect's angle:"<<angle_rotatedRect.angle
			<<" , "<<"points_RotatedRect's angle:"<<points_RotatedRect.angle<<endl;
		// 用角度构造的旋转矩形的宽,用点构造的旋转矩形的宽
		cout<<"angle_rotatedRect's width:"<<angle_rotatedRect.size.width<<" , "
			<<"points_RotatedRect's width:"<<points_RotatedRect.size.width<<endl;
		// 用角度构造的旋转矩形的高,用点构造的旋转矩形的高
		cout<<"angle_rotatedRect's height:"<<angle_rotatedRect.size.height<<" , "
			<<"points_RotatedRect's height:"<<points_RotatedRect.size.height<<endl;
		cout<<endl;
		
		imshow("src",src);
		if(waitKey()=='q') return 0;
		src=Scalar::all(0);
	}	
	return 0;
}

在这里插入图片描述

2.minAreaRect()圈出的旋转矩形

  • angle范围:[-90°,0°]
  • width就是角度挨着的那一边,height就是另一边(会变化)
  • 判定机制:还是最低顶点建轴,只不过这会只选择右边(负)为angle,其边为width。当为0°时,以左下角为顶点。当为-90°时,以右下角为顶点
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

#define W_CONVEX "RESULT"

int main()
{
	Mat image=Mat::zeros(600,600,CV_8UC3);

	RNG& rng=theRNG();

	while(1)
	{
		char key;

		int count=(unsigned)rng%100+3;
		vector<Point> points;

		for(int i=0;i<count;i++)
		{
			Point point;
			point.x=rng.uniform(image.cols/4,image.cols*3/4);
			point.y=rng.uniform(image.rows/4,image.rows*3/4);
			circle(image,point,2,Scalar::all(255),2);
			points.push_back(point);
		}

		RotatedRect rotatedRect=minAreaRect(points);
		Point2f hull[4];
		rotatedRect.points(hull);
		for(int i=0;i<4;i++)
		{
			line(image,hull[i],hull[(i+1)%4],Scalar::all(255),2);
		}
		cout<<"RotatedRect's angle:"<<rotatedRect.angle<<endl;
		cout<<"RotatedRect's width:"<<rotatedRect.size.width<<endl;
		cout<<"RotatedRect's height:"<<rotatedRect.size.height<<endl;
		cout<<endl;

		namedWindow(W_CONVEX,WINDOW_NORMAL);
		imshow(W_CONVEX,image);

		image=Scalar::all(0);

		if(waitKey()=='q') return 0;

	}

	return 0;
}

在这里插入图片描述

/*获得-90°的情况*/
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

#define W_CONVEX "RESULT"

int main()
{
	Mat image=Mat::zeros(600,600,CV_8UC3);

	vector<Point> points{Point(100,100),Point(200,100),Point(100,300),Point(200,300)};
	

	RotatedRect rotatedRect=minAreaRect(points);
	Point2f hull[4];
	rotatedRect.points(hull);
	for(int i=0;i<4;i++)
	{
		line(image,hull[i],hull[(i+1)%4],Scalar::all(255),2);
	}
	cout<<"RotatedRect's angle:"<<rotatedRect.angle<<endl;
	cout<<"RotatedRect's width:"<<rotatedRect.size.width<<endl;
	cout<<"RotatedRect's height:"<<rotatedRect.size.height<<endl;
	cout<<endl;

	namedWindow(W_CONVEX,WINDOW_NORMAL);
	imshow(W_CONVEX,image);

	waitKey();

	return 0;
}

3.minAreaRect()后改变类属性

比如改变angle,那么width和height是否会变化。是采用角度规则还是三个点的规则还是minAreaRect()规则。
结论:采用角度规则

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{
    Mat image = Mat::zeros(600, 600, CV_8UC3);

    vector<Point> points{Point(100, 100), Point(300, 100), Point(100, 200), Point(300, 200)};

    // 圈出来旋转矩形
    RotatedRect rotatedRect = minAreaRect(points);

    cout << "RotatedRect's angle:" << rotatedRect.angle << endl;
    cout << "RotatedRect's width:" << rotatedRect.size.width << endl;
    cout << "RotatedRect's height:" << rotatedRect.size.height << endl;
    cout << endl;

    Point2f hull1[4];
    rotatedRect.points(hull1);
    for (int i = 0; i < 4; i++)
    {
        line(image, hull1[i], hull1[(i + 1) % 4], Scalar::all(255), 2);
    }
    for (;;)
    {
        rotatedRect.angle += 10;

        cout << "RotatedRect's angle:" << rotatedRect.angle << endl;
        cout << "RotatedRect's width:" << rotatedRect.size.width << endl;
        cout << "RotatedRect's height:" << rotatedRect.size.height << endl;
        cout << endl;

        Point2f hull2[4];
        rotatedRect.points(hull2);
        for (int i = 0; i < 4; i++)
        {
            line(image, hull2[i], hull2[(i + 1) % 4], Scalar::all(120), 2);
        }

        imshow("image", image);

        if (waitKey() == 'q')
            return 0;
        image = Scalar::all(0);
    }

    return 0;
}

在这里插入图片描述
旋转过程:
初始宽为100,高为200,angle是70°,旋转70°
在这里插入图片描述

GitHub 加速计划 / opencv31 / opencv
77.35 K
55.71 K
下载
OpenCV: 开源计算机视觉库
最近提交(Master分支:1 个月前 )
8e5dbc03 Proposed solution for the issue 26297 #26298 closes #26297 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake 2 天前
1909ac86 Enhance cv::TickMeter to be able to get the last elapsed time 2 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐