如何将边界框 (x1, y1, x2, y2) 转换为 YOLO Style (X, Y, W, H)
How to convert bounding box (x1, y1, x2, y2) to YOLO Style (X, Y, W, H)
我正在训练 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 在x
和y
两个方向上将图像space 归一化为运行 从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 */
这是 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
对于那些寻找相反问题的人(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
对于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
只是阅读答案,我也在寻找这个,但发现这个信息更丰富,可以了解后端发生的事情。
表格在这里:Source
假设 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
这假设原点在左上角,如果不是这种情况,您将必须应用偏移因子。
所以答案
有两种可能的解决方案。首先你要明白你的第一个边界框是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
有更多 straight-forward 的方法可以用 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_width=W, image_height=H)
>>> (0.15, 0.15, 0.1, 0.1)
注意,转成YOLO格式需要图片宽高进行缩放。
我正在训练 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 在x
和y
两个方向上将图像space 归一化为运行 从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 */
这是 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
对于那些寻找相反问题的人(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
对于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
只是阅读答案,我也在寻找这个,但发现这个信息更丰富,可以了解后端发生的事情。 表格在这里:Source
假设 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
这假设原点在左上角,如果不是这种情况,您将必须应用偏移因子。
所以答案
有两种可能的解决方案。首先你要明白你的第一个边界框是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
有更多 straight-forward 的方法可以用 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_width=W, image_height=H)
>>> (0.15, 0.15, 0.1, 0.1)
注意,转成YOLO格式需要图片宽高进行缩放。