OpenCV 实现可交互旋转矩形编辑工具:支持移动、旋转与缩放

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

项目中有需要用到在图片上面绘制旋转矩形框,用于得到框选区域。一般的矩形框是不带旋转角度。目前没有找到比较好用的旋转矩形框,这个是博主结合自身需求,通过鼠标控制,在图片上绘制出来矩形框,可以和鼠标进行交互。下面是示例图片,这个是一个简单demo,后续你可以根据得到框,把对应数据取出来,也可以把图片扣出来,根据角度,做一个仿射变换得到矫正后的正的矩形。

示例gif图片,这个是最后代码运行出来效果。可以旋转,移动,缩放。
请添加图片描述

在计算机视觉领域,旋转矩形的标注与编辑是一个常见需求,无论是目标检测中的边界框标注,还是图像测量中的区域划定,都离不开直观易用的旋转矩形交互工具。本文将基于 OpenCV 和 NumPy 实现一个功能完整的可交互旋转矩形编辑工具,支持矩形的移动、旋转和多方式缩放操作,并详细解析其核心技术原理。


一.工具核心功能概述

本工具实现了一个可视化的旋转矩形编辑界面,主要功能包括:

  • 实时显示旋转矩形及各类控制点(中心、旋转手柄、边中点、角落点)

  • 鼠标交互操作:

    • 拖动中心控制点移动矩形

    • 拖动旋转手柄(蓝色)旋转矩形

    • 拖动边中点(紫色)沿垂直边方向缩放

    • 拖动角落点(青色)同时调整矩形宽高

  • 自动处理坐标转换与旋转逻辑,确保交互自然流畅

二.完整代码示例

下面是完整代码示例,直接复制粘贴可以运行

import cv2
import numpy as np

# 全局变量
rects = []  # 存储所有矩形,每个矩形包含center, size, angle
selected_rect_idx = None  # 当前选中的矩形索引
drawing = False  # 是否正在拖动
current_mode = None  # 'move', 'rotate', 'resize'
selected_handle = None  # 选中的手柄类型
initial_mouse_pos = None  # 初始鼠标位置
initial_rect_params = None  # 初始矩形参数
initial_mouse_local = None  # 初始鼠标局部坐标


def compute_handles(center, size, angle):
    """计算矩形的控制点坐标"""
    w, h = size[0] / 2, size[1] / 2

    # 计算旋转手柄的距离为矩形对角线长度的一半
    handle_distance = np.sqrt(w**2 + h**2) * 0.5

    return {
   
   
        'center': (int(center[0]), int(center[1])),
        'rotate_handle': (
            int(local_to_global(handle_distance, 0, center, angle)[0]),
            int(local_to_global(handle_distance, 0, center, angle)[1])
        ),
        'left': (
            int(local_to_global(-w, 0, center, angle)[0]),
            int(local_to_global(-w, 0, center, angle)[1])
        ),
        'right': (
            int(local_to_global(w, 0, center, angle)[0]),
            int(local_to_global(w, 0, center, angle)[1])
        ),
        'top': (
            int(local_to_global(0, h, center, angle)[0]),
            int(local_to_global(0, h, center, angle)[1])
        ),
        'bottom': (
            int(local_to_global(0, -h, center, angle)[0]),
            int(local_to_global(0, -h, center, angle)[1])
        ),
        'corner': (
            int(local_to_global(w, h, center, angle)[0]),
            int(local_to_global(w, h, center, angle)[1])
        )
    }


def draw_rotated_rect(img, rect, is_selected=False):
    """绘制旋转矩形及控制点"""
    center = rect['center']
    size = rect['size']
    angle = rect['angle']

    # 绘制旋转矩形
    rect_obj = ((center[0], center[1]), (size[0], size[1]), angle)
    box = cv2.boxPoints(rect_obj)
    box = np.intp(box)
    color = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值