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

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

 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.mfbz.cn/a/206061.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

服务器之间的conda环境迁移

有的时候python环境中可能包含了我们编译好的很多库文件,如果在别的服务器想直接使用环境就会比较困难些。最好的办法就是直接迁移环境。而传统的迁移方法导出“*.yaml”环境配置的这种方法,实际是需要重新安装环境,对于这种安装好的环境是不…

分布式运用之Filebeat+Kafka+ELK 的服务部署

1. Kafka 架构深入了解 1.1 Kafka 工作流程及文件存储机制 Kafka 中消息是以 topic 进行分类的,生产者生产消息,消费者消费消息,都是面向 topic 的。 topic 是逻辑上的概念,而 partition 是物理上的概念,每个 parti…

Vue中 实现自定义指令(directive)及应用场景

一、Vue2 1. 指令钩子函数 一个指令定义对象可以提供如下几个钩子函数 (均为可选): bind 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已…

RNN:文本生成

文章目录 一、完整代码二、过程实现2.1 导包2.2 数据准备2.3 字符分词2.4 构建数据集2.5 定义模型2.6 模型训练2.7 模型推理 三、整体总结 采用RNN和unicode分词进行文本生成 一、完整代码 作者在文章开头地址中使用C实现了这一过程,为了便于理解,这里我…

使用vscode的remotessh插件远程连接的时候被要求重复输入密码

问题描述: 需要远程连接服务器,使用ssh,我用到的是vscode里面的remotessh插件。配置好config以后 HostHostNameUserPortIdentifyFile进入到了vscode的密码登录界面,但是一直被要求循环输入密码,很奇怪,去…

防爆执法记录仪、防爆智能安全帽助力海上钻井平台远程可视化监管平台建设

推动远程安全管理,海上钻井"视"界拓新—防爆执法记录仪与防爆智能安全帽的创新应用 在海上钻井作业领域,安全生产一直是萦绕在每一个业者心头的重大课题。由于环境的恶劣及作业的特殊性,一旦发生安全事故,其后果往往极…

CentOS 7安装Java 8

前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱 要在CentOS 7上安装Java 8,请按照以下步骤操作: 打开终端并以root身份登录。 更新系统软件包: …

Mybatis 的简单运用介绍

Mybatis 用于操作数据库 操作数据库肯定需要: 1.SQL语句 2.数据库对象和 java 对象的映射 接下来我们看看怎么使用 Mybatis 我们先搞一些数据库内容 然后将其这些内容和Java对象进行映射 再创建一个类实现 select * from 再写一个类证明上述代码是否可以实现 别忘了在appli…

中信建投在金融电于化期刊发布 DataOps 实践

文 ‖ 中信建投证券股份有限公司 马丽霞 高宇航 李可 许哲 李海伟 近年来,数据的分析和应用对各行各工业的业务模式和竞争形态进行重塑,而积极应对挑战和顺应时代变化是各个市场参与者的必选项。作为资本市场数字化转型的领航者,中信建投证券…

python动态加载内容抓取问题的解决实例

问题背景 在网页抓取过程中,动态加载的内容通常无法通过传统的爬虫工具直接获取,这给爬虫程序的编写带来了一定的技术挑战。腾讯新闻(https://news.qq.com/)作为一个典型的动态网页,展现了这一挑战。 问题分析 动态…

指针(2)

函数指针数组 函数指针数组是一个用来存放函数指针(地址)的数组。 如上图,是将两个函数指针存入数组中。如何写函数指针数组名呢?我们可以先写出函数指针类型int (*)(int,int)然后在(*)里面加上数组名[]即可。 指向函数指针数组…

面试题:什么是负载均衡?常见的负载均衡策略有哪些?

文章目录 一、负载均衡二、负载均衡模型分类三、CDN负载均衡四、LVS负载均衡4.1 LVS 支持的三种模式4.1.1 DR 模式4.1.2 TUN 模式4.1.3 NAT 模式 4.2 LVS 基于 Netfilter 的框架实现 五、负载均衡策略是什么六、常用负载均衡策略图解6.1 轮询6.2 加权轮询6.3 最少连接数6.4 最快…

Ubuntu使用Nginx部署前端项目——记录

安装nginx 依次执行以下两条命令进行安装: sudo apt-get update sudo apt-get install nginx通过查看版本号查看是否安装成功: nginx -v补充卸载操作: sudo apt-get remove nginx nginx-common sudo apt-get purge nginx nginx-common su…

解决:ModuleNotFoundError: No module named ‘xlrd‘

解决:ModuleNotFoundError: No module named ‘xlrd’ 文章目录 解决:ModuleNotFoundError: No module named xlrd背景报错问题报错翻译报错位置代码报错原因解决方法今天的分享就到此结束了 背景 在使用之前的代码时,报错: pin_r…

C 中的结构 - 存储、指针、函数和自引用结构

0. 结构体的内存分配 当声明某种类型的结构变量时,结构成员被分配连续(相邻)的内存位置。 struct student{char name[20];int roll;char gender;int marks[5];} stu1; 此处,内存将分配给name[20]、roll、gender和marks[5]。st1这…

11-30 JavaWeb

修改与删除操作 防止空指针异常 localhost:8080 -> 分页查询 修改流程:(先查后改(两个servlet)) 修改: 传用户id(用户id怎么得到 -> 循环一次得到一个user 对象 user对象里用user.getId()得到用户id) UpdateUserQueryServlet.java (…

「Verilog学习笔记」状态机-重叠序列检测

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网 读入数据移位寄存,寄存后的数据与序列数做对比,相等则flag为1,不等则为0 timescale 1ns/1nsmodule sequence_test2(input wire clk ,in…

计网Lesson5 - MAC 地址与 ARP

文章目录 M A C MAC MAC 地址1. M A C MAC MAC 地址的格式 2. M A C MAC MAC 地址的获取3. A R P ARP ARP 协议4. A R P ARP ARP 缓存5. R A R P RARP RARP M A C MAC MAC 地址 1. M A C MAC MAC 地址的格式 每个网卡都有一个 6 6 6 字节的 M A C MAC MAC 地址 M A C…

最大公约数的C语言实现xdoj31

时间限制: 1 S 内存限制: 1000 Kb 问题描述: 最大公约数(GCD)指某几个整数共有因子中最大的一个,最大公约数具有如下性质, gcd(a,0)a gcd(a,1)1 因此当两个数中有一个为0时,gcd是不为0的那个整数&#xff…

ios 逆向分分析,某业帮逆向算法(一)

用到工具: 爱思助手CrackerXL(砸壳软件)越狱手机ida反汇编软件分析login 的sign 签名算法中自己写算法 已知我们32位,我们不妨猜测是md5 ,那我们试图使用CC_MD5 ,这个是ios 中的标准库, 我们使用frida-trace 注入hook一下,看看有没有 经过 是经过了这个函数,密码也是…
最新文章