旋转框(obb)目标检测计算iou的方法

news2024/12/23 0:05:25

首先先定义一组多边形,这里的数据来自前后帧的检测结果

 pre = [[[860.0, 374.0], [823.38, 435.23], [716.38, 371.23], [753.0, 310.0]],
         [[829.0, 465.0], [826.22, 544.01], [684.0, 539.0], [686.78, 459.99]],
         [[885.72, 574.95], [891.0, 648.0], [725.0, 660.0], [719.72, 586.95]],
         [[1164.0, 406.0], [1101.05, 410.72], [1095.0, 330.0], [1157.95, 325.28]],
         [[953.04, 102.78], [955.04, 138.78], [915.0, 141.0], [913.0, 105.0]],
         [[1173.0, 524.0], [1104.0, 524.0], [1104.0, 437.0], [1173.0, 437.0]],
         [[879.0, 297.0], [831.45, 340.49], [756.0, 258.0], [803.55, 214.51]],
         [[1136.79, 226.81], [1176.33, 263.31], [1111.54, 333.5], [1072.0, 297.0]],
         [[835.42, 225.76], [790.0, 251.0], [750.66, 180.19], [796.08, 154.95]],
         [[887.0, 196.0], [839.04, 208.16], [821.0, 137.0], [868.96, 124.84]],
         [[1033.0, 109.0], [1027.07, 142.01], [988.0, 135.0], [993.93, 101.99]],
         [[1056.0, 83.0], [1093.09, 90.53], [1080.0, 155.0], [1042.91, 147.47]],
         [[1064.01, 155.84], [1104.0, 158.0], [1099.99, 232.16], [1060.0, 230.0]],
         [[1087.06, 118.88], [1124.0, 137.0], [1097.94, 190.12], [1061.0, 172.0]]]
    post = [[[860.44, 373.25], [825.0, 434.0], [716.56, 370.75], [752.0, 310.0]],
         [[829.0, 466.0], [825.64, 545.03], [684.64, 539.03], [688.0, 460.0]],
         [[884.04, 575.0], [889.0, 649.0], [724.96, 660.0], [720.0, 586.0]],
         [[1163.0, 406.0], [1100.0, 410.0], [1094.92, 329.94], [1157.92, 325.94]],
         [[953.0, 103.0], [955.56, 137.96], [914.56, 140.96], [912.0, 106.0]],
         [[1173.0, 524.0], [1104.0, 524.0], [1104.0, 438.0], [1173.0, 438.0]],
         [[880.0, 297.0], [831.0, 342.0], [755.34, 259.61], [804.34, 214.61]],
         [[1137.31, 226.66], [1177.0, 263.0], [1112.0, 334.0], [1072.31, 297.66]],
         [[887.06, 194.23], [840.0, 207.0], [820.94, 136.77], [868.0, 124.0]],
         [[836.69, 224.57], [792.69, 251.57], [750.0, 182.0], [794.0, 155.0]],
         [[1033.0, 106.0], [1030.0, 143.0], [987.95, 139.59], [990.95, 102.59]],
         [[1055.95, 83.27], [1094.0, 91.0], [1081.0, 155.0], [1042.95, 147.27]],
         [[1064.0, 155.0], [1105.02, 156.05], [1103.02, 234.05], [1062.0, 233.0]],
         [[1081.72, 120.74], [1120.0, 135.0], [1101.0, 186.0], [1062.72, 171.74]]]

其中的每个列表元素代表一个多边形,列表中包含四个元素,分别代表多边形的顶点坐标

    import numpy as np
    import cv2
    # 创建一个全白图像
    image = np.ones((1080, 1920, 3), dtype=np.uint8) * 255

    for i, poly in enumerate(pre):
        polygon_list = np.array(poly, np.int32)
        cv2.drawContours(image, contours=[polygon_list], contourIdx=-1, color=(0, 0, 255), thickness=2)
    for i, poly in enumerate(post):
        polygon_list = np.array(poly, np.int32)
        cv2.drawContours(image, contours=[polygon_list], contourIdx=-1, color=(255, 0, 0), thickness=2)

    cv2.imshow("Image", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

用opencv将这些坐标画出来:

方法一

使用opencv内置函数计算iou

    import math
    
    def poly2rbox(polys):
        """
        Trans poly format to rbox format.
        """
        assert polys.shape[-1] == 8
        rboxes = []
        for poly in polys:
            poly = np.float32(poly.reshape(4, 2))
            (x, y), (w, h), angle = cv2.minAreaRect(poly)  # θ ∈ [0, 90]
            rboxes.append([x, y, w, h, angle])
        return np.array(rboxes)


    def bbox_overlaps(boxes, query_boxes):
        """ Calculate IoU(intersection-over-union) and angle difference for each input boxes and query_boxes. """
        if isinstance(boxes, list):
            boxes = np.array(boxes)
        if isinstance(query_boxes, list):
            query_boxes = np.array(query_boxes)
        N = boxes.shape[0]
        K = query_boxes.shape[0]
        boxes = np.round(boxes, decimals=2)
        query_boxes = np.round(query_boxes, decimals=2)
        overlaps = np.reshape(np.zeros((N, K)), (N, K))
        delta_theta = np.reshape(np.zeros((N, K)), (N, K))

        for k in range(K):
            rect1 = ((query_boxes[k][0], query_boxes[k][1]),
                     (query_boxes[k][2], query_boxes[k][3]),
                     query_boxes[k][4])
            for n in range(N):
                rect2 = ((boxes[n][0], boxes[n][1]),
                         (boxes[n][2], boxes[n][3]),
                         boxes[n][4])
                # can check official document of opencv for details
                num_int, points = cv2.rotatedRectangleIntersection(rect1, rect2)
                S1 = query_boxes[k][2] * query_boxes[k][3]
                S2 = boxes[n][2] * boxes[n][3]
                if num_int == 1 and len(points) > 2:
                    s = cv2.contourArea(cv2.convexHull(points, returnPoints=True))
                    overlaps[n][k] = s / (S1 + S2 - s)
                elif num_int == 2:
                    overlaps[n][k] = min(S1, S2) / max(S1, S2)
                delta_theta[n][k] = np.abs(query_boxes[k][4] - boxes[n][4])
        return overlaps, delta_theta
    
    pre = poly2rbox(np.array(pre).reshape(-1,8))
    post = poly2rbox(np.array(post).reshape(-1,8))
    overlaps = bbox_overlaps(pre, post)[0]
    print(overlaps)

运行结果如下: 

方法二

使用shapely

    from shapely.geometry import Polygon
    def calculate_iou(poly1, poly2):
        # 计算两个多边形的交集面积
        intersection_area = calculate_intersection(poly1, poly2)
        # 计算两个多边形的并集面积
        union_area = calculate_union(poly1, poly2)
        # 计算IoU值
        iou = intersection_area / union_area
        return iou

    def calculate_intersection(poly1, poly2):
        # 计算多边形的交集面积
        # 这里使用你选择的多边形交集计算方法,例如使用Shapely库的intersection()函数
        intersection = poly1.intersection(poly2)
        intersection_area = intersection.area
        return intersection_area

    def calculate_union(poly1, poly2):
        # 计算多边形的并集面积
        # 这里使用你选择的多边形并集计算方法,例如使用Shapely库的union()函数
        union = poly1.union(poly2)
        union_area = union.area
        return union_area

    def bbox_overlaps_shapely(boxes, query_boxes):
        """ Calculate IoU(intersection-over-union) and angle difference for each input boxes and query_boxes. """
        if isinstance(boxes, list):
            boxes = np.array(boxes)
        if isinstance(query_boxes, list):
            query_boxes = np.array(query_boxes)
        N = boxes.shape[0]
        K = query_boxes.shape[0]
        boxes = np.round(boxes, decimals=2)
        query_boxes = np.round(query_boxes, decimals=2)
        overlaps = np.reshape(np.zeros((N, K)), (N, K))
        delta_theta = np.reshape(np.zeros((N, K)), (N, K))

        for k in range(K):
            q_box = Polygon(query_boxes[k].reshape(-1, 2).tolist())
            for n in range(N):
                d_box = Polygon(boxes[n].reshape(-1, 2).tolist())
                overlaps[n][k] = calculate_iou(q_box, d_box)
        return overlaps, delta_theta

    overlaps = bbox_overlaps_shapely(np.array(pre).reshape(-1,8),np.array(post).reshape(-1,8))[0]
    print(overlaps)

运行结果如下:

方法三

cuda内置的函数,需要编译环境,就不展开了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1274078.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubantu配置网卡ip

1.ifconfig查看网卡 2. vi /etc/network/interfaces auto ens33 # 网卡名 iface ens33 inet static # 注意网卡名 address 192.168.43.10 # 配置ip地址 netmask 255.255.255.0 # 掩码 gateway 192.168.43.1 # 网关 3.重启网卡 ifconfig ens33 down ifco…

UG\NX二次开发 获取对象上属性的锁定状态UF_ATTR_ask_locked

文章作者:里海 来源网站:里海NX二次开发3000例专栏 感谢粉丝订阅 感谢 2301_80435318 开发 订阅本专栏,非常感谢。 简介 设置对象上属性的锁定状态UF_ATTR_set_locked,需要先在“用户默认设置”中勾选“通过NX Open锁定属性”&…

基于单片机的电子密码锁设计

1.设计任务 利用AT89C51单片机为核心控制元件,设计一个简易的电子密码锁,可设置四位密码,输入错误三次,报警灯亮起(红灯亮起),输入正确,绿灯闪烁三次。可通过LCD显示屏查看密码&…

抑制过拟合——从梯度的角度看LayerNorm的作用

抑制过拟合——从梯度的角度看LayerNorm的作用 Normalization的目的 LayerNorm & BatchNorm 可视化分析LayerNorm 分析loss 分析梯度 在深入探索transformer模型时,一个不可忽视的组成部分便是LayerNorm,它在模型的优化过程中起着关键作用。相比…

智能优化算法应用:基于平衡优化器算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于平衡优化器算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于平衡优化器算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.平衡优化器算法4.实验参数设定5.算法结果…

Android Bitmap裁剪/压缩/缩放到限定的最大宽高值,Kotlin

Android Bitmap裁剪/压缩/缩放到限定的最大宽高值&#xff0c;Kotlin private fun cropImage(image: Bitmap): Bitmap {val maxWidth 1024 //假设宽度最大值1024val maxHeight 1024 //假设高度最大值1024val width image.widthval height image.heightif (width < maxWi…

opencv知识库:cv2.add()函数和“+”号运算符

需求场景 现有一灰度图像&#xff0c;需求是为该图像增加亮度。 原始灰度图像 预期目标图像 解决方案 不建议的方案——“”运算符 假设我们需要为原始灰度图像的亮度整体提升88&#xff0c;那么利用“”运算符的源码如下&#xff1a; import cv2img_path r"D:\pych…

git的版本控制流程

1、git是一款版本控制工具 例如我们常用的淘宝&#xff0c;每次升级&#xff0c;版本号就会加一。那么我们怎么控制版本号呢&#xff1f; --使用git。 2、最常使用的git指令 git add . 暂存 git commit -m"***" 提交到本地 git pull 将远程仓库代码下拉到本地 git …

基于GAN的多尺度门合并多模态MRI图像合成

Multi-Modal MRI Image Synthesis via GAN With Multi-Scale Gate Mergence 基于GAN的多尺度门合并多模态MRI图像合成背景贡献实验方法生成器gate mergence (GM) strategy&#xff08;门控融合策略&#xff09;判别器 损失函数Thinking 基于GAN的多尺度门合并多模态MRI图像合成…

从零开始部署一个网站详细图文教程——腾讯云的服务器、SSL证书,阿里云的域名,七牛云的对象存储、CDN等

文章目录 前期准备连接服务器配置Golang环境安装配置MySQL安装配置Redis安装配置Nginx安装Node域名解析SSL证书下载启动项目配置CDN加速总结 前期准备 云服务器&#xff08;必备&#xff09;、已经备案的域名&#xff08;必备&#xff09;&#xff0c;已签发的SSL证书&#xf…

plt创建指定色系

1、创建不连续色系 import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap# 定义颜色的RGB值 colors [(0.2, 0.4, 0.6), # 蓝色(0.8, 0.1, 0.3), # 红色(0.5, 0.7, 0.2),(0.3,0.5,0.8)] # 绿色# 创建色系 cmap ListedColormap(colors)# 绘制…

STM32USART+DMA实现不定长数据接收/发送

STM32USARTDMA实现不定长数据接收 CubeMX配置代码分享实践结果 这一期的内容是一篇代码分享&#xff0c;CubeMX配置介绍&#xff0c;关于基础的内容可以往期内容 夜深人静学32系列11——串口通信夜深人静学32系列18——DMAADC单/多通道采集STM32串口重定向/实现不定长数据接收 …

3D点云目标检测:VoxelNex解读

VoxelNext 通用检测器 vs VoxelNext一、3D稀疏卷积模块1.1、额外的两次下采样消融实验结果代码 1.2、稀疏体素删减消融实验&#xff1a;代码 二、稀疏体素高度压缩代码 三、稀疏预测head 通用检测器 vs VoxelNext 一、3D稀疏卷积模块 1.1、额外的两次下采样 使用通用的3D spa…

2023年亚太杯数学建模C题新能源汽车(思路模型代码)

一、翻译 新能源汽车是指采用先进的技术原理、新技术和新结构&#xff0c;以非常规车用燃料&#xff08;非常规车用燃料是指汽油和柴油以外的燃料(非常规车用燃料是指汽油和柴油以外的燃料&#xff09;&#xff0c;并集成了汽车动力控制和驱动等先进技术的汽车。新能源汽车包括…

Gitee 之初体验(上)

我们在项目开发或者自己学习的时候&#xff0c;总会存在这样的问题&#xff1a; 在一台电脑上编写完代码&#xff0c;想要再另外一台电脑上再去写&#xff0c;再或者和其他人一起协作等等场合&#xff0c;代码传来传去很麻烦。 这个时候&#xff0c;我们就可以去使用代码管理工…

在java java.util.Date 已知逝去时间怎么求年月日 数学计算不用其他方法

在Java中&#xff0c;使用java.util.Date类已知逝去时间求年月日的方法如下&#xff1a; 首先&#xff0c;获取当前时间和逝去时间之间的毫秒数差值&#xff0c;可以使用Date类的getTime()方法获得时间戳。 将毫秒数转换为秒数&#xff0c;并计算出总共的天数。 根据总共的天…

计算机网络:应用层(上篇)

文章目录 前言一、应用层协议原理1.网络应用的体系结构2.进程通信 二、Web与HTTP1.HTTP概况2.HTTP连接3.HTTP请求报文4.用户-服务器状态&#xff1a;cookies5.Web缓存&#xff08;代理服务器&#xff09; 三、FTP&#xff1a;文件传输协议1.FTP&#xff1a;控制连接与数据连接分…

ClassNotFoundException: org.apache.hive.spark.client.Job

hive使用的是3.13版本&#xff0c;spark是3.3.3支持hadoop3.x hive将engine从mr改成spark&#xff0c;通过beeline执行insert、delete时一直报错&#xff0c;sparkTask rpc关闭&#xff0c; 查看yarn是出现ClassNotFoundException: org.apache.hive.spark.client.Job。 开始…

怎么一键批量转换PDF/图片为Excel、Word,从而提高工作效率?

在处理大量PDF、图片文件时&#xff0c;我们往往需要将这些文件转换成Word或Excel格式以方便编辑和统计分析。此时&#xff0c;金鸣表格文字识别大师这款工具可以发挥巨大作用。下面&#xff0c;我们就来探讨如何使用它进行批量转换&#xff0c;以实现高效处理。 一、准备工作…

linux服务器环境搭建(使用yum 安装mysql、jdk、redis)

一:yum的安装 1:下载yum安装包并解压 wget http://yum.baseurl.org/download/3.2/yum-3.2.28.tar.gz tar xvf yum-3.2.28.tar.gz 2.进入yum-3.2.28文件夹中进行安装,执行安装指令 cd yum-3.2.28 sudo apt install yum 3.更新版本 yum check-update yum update yum cle…