制作voc数据集
1主要是从一些大的数据集里面抽取部分数据,然后根据大数据集的TXT标签文件和box文件,制作小数据集的标签,然后进行重新命名,转换成xml文件,进行训练。
2数据集的结构特点:数据集原始文件包括Anno/list_category_img.txt
**从数据集将每种标签大于2000的数据的标签打印出来
# datas = open("Anno/list_category_img.txt").readlines()[2:]#原来的数据集的标签文件
# ann_labels = [eval(data.split(' ')[-1].strip()) for data in datas]
# category_labels = np.unique(ann_labels)
# img_label = []
# selected_data = []
# for label_temp in category_labels:
# tmpdata = []
# count = 0
# if ann_labels.count(label_temp) > 2000:
# img_label.append(label_temp)
# for data in datas:
# if count == 2000:
# selected_data.append(tmpdata)
# break
# tmplabel = eval(data.split(' ')[-1].strip())
# if tmplabel == label_temp:
# tmpdata.append(data.split(' ')[0].strip())
# count = count + 1
# # print(img_label)
将标签大于2000的图片每个挑选出来200张的标签和路径名写进文件selexttxt.txt文件
# f1=open('Anno/list_category_img.txt','rb')
# f2=open('Anno/selectxt.txt','wb+')#
# lines=f1.readlines()[2:]
# label=[eval(line.split()[-1].strip()) for line in lines]
# print(label)
# for label in [2, 3, 6, 10, 11, 16, 17, 18, 19, 26, 29, 30, 32, 33, 34, 39, 41, 42, 44, 48]:#属于大于2000#的标签列表
# i=0
# for line in lines:
# datalabel=eval(line.split()[-1].strip())
# if datalabel==label and i<200:
# f2.write(line)
# i+=1#为了检验数量
将这两千个图片的box文件的标签从原来的box文件中提取出来弄出来,保存selectbox.txt文件
f1=open('Anno/list_bbox.txt','rb')
f2=open('Anno/selectbox.txt','wb+')#挑选出来写入这个文件
f3=open('Anno/selectxt.txt','rb')
line1=f1.readlines()[2:]#很多行
line2=f3.readlines()#4000行
# label2=[eval(line.split()[0].strip()) for line in line2]
label2=[(line.split()[0].strip()) for line in line2]
for line in line1:
label1=(line.split()[0].strip())
if label1 in label2:
f2.write(line)
根据标签文件,将图片读取出来,4000张图片放在一个文件夹里面,一个新的文件夹selectimg,但是这个文件夹还是按照一路径要求存放的文件,不再放在那个大的数据集里面
我们一会还得把这些文件抽取出来。下面的图片长这样,一会还得给这些图片重新命名。
-*- encoding:utf-8 -*-
from PIL import Image
import os.path
import glob
import shutil
def convertjpg(src,outdir):
# img=Image.open(jpgfile)
# new_img=img.resize((width,height),Image.BILINEAR)
# new_img.save(os.path.join(outdir,os.path.basename(jpgfile)))
# for jpgfile in glob.glob("D:/python/*.jpg"):
# convertjpg(jpgfile,"D:/newfile")
f3 = open('selectxt.txt', 'r')
line2 = f3.readlines() # 4000行
# label2=[eval(line.split()[0].strip()) for line in line2]
for line in line2:
label3 = (line.split()[0].strip())
# label3=str(label2)
(filepath, tempfilename) = os.path.split(label3)
# file_suffix = os.path.splitext(label3)[0]
# print(filepath)
img=Image.open(os.path.join(src,label3))
# img=Image.open(filepath)
if os.path.exists(os.path.join(outdir,filepath)):
shutil.copy(os.path.join(src,label3), os.path.join(outdir,filepath))
else:
os.makedirs(os.path.join(outdir,filepath))
shutil.copy(os.path.join(src,label3), os.path.join(outdir,filepath))
convertjpg("F:\jupyter\dataset","F:\jupyter\selectimg")
将selectbox文件和select文件合并,就是将原来的标签,box,路径写在同一行,之前的文件是这样的
selecttxt.txt文件长这样:
selectbox.txt长这样:
合并之后长这样:last.txt
代码如下:
f1=open('Anno/selectbox.txt','r')
f3=open('Anno/last.txt','w')
f2=open('Anno/selectxt.txt','r')
line1=f1.readlines()#很多行 box
line2=f2.readlines()#4000行 label
# labellabel=[(line.split()[0].strip())for line in line2]
ount=0
for line in line1:#box
boxlabel=(line.split()[0].strip())
for linee in line2:
if boxlabel==(linee.split()[0].strip()):
l1=linee.split()[-1].strip()
line3=l1+' '+line
ount+=1
# print(line3)
# print(ount)
f3.write(line3)
修改路径的名字,并将最后的修改文件写在标签文件里面改成这样的txt文件,同时修改照片的名字,下面是改变之前和之后的对比。
重新命名的图片长这样
# -*- encoding:utf-8 -*-
from PIL import Image
import os.path
import glob
import shutil
import os
f1 = open('F:\\rename\\Anno\\last.txt', 'r')
f2 = open('F:\\rename\\Anno\\a1.txt', 'a')
imgdir = 'F:\\rename\\selectimg'
newdir = 'F:\\rename\\selet'
line1 = f1.readlines()
i = 1
n = 6
for line in line1:
splitline = line.split()
file_name = splitline[1]
labelname = splitline[0]
boxname = splitline[3]
(filepath, tempfilename) = os.path.split(file_name)
sorce = os.path.join(imgdir, filepath)
if tempfilename.endswith('.jpg'):
n = 6 - len(str(i))
src = os.path.join(os.path.abspath(sorce), tempfilename)
dst = os.path.join(os.path.abspath(sorce), str(0) * n + str(i) + '.jpg')
spp = str(0) * n + str(i) + '.jpg'
newline = labelname + ' ' + spp + ' ' + splitline[2] + ' ' + splitline[3] + ' ' + splitline[4] + ' ' + \
splitline[5] + '\n'
f2.write(newline)
os.rename(src, dst)
转换成xml文件
f1=open('Anno/selectbox.txt','r')
f3=open('Anno/last.txt','w')
f2=open('Anno/selectxt.txt','r')
line1=f1.readlines()#很多行 box
line2=f2.readlines()#4000行 label
# labellabel=[(line.split()[0].strip())for line in line2]
ount=0
for line in line1:#box
boxlabel=(line.split()[0].strip())
for linee in line2:
if boxlabel==(linee.split()[0].strip()):
l1=linee.split()[-1].strip()
line3=l1+' '+line
ount+=1
# print(line3)
# print(ount)
f3.write(line3)
制作ImageSets\Main里的四个txt文件
# -*- coding: utf-8 -*-
# @Author : matthew
# @File : make_train_val_test_set.py
# @Software: PyCharm
import os
import random
def _main():
trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'F:/jupyter/process/VOC2007/Annotation/'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
ftrainval = open('F:/jupyter/process/VOC2007/ImageSets/Main/trainval.txt', 'w')
ftest = open('F:/jupyter/process/VOC2007/ImageSets/Main/test.txt', 'w')
ftrain = open('F:/jupyter/process/VOC2007/ImageSets/Main/train.txt', 'w')
fval = open('F:/jupyter/process/VOC2007/ImageSets/Main/val.txt', 'w')
for i in list:
name = total_xml[i][:-4] + '\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftest.write(name)
else:
fval.write(name)
else:
ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
if __name__ == '__main__':
_main()
现在终于做好了将我们得到的文件按照固定的要求放入相应的文件夹就好了
我们其实制作了只是想得到三个文件
data
- VOCdevkit2007
- VOC2007
- Annotations (标签XML文件,用对应的图片处理工具人工生成的)
- ImageSets (最后一个代码可以得到)
- Main
- test.txt
- trian.txt
- trainval.txt
- val.txt
- JPEGImages(我们可以在selectimg文件夹下搜索.jpg,然后将得到的4000张图片复制到这个文件夹下面。)
下一篇博客将会讲解如何训练这些图片。