一、csv数据准备(需要利用Pascal voc2007数据集形式来生成)
在生成csv数据集时候,需要先将自己的数据做成VOC 2007形式,参考上篇博客:VOC2007数据集制作-进行自己数据集的训练,可用于目标检测、图像分隔等任务
Pascal voc2007 数据集转换成csv数据集时候,将会使用voc2007数据集中三个文件JPEGImages,Annatations,ImageSets中Main文件夹生成,结果保存到csv文件夹下的annotations.csv,classes.csv。
首先介绍本文使用的文件夹目录情况:
1. 自己的voc2007数据集,用来生成csv数据集
自己的VOC数据格式如下,图片的命名没有按照标准VOC2007重命名,因为在后面进行Retinanet训练时候,图片名字不影响。
├── Annotations │ ├── 0095.xml │ ├── 0096.xml │ ├── 0312.xml │ ├── 0313.xml │ ├── 0588.xml │ ├── 0589.xml │ ├── 0590.xml │ ├── 0800.xml │ ├── 0801.xml │ ├── 0802.xml │ ├── 0803.xml │ ├── 0804.xml │ └── 0805.xml ├── generate_Main_txt.py # generate_Main_txt是上文博客中生成ImageSets/Main中4个txt的函数。在本篇博客暂时用不到 ├── ImageSets │ └── Main │ ├── test.txt │ ├── train.txt │ ├── trainval.txt │ └── val.txt ├── JPEGImages │ ├── 0095.png │ ├── 0096.png │ ├── 0312.png │ ├── 0313.png │ ├── 0588.png │ ├── 0589.png │ ├── 0590.png │ ├── 0800.png │ ├── 0801.png │ ├── 0802.png │ ├── 0803.png │ ├── 0804.png │ └── 0805.png └── pascal2csv.py 4 directories, 32 files
2.自己的csv数据集按如下格式存放
├── csv │ ├── Annotations #上文步骤1中的自己的vOC2007数据集中的Annotations │ │ ├── 0095.xml │ │ ├── 0096.xml │ │ ├── 0312.xml │ │ ├── 0313.xml │ │ ├── 0588.xml │ │ ├── 0589.xml │ │ ├── 0590.xml │ │ ├── 0800.xml │ │ ├── 0801.xml │ │ ├── 0802.xml │ │ ├── 0803.xml │ │ ├── 0804.xml │ │ └── 0805.xml │ ├── annotations.csv #生成的CSV数据集中文件 │ ├── classes.csv #生成的CSV数据集中文件 │ ├── ImageSets #上文步骤1中的自己的vOC2007数据集中的ImageSets │ │ └── Main │ │ ├── test.txt │ │ ├── train.txt │ │ ├── trainval.txt │ │ └── val.txt │ ├── JPEGImages #上文步骤1中的自己的vOC2007数据集中的JPEGImages │ │ ├── 0095.png │ │ ├── 0096.png │ │ ├── 0312.png │ │ ├── 0313.png │ │ ├── 0588.png │ │ ├── 0589.png │ │ ├── 0590.png │ │ ├── 0800.png │ │ ├── 0801.png │ │ ├── 0802.png │ │ ├── 0803.png │ │ ├── 0804.png │ │ └── 0805.png │ └── pascal2csv.py #下文将要说的转换函数
二、Pascal voc2007 数据集转换成csv数据转换函数
直接上pascal2csv.py:
# -*- coding:utf-8 -*- import csv import os import glob import sys class PascalVOC2CSV(object): def __init__(self,xml=[], ann_path='./annotations.csv',classes_path='./classes.csv'): ''' :param xml: 所有Pascal VOC的xml文件路径组成的列表 :param ann_path: ann_path :param classes_path: classes_path ''' self.xml = xml self.ann_path = ann_path self.classes_path=classes_path self.label=[] self.annotations=[] self.data_transfer() self.write_file() def data_transfer(self): for num, xml_file in enumerate(self.xml): try: # print(xml_file) # 进度输出 sys.stdout.write('\r>> Converting image %d/%d' % ( num + 1, len(self.xml))) sys.stdout.flush() with open(xml_file, 'r') as fp: for p in fp: if '<filename>' in p: self.filen_ame = p.split('>')[1].split('<')[0] if '<object>' in p: # 类别 d = [next(fp).split('>')[1].split('<')[0] for _ in range(9)] self.supercategory = d[0] if self.supercategory not in self.label: self.label.append(self.supercategory) # 边界框 x1 = int(d[-4]); y1 = int(d[-3]); x2 = int(d[-2]); y2 = int(d[-1]) self.annotations.append([os.path.join('JPEGImages',self.filen_ame),x1,y1,x2,y2,self.supercategory]) except: continue sys.stdout.write('\n') sys.stdout.flush() def write_file(self,): with open(self.ann_path, 'w', newline='') as fp: csv_writer = csv.writer(fp, dialect='excel') csv_writer.writerows(self.annotations) class_name=sorted(self.label) class_=[] for num,name in enumerate(class_name): class_.append([name,num]) with open(self.classes_path, 'w', newline='') as fp: csv_writer = csv.writer(fp, dialect='excel') csv_writer.writerows(class_) xml_file = glob.glob('./Annotations/*.xml') PascalVOC2CSV(xml_file)
函数运行结束后,会在目录下生成classes.csv、annotations.csv.
他们的格式大致如下:
annotations.csv
path/to/image.jpg,x1,y1,x2,y2,class_name /data/imgs/img_001.jpg,837,346,981,456,cow /data/imgs/img_002.jpg,215,312,279,391,cat # 02图片第一个对象 /data/imgs/img_002.jpg,22,5,89,84,bird # 02图片第二个对象 /data/imgs/img_003.jpg,,,,, # 背景图片,没有任何要检查的对象
classes.csv
class_name,id cow,0 cat,1 bird,2 # 因为这里的背景对应的类别为 空 , # 而mask RCNN 与 FCN(RFCN)都是使用0来表示背景,也就是google object detection中的检测框架,以及mask rcnn中第一种目标是从1开始标记的
至此,自己数据集csv制作完毕。