#其中,xml格式以图像的标记框的左上角、右下角的像素坐标为记录值,分别记作(box[0],box[2]),(box[1],box[3]),图像像素大小宽高为(size[0],size[1]);
#其中,yolo标注格式txt以图像的标记框中心点的像素坐标,以及标记框的宽,高相对图像的宽高比值作为记录值,分别为x,y,w,h;
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)
#其中,xml格式以图像的标记框的左上角、右下角的像素坐标为记录值,分别记作(box[0],box[2]),(box[1],box[3]),图像像素大小宽高为(size[0],size[1]);
#其中,yolo标注格式txt以图像的标记框中心点的像素坐标,以及标记框的宽,高相对图像的宽高比值作为记录值,分别为x,y,w,h;
"""
voc(xml格式)转yolo(txt格式),coco数据集对应的是json格式
"""
import os
import xml.etree.ElementTree as ET
# 注意修改数据集标签的路径
dirpath = 'C:/Users/sjh/Desktop/PennFudanPed/Annotation_xml' # 原来存放xml文件的目录
newdir = 'C:/Users/sjh/Desktop/PennFudanPed/Annotation_xml' # 修改label后形成的txt目录
if not os.path.exists(newdir):
os.makedirs(newdir)
for fp in os.listdir(dirpath):
# 直接解析XML文件:
root = ET.parse(os.path.join(dirpath, fp)).getroot()
xmin, ymin, xmax, ymax = 0, 0, 0, 0
sz = root.find('size')
width = float(sz[0].text)
height = float(sz[1].text)
filename = root.find('filename').text
for child in root.findall('object'): # 找到图片中的所有框
name = child.find('name').text
# print(name)
if name == 'human':
classes = 0
elif name == 'light':
classes = 1
sub = child.find('bndbox') # 找到框的标注值并进行读取
xmin = float(sub[0].text)
ymin = float(sub[1].text)
xmax = float(sub[2].text)
ymax = float(sub[3].text)
try: # 转换成yolov3的标签格式,需要归一化到(0-1)的范围内
x_center = (xmin + xmax) / (2 * width)
y_center = (ymin + ymax) / (2 * height)
w = (xmax - xmin) / width
h = (ymax - ymin) / height
except ZeroDivisionError:
print(filename, '的 width有问题')
with open(os.path.join(newdir, fp.split('.')[0] + '.txt'), 'a+') as f:
f.write(' '.join([str(classes), str(x_center), str(y_center), str(w), str(h) + '\n']))
labelimg图片标注软件
pascal voc格式xml
yolo txt格式
中心点: 326=(246+407)/2;
214.5= (154+275)/2;
宽度: 161=407-246
高度: 121=275-154