IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> IOU原理详解代码复现 python numpy/pytorch -> 正文阅读

[Python知识库]IOU原理详解代码复现 python numpy/pytorch

IOU

IOU就是两个图像的交并比,这是一个图像检测中很重要的概念,想要构建YOLO系列的目标检测对应函数,就必须要先写一个计算交并比的程序,什么是交并比,就是两个图像交集的面积比上并集的面积,如果用下面的图来举例子的话。
请添加图片描述
I O U = S 3 S 1 + S 2 ? S 3 IOU = \frac{S_3}{S_1+S_2-S_3} IOU=S1?+S2??S3?S3??

由于目标检测的过程中我们大部分用的都是矩形框,根据算法我们都是知道两个矩形的左上角点的坐标和矩形的高和宽请添加图片描述
根据计算IOU的通用办法我们只需要再算出两个矩形的右下角坐标,用这四个坐标就可以确定并算出交集部分的左上角坐标和右下角坐标,这样就可以得到交集区域的宽和高,进一步就能算出交集区域的面积,算出了交集区域的面积,就可以算出交并比。
请添加图片描述
这里会有一个很明显的问题就是随着求交并比的两个大的矩形的位置的不同,交集矩形的坐标的表示方式也会有不同,接下来我们遍历一下所有的情况,最后找出一个规律。下面这个图画的累死我了,公式还各种变形,就这样吧哪天再改。

在这里插入图片描述

好的接下来看一下规律,交集区域的左上角坐标都是由两个相交矩形的左上角坐标决定的,同理右下角的坐标都是由相交矩形的右下角坐标决定的,这里可以停下来仔细看一下上面的图思考一下,验证一下下面的规律,这样有助于代码的理解。

  • 左上角点的横坐标 x _ b o x x\_box x_box x x x x 1 x_1 x1?的最小值
  • 左上角点的纵坐标 y _ b o x y\_box y_box y y y y 1 y_1 y1?的最小值
  • 右下角点的横坐标 x _ w _ b o x x\_w\_box x_w_box x _ w x\_w x_w x 1 _ w 1 x_1\_w_1 x1?_w1?的最大值
  • 右下角点的纵坐标 y _ h _ b o x y\_h\_box y_h_box y _ h y\_h y_h y 1 _ h 1 y_1\_h_1 y1?_h1?的最大值

在知道了左上角标和右下角标之后就可以算出交集的宽和高,然后就可以算出交集的面积,则就能求出总体的IOU

b o x _ w = x _ w _ b o x ? x _ b o x box\_w=x\_w\_box-x\_box box_w=x_w_box?x_box
b o x _ h = y _ h _ b o x ? y _ b o x box\_h=y\_h\_box-y\_box box_h=y_h_box?y_box

S 3 = b o x _ w × b o x _ h S_3=box\_w×box\_h S3?=box_w×box_h

上面都是相交的情况那如果两个矩形没有相交呢,那 b o x _ w box\_w box_w b o x _ h box\_h box_h算出来一定会有至少一个变量小于0,我们用一种情况举例,其他情况也可以自己尝试的在纸上画一画,验证一下。

请添加图片描述
也就是说只要我们判断到计算出来的宽和高有小于0的那就证明两个矩形框并没有交集也就是IOU为0,明确了计算规则和,不相交的判断条件。接下来写代码,如果代码看起来感觉还是稍微有一点吃力,那就再自己看一下上面的内容,自己画画吸收的会更好。

numpy单独计算版本

import numpy as np

# coordinate = [x,y,w,h]

def IOU(coordinate,coordinate1):
    x = coordinate[0]
    y = coordinate[1]
    w = coordinate[2]
    h = coordinate[3]

    x1 = coordinate1[0]
    y1 = coordinate1[1]
    w1 = coordinate1[2]
    h1 = coordinate1[3]

    x_box = np.max([x,x1])
    y_box = np.max([y,y1])

    x_w_box = np.min([x+w, x1+w1])
    y_h_box = np.min([y+h, y1+h1])

    box_w = x_w_box - x_box
    box_h = y_h_box - y_box

    if box_w<0 or box_h<0:
        return 0
        
    box_s = box_w*box_h
    iou = box_s/(w*h + w1*h1 -box_s)
    return iou


if __name__ == "__main__":

    x = np.array([1,1,1,1])
    y = np.array([0.5,0.5,1,1])
    y1 = np.array([4,4,1,1])

    print(IOU(x,y))
    #0.14285714285714285
    print(IOU(x,y1))
    #0

numpy批量计算版本

单独计算版本有个问题,就是在实际的目标检测中由于有minibatch维度,我们需要同时计算多组坐标的IOU但是单独计算版本只能计算一个坐标的IOU,如果想计算多组坐标的IOU就需要循环依次运算,我们知道for运算在python中是非常浪费时间的,所以在训练中每次都需要大量调用for循环无疑是不明智的所以我们需要对输入进来的多组坐标进行同时运算并输出一组IOU值。

这里将if语句换成了np.where语句。作用是判断数组中的是否有元素满足某一条件,满足怎么样,不满足怎么样,根据我们的任务目标当我们检测到目标区域的长和宽的数组中有小于等于0的数那我们就将该负数换成0这样最后计算出来的对应的IOU就是0.这块可以简单思考一下,如果实在不理解去搜一下np.where的语法。

import numpy as np

# coordinate = [x,y,w,h]
def IOU(coordinate,coordinate1):
    x = coordinate[:,0]
    y = coordinate[:,1]
    w = coordinate[:,2]
    h = coordinate[:,3]


    x1 = coordinate1[:,0]
    y1 = coordinate1[:,1]
    w1 = coordinate1[:,2]
    h1 = coordinate1[:,3]

    x_box = np.max([x,x1],axis=0)
    y_box = np.max([y,y1],axis=0)
    q = x+w
    q1 = x1+w1

    x_w_box = np.min([x+w, x1+w1])
    y_h_box = np.min([y+h, y1+h1])

    box_w = x_w_box - x_box
    box_h = y_h_box - y_box

    box_w = np.where(box_w>0,box_w,0)
    box_h = np.where(box_h>0,box_h,0)

    box_s = box_w*box_h

    iou = box_s/(w*h + w1*h1 -box_s)

    return iou


if __name__ == "__main__":

    x = np.array([[1,1,1,1],[1,1,1,1]])
    y = np.array([[0.5,0.5,1,1],[4,4,1,1]])

    print(IOU(x,y))
	#[0.14285714 0.        ]

pytorch批量计算版本

numpy批量计算版本还有一个问题,那就是我们在做训练的时候是需要用到框架的,为了让数据在GPU上运算我们得把数据都转换成张量,所以实际上是需要一个使用框架的函数来运算IOU的代码。很简单只需要把np换成torch就好了

import torch
# coordinate = [x,y,w,h]

def IOU(coordinate:torch.Tensor,coordinate1:torch.Tensor):
    x = coordinate[:, 0]
    y = coordinate[:, 1]
    w = coordinate[:, 2]
    h = coordinate[:, 3]

    x1 = coordinate1[:, 0]
    y1 = coordinate1[:, 1]
    w1 = coordinate1[:, 2]
    h1 = coordinate1[:, 3]

    x_box = torch.max(x,x1)
    y_box = torch.max(y,y1)

    x_w_box = torch.min(x+w, x1+w1)
    y_h_box = torch.min(y+h, y1+h1)

    box_w = x_w_box - x_box
    box_h = y_h_box - y_box

    box_w = torch.where(box_w>0,box_w,0)
    box_h = torch.where(box_h>0,box_h,0)

    box_s = box_w*box_h
    iou = box_s/(w*h + w1*h1 -box_s)

    return iou

if __name__ == "__main__":

    x = torch.Tensor([[1,1,1,1],[1,1,1,1],[1,1,1,1]])
    y = torch.Tensor([[0.5,0.5,1,1],[4,4,1,1],[1,1,1,1]])

    print(IOU(x,y))
	#tensor([0.1429, 0.0000, 1.0000])

结束

从这篇开始开始尝试进军目标检测领域,加油代码人!

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:11:19  更:2022-10-22 21:11:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 7:00:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码