为了方便增加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