如何将边界框(x1,y1,x2,y2)转换为YOLO样式(X,Y,W,H)

问题描述 投票:0回答:8

我正在训练 YOLO 模型,我有以下格式的边界框:-

x1, y1, x2, y2 => ex (100, 100, 200, 200)

我需要将其转换为 YOLO 格式,如下所示:-

X, Y, W, H => 0.436262 0.474010 0.383663 0.178218

我已经计算了中心点X、Y、高度H和重量W。 但仍然需要像前面提到的那样将它们转换为浮点数。

machine-learning math image-processing computer-vision yolo
8个回答
31
投票

对于那些寻找问题相反的人(yolo 格式到普通 bbox 格式)

def yolobbox2bbox(x,y,w,h):
    x1, y1 = x-w/2, y-h/2
    x2, y2 = x+w/2, y+h/2
    return x1, y1, x2, y2

20
投票

这是Python中的代码片段,用于将x,y坐标转换为yolo格式

def convert(size, box):
    dw = 1./size[0]
    dh = 1./size[1]
    x = (box[0] + box[1])/2.0
    y = (box[2] + box[3])/2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x*dw
    w = w*dw
    y = y*dh
    h = h*dh
    return (x,y,w,h)

im=Image.open(img_path)
w= int(im.size[0])
h= int(im.size[1])


print(xmin, xmax, ymin, ymax) #define your x,y coordinates
b = (xmin, xmax, ymin, ymax)
bb = convert((w,h), b)

查看我的示例程序,将LabelMe标注工具格式转换为Yolo格式https://github.com/ivder/LabelMeYoloConverter


8
投票

有一种更直接的方法可以使用 pybboxes 来完成这些事情。安装,

pip install pybboxes

如下使用它,

import pybboxes as pbx

voc_bbox = (100, 100, 200, 200)
W, H = 1000, 1000  # WxH of the image
pbx.convert_bbox(voc_bbox, from_type="voc", to_type="yolo", image_size=(W,H))
>>> (0.15, 0.15, 0.1, 0.1)

注意,转换为YOLO格式需要图像宽度和高度进行缩放。


3
投票

YOLO 将图像空间标准化为在

x
y
方向上从 0 到 1。要在
(x, y)
坐标和 yolo
(u, v)
坐标之间进行转换,您需要将数据转换为
u = x / XMAX
y = y / YMAX
,其中
XMAX
YMAX
是您正在使用的图像数组的最大坐标。

这一切都取决于图像阵列以相同的方式定向。

这是一个执行转换的 C 函数

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <math.h>

struct yolo {
    float   u;
    float   v;
    };

struct yolo
convert (unsigned int x, unsigned int y, unsigned int XMAX, unsigned int YMAX)
{
    struct yolo point;

    if (XMAX && YMAX && (x <= XMAX) && (y <= YMAX))
    {
        point.u = (float)x / (float)XMAX;
        point.v = (float)y / (float)YMAX;
    }
    else
    {
        point.u = INFINITY;
        point.v = INFINITY;
        errno = ERANGE;
    }

    return point;
}/* convert */


int main()
{
    struct yolo P;

    P = convert (99, 201, 255, 324);

    printf ("Yolo coordinate = <%f, %f>\n", P.u, P.v);

    exit (EXIT_SUCCESS);
}/* main */

1
投票

有两种可能的解决方案。首先你必须了解你的第一个边界框是Coco还是Pascal_VOC格式。否则你无法做正确的数学。

这是格式;

Coco 格式: [x_min, y_min, 宽度, 高度]
Pascal_VOC 格式: [x_min, y_min, x_max, y_max]

以下是一些如何进行转换的 Python 代码:

将 Coco 转换为 Yolo

# Convert Coco bb to Yolo
def coco_to_yolo(x1, y1, w, h, image_w, image_h):
    return [((2*x1 + w)/(2*image_w)) , ((2*y1 + h)/(2*image_h)), w/image_w, h/image_h]

将 Pascal_voc 转换为 Yolo

# Convert Pascal_Voc bb to Yolo
def pascal_voc_to_yolo(x1, y1, x2, y2, image_w, image_h):
    return [((x2 + x1)/(2*image_w)), ((y2 + y1)/(2*image_h)), (x2 - x1)/image_w, (y2 - y1)/image_h]

如果需要额外的转换,您可以在 Medium 上查看我的文章:https://christianbernecker.medium.com/convert-bounding-boxes-from-coco-to-pascal-voc-to-yolo-and-back-660dc6178742


0
投票

您需要做两件事:

  1. 将坐标除以图像大小,将其标准化为 [0..1] 范围。
  2. (x1, y1, x2, y2) 坐标转换为 (center_x, center_y, width, height)

如果您使用 PyTorch,Torchvision 提供了一个可用于转换的函数:

from torch import tensor
from torchvision.ops import box_convert

image_size = tensor([608, 608])
boxes = tensor([[100, 100, 200, 200], [300, 300, 400, 400]], dtype=float)
boxes[:, :2] /= image_size
boxes[:, 2:] /= image_size
boxes = box_convert(boxes, "xyxy", "cxcywh")

0
投票

将 yolo 格式转换为 x1,y1, x2,y2 格式

def yolobbox2bbox(x,y,w,h):
    x1 = int((x - w / 2) * dw)
    x2 = int((x + w / 2) * dw)
    y1 = int((y - h / 2) * dh)
    y2 = int((y + h / 2) * dh)

    if x1 < 0:
        x1 = 0
    if x2 > dw - 1:
        x2 = dw - 1
    if y1 < 0:
        y1 = 0
    if y2 > dh - 1:
        y2 = dh - 1

return x1, y1, x2, y2

-1
投票

只是阅读答案,我也在寻找这个,但发现这个信息更丰富,可以了解后端发生的情况。 在此填写:来源

假设

x/ymin
x/ymax
分别是您的边界角,
top left and bottom right
。然后:

x = xmin
y = ymin
w = xmax - xmin
h = ymax - ymin

然后您需要

normalize
这些,这意味着将它们作为整个图像的比例,因此简单地将每个值除以上面的值各自的大小:

x = xmin / width
y = ymin / height
w = (xmax - xmin) / width
h = (ymax - ymin) / height

这假设原点是左上角,如果不是这种情况,您将必须应用移位因子。

所以答案

© www.soinside.com 2019 - 2024. All rights reserved.