OpenCV之RotatedRect基本用法和角度探究

本文详细探讨了OpenCV中RotatedRect类的属性、构造函数和成员函数,包括使用角度和三点构造方法的区别,以及minAreaRect()函数的特性。通过实例展示了不同构造方式下旋转矩形的属性变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、属性

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°
在这里插入图片描述

OpenCV(Open Source Computer Vision Library)是一个广泛使用的计算机视觉库,它并没有直接内置计算RotatedRect(旋转矩形)亮度值的功能。RotatedRect通常用于描述倾斜的边界框,它包含中心点、宽度、高度以及旋转角度等信息,并非图像像素数据结构。 如果你想要计算一个区域(由RotatedRect所描述的)内图像的平均亮度或颜色值,你需要首先通过OpenCV获取该区域内的像素。这通常涉及到读取原始图像,裁剪出旋转矩形对应的部分,然后对这些像素进行累加并除以面积来得到平均值。 以下是基本步骤: 1. 使用`getPoints()`方法从RotatedRect获取四边形顶点。 2. 使用`Mat::Rect`创建一个矩形区域,并将其与原图进行位运算,提取出旋转矩形区域。 3. 读取这个区域的像素数据。 4. 对每个像素的RGB值求,然后除以像素数得到平均亮度。 由于涉及的具体编程操作会依赖于OpenCV版本使用的编程语言(如C++或Python),这里提供一个简化的伪代码示例: ```python import cv2 import numpy as np # 假设img是你的图像,rot_rect是RotatedRect对象 # 获取四边形顶点 points = rot_rect.getPoints() # 创建一个与原图大小相同的矩阵作为目标区域 region = np.zeros_like(img) # 使用OpenCV的fillConvexPoly填充区域 cv2.fillConvexPoly(region, points, (255, 255, 255)) # 计算平均亮度 brightness_sum = np.sum(region) area = region.shape[0] * region.shape[1] avg_brightness = brightness_sum / area
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值