日志作我忘了查找用,有个人习惯,我并没有为了上传博客,而重新美化它,有些代码也是借鉴的网上的,有些无关的code我没有删除,用此博客学习的人可能并不能跑通它,找里面的有用部分即可。
1、数据集可能分为多个目录,每个目录的名字相同,如都是从0001.jpg开始,再把多个数据集目录合在一个目录内,需要先改名。`
#!usr/bin/env python
# -*- coding:utf-8 -*-
import os
class BatchRename():
def __init__(self):
self.path = 'E:\ch4_data\labels_txt'
def rename(self):
filelist = os.listdir(self.path) # 返回指定目录下的文件和子目录列表
print(filelist)
total_num = len(filelist)
i = 4006
for item in filelist:
if item.endswith('.jpg'):
src = os.path.join(os.path.abspath(self.path), item)
print(src)
dst = os.path.join(os.path.abspath(self.path), item.split('.')[0] + '.txt')
print (dst)
os.rename(src, dst)
#print 'converting %s to %s ...' % (src, dst)
i = i + 1
#print 'total %d to rename & converted %d jpgs' % (total_num, int(i))
"""
if item.endswith('.txt'):
src = os.path.join(os.path.abspath(self.path), item)
dst = os.path.join(os.path.abspath(self.path), 'img_'+str(i) + '.txt')
try:
os.rename(src, dst)
print 'converting %s to %s ...' % (src, dst)
except:
continue
"""
if __name__ == '__main__':
demo = BatchRename()
demo.rename()
2、labels的制作(xml2txt)
github上有些模型的数据标签接口是采用txt的形式,所有需要把xml转成txt
在这里,把xml的box信息(类别和坐标)转成了txt中(每行:类别号,中心x,y,宽,高),多个box转成多行,并且归一化
xml文件的解析中,iter、find和findall的区别,在研究下
#!usr/bin/env python
# -*- coding:utf-8 -*-
import os
import sys
try:
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
def xml2txt(outdir):
annotations = os.listdir('E:\ch4_data\labels') # 返回目录内包含的文件或子目录的m名字的列表
for i, file in enumerate(annotations):
file_save = file.split('.')[0]+'.txt'
file_txt=os.path.join(outdir, file_save)
#print(file_txt)
f_w = open(file_txt, 'w', encoding='utf-8') # ‘w’ 负责创建txt文件,
in_file = 'E:\ch4_data\labels\\' + file
tree=ET.parse(in_file)
root = tree.getroot()
size = root.find('size') #iter不行,find可以,findall不行,会影响后面
w = int(size.find('width').text)
h = int(size.find('height').text)
#print(w, h)
for obj in root.findall('object'): # iter可以,find不能for循环,findall可以 findall,如果没有找到,也不会报错,find如果没有就会报错
xmlbox = obj.find('bndbox')
xmin = float(xmlbox.find('xmin').text)
xmax = float(xmlbox.find('xmax').text)
x_center = round((xmin+xmax) / 2, 6)
x_center = round(x_center/w, 6)
ymin = float(xmlbox.find('ymin').text)
ymax = float(xmlbox.find('ymax').text)
y_center = round((ymin+ymax) / 2)
y_center = round(y_center/h, 6)
box_w = float(obj.find('width').text)
box_w = round(box_w/w, 6)
box_h = float(obj.find('height').text)
box_h = round(box_h/h, 6)
#f_w.write(name.encode("utf-8") + ' ')
f_w.write('0' + ' ')
f_w.write(str(x_center)+' '+str(y_center)+' '+str(box_w)+' '+str(box_h))
# 将坐标归一化
outdir='E:\ch4_data\labels_txt1' #txt目录
xml2txt(outdir)
3、生成train.txt和valid.txt
按照比例分好数据集
#!usr/bin/env python
# -*- coding:utf-8 -*-
"""
1是生成个jpg内容,就写入txt
2是先生成jpg列表,然后把列表写入txt
"""
import os
label_path = 'E:\ch4_data\labels'
imgfile_list = []
write_train_txt = 'E:\ch4_data\\train_imgfile.txt'
write_train_txt = open(write_train_txt, "w")
write_valid_txt = 'E:\ch4_data\\valid_imgfile.txt'
write_valid_txt = open(write_valid_txt, "w")
label_list = os.listdir(label_path)
print(len(label_list))
for label in label_list:
if label.endswith('.xml'):
write_content = label[:-4]
#print (write_content)
imgfile_list.append(write_content)
#print(imgfile_list)
#print (len(imgfile_list))
for i, imgfile in enumerate(imgfile_list):
if i and i % 5 ==0:
write_valid_txt.write('****' + imgfile + '\n')
else:
write_train_txt.write('****' + imgfile + '\n')
4、按照2的方法,如果xml没有object信息,程序是不会报错的,就是对应的txt文件没有内容,由于不会报错,在准备数据的说话,是发现不了的,但是在跑模型的时候就会报错了,数据标注公司是真的坑,所以在转txt或者是使用xml时都应查一查,有没有漏box信息的时候。
#!usr/bin/env python
# -*- coding:utf-8 -*-
import os
txt_path = 'E:\ch4_data\labels_txt'
txt_list = os.listdir(txt_path)
i =0
for txt_name in txt_list:
txt_file = os.path.join('E:\ch4_data\labels_txt', txt_name)
size = os.path.getsize(txt_file) # 如果内容为空则size为0
if size == 0:
print(txt_name)
i = i+1
print(i)