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

news/2024/7/7 18:45:37

深度学习


文章目录

  • 深度学习


尝试着写了一个可以转换任何维度的任意格式的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://lihuaxi.xjx100.cn/news/1313044.html

相关文章

【rtklibexployer】RTKLIB Static-start feature 静态启动模式

原文:RTKLIB: Static-start feature 静态启动模式是我不久前添加到 demo4 代码中的,但一直没来得及解释,所以我现在要做。 正如我以前提到的,我总是喜欢在第一次打开接收器后让接收机静止不动,以便在允许它移动之前获…

svn和git的使用杂谈

笔者毕业的4年一直都是使用svn,直到前面几个月换了工作,新单位用的git,愣是用了1-2个月的时间才缓过来;下面是笔者关于这两款代码管理工具使用的一点经验。 svn svn:使用简单,入门容易,就只有本地代码和远…

jenkins部署springboot项目

jenkins部署springboot项目 1、创建一个项目 上传到gitee 1、创建项目 2、上传到git 2、jenkins创建一个pipeline项目 Pipeline简介 1)概念 Pipeline,简单来说,一套运行在 Jenkins 上的工作流框架,将原来独立运行于单个或者…

Markdown(6):段落缩进

Markdown 段落缩进 \qquad Markdown 是一种轻量级标记语言,创始人为约翰格鲁伯(John Gruber)。 它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的 XHTML(或者HTML)文档。这种语言吸收了很多在…

SSL证书中的对称加密是什么?有哪些算法

SSL证书中的对称加密是一种加密类型,它使用相同的密钥来加密和解密数据。发送者和接收者都具有相同的密钥副本,它们是秘密的,不会与任何人共享。这与非对称加密不同,后者使用两个密钥-一个公共密钥(任何人都可以访问&a…

CSS_calc() 函数内部怎么使用scss变量

使用 calc() 函数来计算主体元素的宽度,其中通过 #{} 语法将 SCSS 变量转换为 CSS 变量,然后使用加法运算符 和乘法运算符 * 来计算宽度值 $main-width: 100px; $main-padding: 10px;.main {width: calc(#{$main-width} #{$main-padding} * 2); }

新颖的文档、视频交互方式:以《GPT API Unofficial Docs》和《渐构》为例

一、背景 无意中看到一份 《GPT API 非官方文档》:https://gpt.pomb.us/ 被网站的交互方式所吸引,颇为新颖,值得借鉴。 左侧是对应的 API 代码调用示例,右侧是文档的每个部分,滑动到对应部分,左侧相关的代…

百度--搜索引擎是怎么实现的--如何制作一个搜索浏览器

1.搜索引擎是怎么实现的? 搜索引擎是通过以下步骤实现的: 网页抓取(Crawling):搜索引擎会使用网络爬虫(Web Crawler)自动地从互联网上抓取网页内容。爬虫按照一定的规则遍历网页并提取网页内容…