Pascal VOC数据集是目标检测领域最常用的标准数据集之一,几乎所有检测方向的论文都会给出其在VOC数据集上训练并评测的效果。VOC数据集包含的信息非常全,它不仅被拿来做目标检测,也可以拿来做分割等任务,因此除了目标检测所需的文件之外,还包含分割任务所需的文件,比如 SegmentationClass, SegmentationObject等
下面我们来认识一下Pascal voc数据集的文件目录结构,Pascal VOC数据主要有2007和2012两年的数据,其中2007有train,val,test,而2012只有train和val
#第一级
VOCdevkit
├── VOC2007
└── VOC2012
#第二级
VOCdevkit/VOC2007
├── Annotations
├── ImageSets
├── JPEGImages
├── SegmentationClass
└── SegmentationObjectVOCdevkit/VOC2012
├── Annotations
├── ImageSets
├── JPEGImages
├── SegmentationClass
└── SegmentationObject
#以VOC2007为例,第三级
## Annotations
VOCdevkit/VOC2007/Annotations/
├── 000001.xml
├── 000002.xml
├── 000003.xml
├── 000004.xml
├── 000005.xml
├── 000006.xml
├── 000007.xml
├── 000008.xml
├── 000009.xml
├── 000010.xml
...
## JPEGImages
VOCdevkit/VOC2007/JPEGImages/
├── 000001.jpg
├── 000002.jpg
├── 000003.jpg
├── 000004.jpg
├── 000005.jpg
├── 000006.jpg
├── 000007.jpg
├── 000008.jpg
├── 000009.jpg
├── 000010.jpg
├── 000011.jpg
├── 000012.jpg
├── 000013.jpg##ImageSets
VOCdevkit/VOC2007/ImageSets/
├── Layout
├── Main
└── Segmentation#ImageSets第四级
VOCdevkit/VOC2007/ImageSets/
├── Layout
│ ├── test.txt
│ ├── train.txt
│ ├── trainval.txt
│ └── val.txt
├── Main
│ ├── aeroplane_test.txt
│ ├── aeroplane_train.txt
│ ├── aeroplane_trainval.txt
│ ├── aeroplane_val.txt
│ ├── bicycle_test.txt
│ ├── bicycle_train.txt
│ ├── bicycle_trainval.txt
│ ├── bicycle_val.txt
│ ├── bird_test.txt
│ ├── bird_train.txt
│ ├── bird_trainval.txt
│ ├── bird_val.txt
│ ├── boat_test.txt
│ ├── boat_train.txt
│ ├── boat_trainval.txt
│ ├── boat_val.txt
│ ├── bottle_test.txt
│ ├── bottle_train.txt
│ ├── bottle_trainval.txt
│ ├── bottle_val.txt
│ ├── bus_test.txt
│ ├── bus_train.txt
│ ├── bus_trainval.txt
│ ├── bus_val.txt
│ ├── car_test.txt
│ ├── car_train.txt
│ ├── car_trainval.txt
│ ├── car_val.txt
│ ├── cat_test.txt
│ ├── cat_train.txt
│ ├── cat_trainval.txt
│ ├── cat_val.txt
│ ├── chair_test.txt
│ ├── chair_train.txt
│ ├── chair_trainval.txt
│ ├── chair_val.txt
│ ├── cow_test.txt
│ ├── cow_train.txt
│ ├── cow_trainval.txt
│ ├── cow_val.txt
│ ├── diningtable_test.txt
│ ├── diningtable_train.txt
│ ├── diningtable_trainval.tx
│ ├── diningtable_val.txt
│ ├── dog_test.txt
│ ├── dog_train.txt
│ ├── dog_trainval.txt
│ ├── dog_val.txt
│ ├── horse_test.txt
│ ├── horse_train.txt
│ ├── horse_trainval.txt
│ ├── horse_val.txt
│ ├── motorbike_test.txt
│ ├── motorbike_train.txt
│ ├── motorbike_trainval.txt
│ ├── motorbike_val.txt
│ ├── person_test.txt
│ ├── person_train.txt
│ ├── person_trainval.txt
│ ├── person_val.txt
│ ├── pottedplant_test.txt
│ ├── pottedplant_train.txt
│ ├── pottedplant_trainval.tx
│ ├── pottedplant_val.txt
│ ├── sheep_test.txt
│ ├── sheep_train.txt
│ ├── sheep_trainval.txt
│ ├── sheep_val.txt
│ ├── sofa_test.txt
│ ├── sofa_train.txt
│ ├── sofa_trainval.txt
│ ├── sofa_val.txt
│ ├── test.txt
│ ├── train_test.txt
│ ├── train_train.txt
│ ├── train_trainval.txt
│ ├── train.txt
│ ├── train_val.txt
│ ├── trainval.txt
│ ├── tvmonitor_test.txt
│ ├── tvmonitor_train.txt
│ ├── tvmonitor_trainval.txt
│ ├── tvmonitor_val.txt
│ └── val.txt
└── Segmentation
├── test.txt
├── train.txt
├── trainval.txt
└── val.txt
1.JPEGImages
这个文件夹中存放所有的图片,包括训练验证测试用到的所有图片。
2.ImageSets
这个文件夹中包含三个子文件夹,Layout、Main、Segmentation
3.Annotations
Annotation文件夹中存放着每张图片相关的标注信息,以xml格式的文件存储,标注文件中各个属性的含义,见下图。
红框区域内的内容是我们真正需要关注的,它包含。
一张图片中有多少需要识别的目标,其 xml 文件中就有多少个 object。上面的例子中有两个object,分别对应人和狗。
yolo数据集的格式通常为:
class_id x y w h
下图为一张图片按照yolo格式进行标注的txt标注文件
voc与yolo数据集格式比较如下:
理解了voc格式的数据集以及yolo格式的数据集,那么将两者相互转化就容易多了。下面为voc转yolo格式的案例模板代码:
- import xml.etree.ElementTree as ET
- import os
-
-
- voc_folder = r"E:\Download_Datasets\detection_reflect_clothes\Annotations" #储存voc格式的xml标注文件的文件夹
- yolo_folder = r"E:\Download_Datasets\yolo_detection_reflect_clothes\labels" #转换后的yolo格式标注文件的储存文件夹
-
- class_id = ["person",'other_clothes','hat','reflective_clothes'] #储存数据集中目标种类名称的列表,接下来的转换函数中会将该列表中种类名称对应的列表索引号作为写入yolo标注文件中该类目标的种类序号
-
- #voc标注的目标框坐标值转换到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)
-
- #对单个voc标注文件进行转换成其对应的yolo文件的函数
- def convert_annotation(xml_file):
- file_name = xml_file.strip(".xml") # 这一步将所有voc格式标注文件取出后缀名“.xml”,方便接下来作为yolo格式标注文件的名称
- in_file = open(os.path.join(voc_folder,xml_file)) #打开当前转换的voc标注文件
- out_file = open(os.path.join(yolo_folder,file_name + ".txt",),'w') #创建并打开要转换成的yolo格式标注文件
- 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'):
- cls = obj.find('name').text
- cls_id = class_id.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')
-
-
-
- xml_fileList = os.listdir(voc_folder) #将所有voc格式的标注文件的名称取出存放到列表xml_fileList中
- for xml_file in xml_fileList: #这里的for循环开始依次对所有voc格式标注文件生成其对应的yolo格式的标注文件
- convert_annotation(xml_file)