当前位置: 首页 > news >正文

Opencv---RotatedRect

在Robomaster比赛中,RotatedRect类极为常用,灯条、装甲板以至于整车都可以用RotatedRect类来表示。

一、基本概念与用途

RotatedRect 是OpenCV中用于表示旋转矩形的类,常用于需要描述矩形方向(角度)的场景,如:

  • 目标检测中的倾斜边界框(如灯条、装甲板、车牌、文本检测)。
  • 形状分析中的方向感知(如椭圆拟合后的方向)。
  • 几何变换中的旋转矩形表示。

与普通轴对齐矩形 Rect 的区别:

  • Rect 仅包含位置和尺寸(轴对齐)。
  • RotatedRect 包含中心点、尺寸、旋转角度,可表示任意方向的矩形。
二、类定义与构造函数
1. 成员变量(C++)
class RotatedRect {
public:Point2f center;   // 中心点坐标(x, y)Size2f size;      // 矩形尺寸(宽, 高)float angle;      // 旋转角度(单位:度,逆时针为正)// 构造函数、成员函数...
};
2. 构造方式
  • 标准构造:通过中心点、尺寸、角度初始化。
    // C++
    RotatedRect rRect(Point2f(cx, cy), Size2f(w, h), angle);// Python
    rRect = cv2.RotatedRect((cx, cy), (w, h), angle)
    
  • 从轮廓/点集拟合:通过 minAreaRect() 函数从点集计算最小面积旋转矩形。
    // C++
    vector<Point2f> points; // 轮廓点集
    RotatedRect rRect = minAreaRect(points);// Python
    rRect = cv2.minAreaRect(cnt)  # cnt为轮廓点集(numpy数组)
    
三、核心知识点讲解
1. 旋转角度(angle)的定义
  • 方向:矩形的水平轴(长边)与图像坐标系x轴的夹角,逆时针为正
  • 范围约定:OpenCV中 angle 通常位于 -90° < angle ≤ 0°。当矩形竖放时(高 > 宽),会自动交换宽高,并将角度调整为 -90° < angle ≤ 0°。例如:
    • 若原始宽=20,高=40,角度=30°,则实际存储为宽=40,高=20,角度=-60°(保证宽≥高,角度在约定范围)。
2. 顶点坐标计算(points()函数)

通过 RotatedRectpoints() 方法(C++)或 cv2.boxPoints()(Python)获取矩形的4个顶点,顺序为:

  1. 左上角顶点(中心点左侧,沿旋转方向第一个点)。
  2. 右上角顶点(中心点右侧,顺时针第二个点)。
  3. 右下角顶点
  4. 左下角顶点

示例代码

// C++
vector<Point2f> vertices;
rRect.points(vertices); // vertices包含4个顶点,顺序如上述// Python
vertices = cv2.boxPoints(rRect)  # 返回numpy数组,形状为(4,2)
3. 与轴对齐矩形(Rect)的转换
  • 获取包围旋转矩形的最小轴对齐矩形
    Rect boundRect = rRect.boundingRect2f(); // C++,返回浮点型Rect
    
    x, y, w, h = cv2.boundingRect(vertices.astype(int))  # Python,需先转换为整数顶点
    
  • 旋转矩形转普通矩形:仅取顶点坐标的极值,不保留角度信息。
4. 几何运算
  • 面积与周长
    float area = rRect.size.width * rRect.size.height; // 面积
    float perimeter = 2 * (rRect.size.width + rRect.size.height); // 周长(非旋转周长)
    
  • 旋转矩阵计算:以中心点为原点,计算旋转后的坐标变换矩阵:
    Mat rotationMat = getRotationMatrix2D(rRect.center, rRect.angle, 1.0); // 旋转矩阵
    
5. 绘制与可视化

通过顶点坐标绘制旋转矩形:

// C++
for (int i = 0; i < 4; i++) {line(img, vertices[i], vertices[(i+1)%4], Scalar(0, 255, 0), 2);
}// Python
for i in range(4):cv2.line(img, tuple(vertices[i].astype(int)), tuple(vertices[(i+1)%4].astype(int)), (0, 255, 0), 2)
6. 碰撞检测(两旋转矩形相交判断)

OpenCV未直接提供相交检测函数,需手动实现:

  1. 将旋转矩形转换为多边形(4顶点)。
  2. 使用 分离轴定理(SAT)多边形相交算法 判断是否相交。
  3. 示例思路:
    def is_rotated_rect_intersect(r1, r2):box1 = cv2.boxPoints(r1).astype(int)box2 = cv2.boxPoints(r2).astype(int)# 转换为凸多边形,使用cv2.pointPolygonTest判断点是否在另一多边形内for p in box1:if cv2.pointPolygonTest(box2, tuple(p), False) >= 0:return Truefor p in box2:if cv2.pointPolygonTest(box1, tuple(p), False) >= 0:return Truereturn False
    
四、注意事项与常见误区
  1. 角度与宽高的绑定关系

    • angle(-90°, 0] 时,size.width ≥ size.height(长边为水平轴)。
    • 若手动设置 angle > 0°size.width < size.height,OpenCV会自动调整宽高和角度,以保证约定范围。
  2. 顶点顺序的一致性

    • points() 返回的顶点顺序固定,可通过顺时针或逆时针顺序绘制闭合矩形。
  3. 浮点精度问题

    • 顶点坐标默认为浮点型,绘制时需转换为整数(astype(int)),避免亚像素误差。
  4. 与椭圆(Ellipse)的区别

    • RotatedRect 是矩形,Ellipse 是椭圆,拟合时根据形状选择工具(如 fitEllipse() 返回椭圆,minAreaRect() 返回矩形)。
五、应用场景示例
1. 目标检测中的倾斜边界框
# 假设检测到轮廓cnt,提取旋转矩形
cnt = ... # 轮廓点集
rRect = cv2.minAreaRect(cnt)
vertices = cv2.boxPoints(rRect).astype(int)
cv2.polylines(img, [vertices], isClosed=True, color=(0, 255, 0), thickness=2)
2. 形状方向分析
// 计算矩形的主方向(角度)
float angle = rRect.angle;
if (angle < -45) angle += 90; // 转换为0°~90°范围的方向角
3. 图像旋转后的边界框调整
# 对图像旋转θ角后,重新计算旋转矩形的位置
def rotate_image_with_box(img, rRect, theta):rows, cols = img.shape[:2]M = cv2.getRotationMatrix2D(rRect.center, theta, 1.0)rotated_img = cv2.warpAffine(img, M, (cols, rows))# 调整旋转矩形的角度new_rRect = cv2.RotatedRect(rRect.center, rRect.size, rRect.angle + theta)return rotated_img, new_rRect
六、跨语言差异(C++ vs Python)
特性C++Python
构造函数参数Point2f, Size2f, float元组 (cx, cy), (w, h), float
顶点获取points(vector<Point2f>&)cv2.boxPoints(rRect) 返回numpy数组
序列化需手动存储成员变量可转为元组或JSON存储
七、数学原理补充(顶点坐标推导)

设中心点为 (c_x, c_y),尺寸为 (w, h),角度为 θ,则4个顶点坐标可通过旋转矩阵计算:

  • 原始矩形(未旋转)的顶点相对于中心点的坐标:
    (±w/2, ±h/2)(左上:(-w/2, -h/2),右上:(w/2, -h/2),右下:(w/2, h/2),左下:(-w/2, h/2))。

  • 旋转θ角后的坐标:

    [ x ′ y ′ ] = [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] [ x y ] + [ c x c y ] \begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} \cosθ & -\sinθ \\ \sinθ & \cosθ \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} + \begin{bmatrix} c_x \\ c_y \end{bmatrix} [xy]=[cosθsinθsinθcosθ][xy]+[cxcy]

  • 代入4个顶点的原始坐标,得到旋转后的绝对坐标。


我们太看重了白昼,又太忽视着黑夜。生命,至少有一半是在黑夜中呀。 —史铁生

相关文章:

  • 2025长三角数学建模ABC题赛题已出!速拿
  • 关于vue彻底删除node_modules文件夹
  • 手写Tomcat(一)
  • java接口自动化(四) - 企业级代码管理工具Git的应用
  • 黑马k8s(十二)
  • 【RocketMQ 生产者和消费者】- 生产者启动源码-上报生产者和消费者心跳信息到 broker(3)
  • 复盘20250522
  • LeetCode 76题「最小覆盖子串」
  • 从零基础到最佳实践:Vue.js 系列(8/10):《性能优化与最佳实践》
  • Spring AI 之提示词
  • 论文解读 | 《桑黄提取物对小鼠宫颈癌皮下移植瘤的抑制及机制研究》
  • 红黑树插入的旋转变色
  • 使用C语言实现字符串拷贝与程序编译全解析 ——从strcopy实现到程序内存布局,一文掌握核心知识
  • FPGA通信之VGA
  • 【结构体宏定义】C语言结构体与宏定义:传感器配置的巧妙结合
  • transformer网络
  • 全栈开发中主流 AI 编程辅助工具的实践与对比分析20250522
  • thinkpad x220降频到0.7Ghz解决办法
  • 小白的进阶之路系列之三----人工智能从初步到精通pytorch计算机视觉详解下
  • Python 训练 day31
  • 互动平台抽手机/东莞网站优化公司
  • 玩弄已婚熟妇做爰网站/百度推广售后电话
  • xp做的网站有连接限制/电商网站推广方案
  • wordpress免费手机主题/关键词优化如何做
  • python语言好学吗/seo怎么优化效果更好
  • 济南网站建设培训学校/百度网盘下载安装