为了方便增加YOLO训练数据量,博主将VOC各年数据利用python程序转成了YOLO格式,希望小伙伴可以借鉴一二,如有不正,欢迎指出。
注意:1、可根据需求转成自己的类型,对程序稍作修改即可
2、VOC2005、VOC2006、VOC2007+VOC2008、VOC2009-VOC2012数据格式不同,故程序不同,小伙伴注意下。
VOC各年数据下载网盘:链接:http://pan.baidu.com/s/1mie9kPM 密码:2lgr
VOC2005转换为TXT代码如下:
import os
import os.path
import shutil
anno_path = "E:\\voc_year\\VOCdevkit\\VOC2005\\Annotations\\motorbike\\"
jpeg_path = "E:\\voc_year\\VOCdevkit\\VOC2005\\JEPGImages\\motorbike\\"
obj_path = "E:\\voc_year\\VOCdevkit\\VOC2005\\Annotations_txt\\"
img_path = "E:\\voc_year\\VOCdevkit\\VOC2005\\yolo_img"
if not os.path.exists(obj_path):
os.mkdir(obj_path)
if not os.path.exists(img_path):
os.mkdir(img_path)
for files in os.walk(anno_path):
for file in files[2]:
fp = open(obj_path + file, "w")
txt_name = anno_path + file
txt_file = open(txt_name, "r")
lines = txt_file.read().split('\n')
for i in range(0,len(lines)):
if "Bounding" in lines[i]:
new_lines = lines[i].split(': ')[1].split(', ')
yx = new_lines[1].split(' - ')
xmin = new_lines[0][1:]
ymin = yx[0][:len(yx[0])-1]
xmax = yx[1][1:]
ymax = new_lines[2][:len(new_lines[2])-1]
if (int(float(xmin)) > 0 and (int(float(ymin)) > 0 and (int(float(xmax)) > 0 and (int(float(ymax)) > 0)))):
fp.write("motorbike\n")
fp.write(xmin + '\n')
fp.write(ymin + '\n')
fp.write(xmax + '\n')
fp.write(ymax + '\n')
fp.close()
fn = obj_path + file
size = os.path.getsize(fn)
if size == 0:
os.remove(fn)
else:
img_name = jpeg_path + os.path.splitext(file)[0] + '.png'
shutil.copy(img_name, img_path)
print file + "--> Down!"
VOC2006转换为TXT代码如下:
import os
import os.path
import pdb
import shutil
anno_path = "E:\\voc_year\\VOCdevkit\\VOC2006\\Annotations\\"
jpeg_path = "E:\\voc_year\\VOCdevkit\\VOC2006\\PNGImages\\"
obj_path = "E:\\voc_year\\VOCdevkit\\VOC2006\\Annotations_txt\\"
img_path = "E:\\voc_year\\VOCdevkit\\VOC2006\\yolo_img\\"
classes = ["bicycle","motorbike","bus","car"]
if not os.path.exists(obj_path):
os.mkdir(obj_path)
if not os.path.exists(img_path):
os.mkdir(img_path)
for files in os.walk(anno_path):
for file in files[2]:
fp = open(obj_path + "2006_" + file, "w")
txt_name = anno_path + file
txt_file = open(txt_name, "r")
lines = txt_file.read().split('\n')
for i in range(0,len(lines)):
boj = classes[0] in lines[i] or classes[1] in lines[i] or classes[2] in lines[i] or classes[3] in lines[i]
if "Bounding" in lines[i] and boj == True:
new_lines = lines[i].split(': ')[1].split(', ')
yx = new_lines[1].split(' - ')
xmin = new_lines[0][1:]
ymin = yx[0][:len(yx[0])-1]
xmax = yx[1][1:]
ymax = new_lines[2][:len(new_lines[2])-1]
if (int(float(xmin)) > 0 and (int(float(ymin)) > 0 and (int(float(xmax)) > 0 and (int(float(ymax)) > 0)))):
for k in range(0, 4):
if classes[k] in lines[i]:
cls = classes[k]
break
fp.write(cls + '\n')
fp.write(xmin + '\n')
fp.write(ymin + '\n')
fp.write(xmax + '\n')
fp.write(ymax + '\n')
fp.close()
fn = obj_path + "2006_" + file
size = os.path.getsize(fn)
if size == 0:
os.remove(fn)
else:
img_name = jpeg_path + os.path.splitext(file)[0] + '.png'
new_name = img_path + "2006_" + os.path.splitext(file)[0] + '.png'
shutil.copy(img_name, new_name)
print file + "--> Down!"
VOC07-12转换代码(分两步)如下:
第一步:从XML里面提取各类存至TXT当中
#coding=utf-8
import xml.dom.minidom
import pdb
import os
import os.path
fileDir = 'E:\\voc_year\\VOCdevkit\\VOC2012\\Annotations\\'
saveDir = 'E:\\voc_year\\VOCdevkit\\VOC2012\\Annotations_txt'
if ~os.path.exists(saveDir):
os.mkdir(saveDir)
j = 0
for files in os.walk(fileDir):
for file in files[2]:
print j
dom = xml.dom.minidom.parse(fileDir + file)
aa=dom.getElementsByTagName('name')
bb=dom.getElementsByTagName('xmin')
cc=dom.getElementsByTagName('ymin')
dd=dom.getElementsByTagName('xmax')
ee=dom.getElementsByTagName('ymax')
root = saveDir + "\\" + os.path.splitext(file)[0] + ".txt"
fp=open(root, 'w')
for i in range(0,len(aa)):
a1=aa[i]
str_aa=a1.firstChild.data
fp.write('%s'%str_aa+'\n')
b1=bb[i]
str_bb=b1.firstChild.data
fp.write('%s'%str_bb+'\n')
c1=cc[i]
str_cc=c1.firstChild.data
fp.write('%s'%str_cc+'\n')
d1=dd[i]
str_dd=d1.firstChild.data
fp.write('%s'%str_dd+'\n')
e1=ee[i]
str_ee=e1.firstChild.data
fp.write('%s'%str_ee+'\n')
fp.close()
j += 1
第二步:从TXT里面提取自己想要的类
import os
import os.path
import pdb
anno_path = "E:\\voc_year\\VOCdevkit\\VOC2012\\Annotations_txt"
obj_path = "E:\\voc_year\\VOCdevkit\\VOC2012\\Annotations_obj\\"
if os.path.exists(obj_path):
pass
else:
os.mkdir(obj_path)
b = 0
for files in os.walk(anno_path):
for file in files[2]:
object_ann = anno_path + '\\' + file
fp = open(object_ann, "r")
lines = fp.readlines()
index_bicycle = []
index_motorbike = []
index_car = []
index_bus = []
for i in range(0, len(lines)):
if lines[i] == 'bicycle\n':
index_bicycle.append(i)
else:
continue
for i in range(0, len(lines)):
if lines[i] == 'motorbike\n':
index_motorbike.append(i)
else:
continue
for i in range(0, len(lines)):
if lines[i] == 'car\n':
index_car.append(i)
else:
continue
for i in range(0, len(lines)):
if lines[i] == 'bus\n':
index_bus.append(i)
else:
continue
if (len(index_bicycle) != 0 or len(index_motorbike) != 0 \
or len(index_car) != 0 or len(index_bus) != 0):
objpath = obj_path + file
print b
b += 1
fp_write = open(objpath, 'w')
if len(index_bicycle) != 0:
for j in range(0, len(index_bicycle)):
for k in range(0, 5):
if k == 0:
fp_write.write(lines[index_bicycle[j]+k])
else:
fp_write.write(str(int(float(lines[index_bicycle[j]+k].split('\n')[0])))+'\n')
if len(index_motorbike) != 0:
for j in range(0, len(index_motorbike)):
for k in range(0, 5):
if k == 0:
fp_write.write(lines[index_motorbike[j]+k])
else:
fp_write.write(str(int(float(lines[index_motorbike[j]+k].split('\n')[0])))+'\n')
if len(index_car) != 0:
for j in range(0, len(index_car)):
for k in range(0, 5):
if k == 0:
fp_write.write(lines[index_car[j]+k])
else:
fp_write.write(str(int(float(lines[index_car[j]+k].split('\n')[0])))+'\n')
if len(index_bus) != 0:
for j in range(0, len(index_bus)):
for k in range(0, 5):
if k == 0:
fp_write.write(lines[index_bus[j]+k])
else:
fp_write.write(str(int(float(lines[index_bus[j]+k].split('\n')[0])))+'\n')
fp_write.close()
综上,VOC05-12转换为YOLO数据格式:
#-*- coding: utf-8 -*-
import os
import pdb
from os import walk, getcwd
from PIL import Image
import shutil
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)
mypath = "E:\\voc_year\\VOCdevkit\\VOC2011\\Annotations_obj\\"
outpath = "E:\\voc_year\\VOCdevkit\\VOC2011\\yolo_label\\"
jpg_path = "E:\\voc_year\\VOCdevkit\\VOC2011\\JPEGImages\\"
obj_img = "E:\\voc_year\\VOCdevkit\\VOC2011\\yolo_img\\"
if not os.path.isdir(obj_img):
os.mkdir(obj_img)
classes = ["bicycle", "motorbike", "car", "bus"]
""" Get input text file list """
txt_name_list = []
for (dirpath, dirnames, filenames) in walk(mypath):
txt_name_list.extend(filenames)
break
""" Process """
for txt_name in txt_name_list:
""" Open input text files """
txt_path = mypath + txt_name
txt_file = open(txt_path, "r")
lines = txt_file.read().split('\n')
""" Open output text files """
txt_outpath = outpath + txt_name
if not os.path.isdir(outpath):
os.mkdir(outpath)
txt_outfile = open(txt_outpath, "w")
img_path = jpg_path + os.path.splitext(txt_name)[0] + ".jpg"
shutil.copy(img_path, obj_img)
""" Convert the data to YOLO format """
for i in range(0, len(lines)/5):
xmin = lines[i*5+1]
xmax = lines[i*5+3]
ymin = lines[i*5+2]
ymax = lines[i*5+4]
im=Image.open(img_path)
w= int(im.size[0])
h= int(im.size[1])
b = (float(xmin), float(xmax), float(ymin), float(ymax))
bb = convert((w,h), b)
cls_id = classes.index(lines[i*5])
if (i != len(lines)/5-1):
txt_outfile.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
else:
txt_outfile.write(str(cls_id) + " " + " ".join([str(a) for a in bb]))
txt_outfile.close()
print (txt_name + " DONE!")
任何问题请加唯一QQ2258205918(名称samylee)!
或唯一VX:samylee_csdn