深度学习-目标检测之边界框bbox坐标转换公式汇总

news/2024/7/10 2:22:26 标签: 深度学习, 目标检测, 人工智能

深度学习


文章目录


尝试着写了一个可以转换任何维度的任意格式的bbox函数。

本程序目的是:
可以转换以下三种格式的输入数据 list,numpy,tensor,维度可以从0维到2维, 也就是shape为:(4,) (3, 4) torch.Size([4]) torch.Size([3, 4])的边界框数据

import numpy as np
import torch

#  ===============================================================================#
#  坐标转换系列函数
#  输入:可能是 列表、np矩阵、tensor矩阵 以下六个函数可以保证输入输出的维度一致
#  输入的维度可能是一个向量shape=(4,)(.T转置之后的到的是原变量)
#  ===============================================================================#
def ltwh2center(bbox):
    """

    :param bbox:[left, top, w, h]
    :return:[cx, cy, w, h]
    """
    if isinstance(bbox, list):
        bbox = np.array(bbox)

    if bbox.shape[-1] != 4:
        raise ValueError('bbox.shape[-1] should equal 4')
    else:
        if isinstance(bbox, np.ndarray):
            left, top, w, h = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            # cx=left+w/2; cy=top+h/2;w;h
            _bbox = np.stack([left + w / 2, top + h / 2, w, h], axis=-1)
            return _bbox

        if isinstance(bbox, torch.Tensor):
            left, top, w, h = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            # cx=left+w/2; cy=top+h/2;w;h
            _bbox = torch.stack((left + w / 2, top + h / 2, w, h), dim=-1)
            return _bbox


def ltwh2corner(bbox):
    """

    :param bbox:[left, top, w, h]
    :return:[left, top, right, bottom]
    """
    if isinstance(bbox, list):
        bbox = np.array(bbox)

    if bbox.shape[-1] != 4:
        raise ValueError('bbox.shape[-1] should equal 4')
    else:
        if isinstance(bbox, np.ndarray):
            left, top, w, h = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            # left; top; right=left+w; bottom=top+h
            _bbox = np.stack([left, top, left + w, top + h], axis=-1)
            return _bbox

        if isinstance(bbox, torch.Tensor):
            left, top, w, h = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            _bbox = torch.stack((left, top, left + w, top + h), dim=-1)
            return _bbox


def corner2ltwh(bbox):
    """

    :param bbox:[left, top, right, bottom]
    :return:[left, top, w, h]
    """
    if isinstance(bbox, list):
        bbox = np.array(bbox)

    if bbox.shape[-1] != 4:
        raise ValueError('bbox.shape[-1] should equal 4')
    else:
        if isinstance(bbox, np.ndarray):
            left, top, right, bottom = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            # left; top; w=right-left; h=bottom-top
            _bbox = np.stack([left, top, right - left, bottom - top], axis=-1)
            return _bbox

        if isinstance(bbox, torch.Tensor):
            left, top, right, bottom = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            _bbox = torch.stack((left, top, right - left, bottom - top), dim=-1)
            return _bbox


def corner2center(bbox):
    """

    :param bbox:[left, top, right, bottom]
    :return:[cx,cy, w, h]
    """
    if isinstance(bbox, list):
        bbox = np.array(bbox)

    if bbox.shape[-1] != 4:
        raise ValueError('bbox.shape[-1] should equal 4')
    else:
        if isinstance(bbox, np.ndarray):
            left, top, right, bottom = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            # cx=(left+right)/2; cy=(top+bottom)/2; w=right-left; h=bottom-top
            _bbox = np.stack([(left + right) / 2, (top + bottom) / 2, right - left, bottom - top], axis=-1)
            return _bbox

        if isinstance(bbox, torch.Tensor):
            left, top, right, bottom = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            _bbox = torch.stack(((left + right) / 2, (top + bottom) / 2, right - left, bottom - top), dim=-1)
            return _bbox


def center2corner(bbox):
    """

    :param bbox: [cx,cy,w,h]
    :return: [left, top, right, bottom]
    """
    if isinstance(bbox, list):
        bbox = np.array(bbox)

    if bbox.shape[-1] != 4:
        raise ValueError('bbox.shape[-1] should equal 4')
    else:
        if isinstance(bbox, np.ndarray):
            cx, cy, w, h = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            # left=cx-w/2; top=cy-h/2; right=cx+w/2; bottom=cy+h/2
            _bbox = np.stack([cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2], axis=-1)
            return _bbox

        if isinstance(bbox, torch.Tensor):
            cx, cy, w, h = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            _bbox = torch.stack((cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2), dim=-1)
            return _bbox


def center2ltwh(bbox):
    """

    :param bbox: [cx, cy, w, h]
    :return: [left, top, w, h]
    """
    if isinstance(bbox, list):
        bbox = np.array(bbox)

    if bbox.shape[-1] != 4:
        raise ValueError('bbox.shape[-1] should equal 4')
    else:
        if isinstance(bbox, np.ndarray):
            cx, cy, w, h = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            # left=cx-w/2; top=cy-h/2; w; h
            _bbox = np.stack([cx - w / 2, cy - h / 2, w, h], axis=-1)  # cx,cy,w,h
            return _bbox

        if isinstance(bbox, torch.Tensor):
            cx, cy, w, h = bbox[..., 0], bbox[..., 1], bbox[..., 2], bbox[..., 3]
            _bbox = torch.stack((cx - w / 2, cy - h / 2, w, h), dim=-1)  # 将数据坐标拼接起来
            return _bbox


if __name__ == '__main__':
    print('Start...')
    box1 = [50, 50, 100, 200]  # list
    box2 = np.array([50, 50, 120, 220])  # 一个坐标
    box3 = np.array([[50, 50, 100, 200], [50, 50, 120, 220], [50, 50, 120, 220]])  # 多个坐标
    box4 = torch.FloatTensor([50, 50, 100, 200])  # 一个tensor坐标数据
    box5 = torch.FloatTensor([[50, 50, 100, 200], [50, 50, 120, 220], [50, 50, 120, 220]])  # 多个tensor坐标数据

    for box in [box1, box2, box3, box4, box5]:
        box_ = ltwh2center(box)
        print('\n', 'input (%s):\n' % type(box), box, '\n', 'output(%s):\n' % type(box_), box_)

http://www.niftyadmin.cn/n/1009903.html

相关文章

Java并发编程中的JMM、3个基本属性、synchronized和volatile

1、Java内存模型JMM (Java Meemory Model) JMM规定,所有变量均存储在主内存中每个线程都有自己的工作内存,保存了该线程中用到的变量的主内存副本拷贝线程对变量的所有操作,必须在自己的工作内存中,不可直接读写主内存不同线程无法…

【Linux】调试工具gdb

目录 前言 一、前情了解 二、gdb常用命令 1.基本指令 2.断点 3.调试过程 4.查看内容 前言 gdb是Linux环境下了一个调试工具,在代码运行出现问题时,我们可以通过它来进行调试,找出问题的所在。本文来带大家来了解一下gdb的使用方法。 …

学号编码:TooY0ung的学院(结构体)

根据66十二位编码规则,用城市代码和出生年编制学号。 【本笔记适合初通算法的 coder 翻阅】 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础…

【C语言初阶(4)】循环语句3:do while 循环

文章目录 1. 语法结构2. 执行流程3. do while 循环的特点4. do while 循环中的 break 和 continue4.1 do while 循环中的 break4.2 do while 循环中的 continue 1. 语法结构 do {循环语句; } while(表达式) ; ← 这里还有个分号,不要忘了注意:在 do whi…

力扣 108. 将有序数组转换为二叉搜索树

题目来源:https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/description/ C题解1:递归法。由于要求是平衡树,又给出了递增数组,所以构建二叉树只需将中间值作为中间节点,左右两边分属左右子树…

分布式软件架构——客户端缓存

浏览器的客户端缓存 当万维网刚刚出现的时候,浏览器的缓存机制差不多就已经存在了。在 HTTP 协议设计之初,人们便确定了服务端与客户端之间“无状态”(Stateless)的交互原则,即要求客户端的每次请求是独立的&#xff…

Git代码管理工具

目录 一、安装Git 二、Git基本概念 三、Git基本操作 初始化Git仓库 Git init 添加文件到暂存区Git add 提交暂存区到本地仓库Git commit 上传至远程并合并 Git push Git 分支管理 创建分支:Git branch 切换分支:Git checkout 删除分支 分支合…

xxl-job源码改造集成:适配opengauss数据、适配单点登录等

目录 一、摘要 二、集成方案 三、集成步骤 3.1 springboot集成xxl-job 3.2 适配高斯数据库(postgresql) 3.3 页面集成 3.4 登录集成 3.5 接口集成 四、部署 一、摘要 公司现在打算重构产品,将原来的quartz替换成xxl-job,主要因为quartz不能动态…