我正在训练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。但是仍然需要一个远处将它们转换为提到的浮数。
对于那些寻求问题相反的人(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
以下是python中的代码nipet,以将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
有一种更直接的方法可以用pybbox做出这些事情。安装,
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格式需要图像宽度和缩放高度。
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 */
有两个潜在的解决方案。首先,您必须了解您的第一个边界框是否采用可可或pascal_voc的格式。否则您将无法做正确的数学。
这是格式;
可可格式:
[x_min,y_min,width,height]
pascal_voc格式:
[x_min,y_min,x_max,y_max]
这是一些python代码,如何进行转换:
将可可转换为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]
如果需要进行其他转换,可以在媒体上查看我的文章:https://christianbernecker.medium.com/convert-bounding-boxes-from-coco-coco-to-to-to-pascal-voc--voc-to-to-to-yolo-an-back-660dc61787442
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
您需要做两件事:
- 将坐标划分为图像大小,将它们标准化为 [0..1] range。
- convert (x1,y1,x2,y2( coordinates to (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")
刚刚阅读我也在寻找的答案,但发现这更有用,以了解后端发生了什么。表格在这里:来源
假设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
这是左上角的,如果不是这种情况,您将必须应用一个移位因素。
所以答案