pascal voc转yolo
时间: 2024-12-26 17:27:16 浏览: 14
### 转换过程概述
为了将Pascal VOC格式的数据集转换为YOLO格式,主要涉及文件结构调整以及标注文件内容的转换。具体来说,VOC格式中的每张图片对应一个XML文件,而YOLO格式则采用TXT文件记录目标框信息,并且这些坐标是以相对位置表示的。
#### 文件结构调整
在开始转换之前,确保原始图像和对应的标签文件按照一定规则组织好。对于YOLO格式而言,通常期望看到如下目录结构:
```
dataset/
├── images/
│ ├── img1.jpg
│ └── ...
└── labels/
├── img1.txt
└── ...
```
#### XML到TXT的转换逻辑
从VOC至YOLO的关键在于解析XML文档内的边界框数据,并将其转化为YOLO所需的标准化形式——即中心点(x_center, y_center),宽度(width) 和高度(height),所有数值均为相对于整幅图尺寸的比例值[^1]。
以下是实现上述功能的一段Python代码示例:
```python
import xml.etree.ElementTree as ET
from os import getcwd
sets=[('2007', 'train'), ('2007', 'val')]
classes = ["aeroplane", "bicycle", "bird"] # 需要根据实际情况修改类别列表
def convert(size, box):
dw = 1./(size[0])
dh = 1./(size[1])
x = (box[0] + box[1])/2.0 - 1
y = (box[2] + box[3])/2.0 - 1
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)
def convert_annotation(year, image_id, list_file):
in_file = open(f'./VOCdevkit/VOC{year}/Annotations/{image_id}.xml')
out_file = open(f'./labels/{image_id}.txt', 'w')
tree=ET.parse(in_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
for obj in root.iter('object'):
difficult = obj.find('difficult').text
cls = obj.find('name').text
if cls not in classes or int(difficult)==1:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
bb = convert((w,h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
wd = getcwd()
for year, image_set in sets:
image_ids = open(f'./VOCdevkit/VOC{year}/ImageSets/Main/{image_set}.txt').read().strip().split()
list_file = open('%s_%s.txt'%(year, image_set), 'w')
for image_id in image_ids:
list_file.write(f'{wd}/images/{image_id}.jpg\n')
convert_annotation(year, image_id, list_file)
list_file.close()
```
此脚本遍历指定年份下的训练/验证集合,读取相应的XML文件并创建匹配的TXT文件用于存储转换后的YOLO风格的目标检测标记信息。
阅读全文