制作voc数据集

1主要是从一些大的数据集里面抽取部分数据,然后根据大数据集的TXT标签文件和box文件,制作小数据集的标签,然后进行重新命名,转换成xml文件,进行训练。
2数据集的结构特点:数据集原始文件包括Anno/list_category_img.txt

  • **1 从数据集将每种标签大于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)
  • 2 将标签大于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#为了检验数量
  • 3 将这两千个图片的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)
  • 4 根据标签文件,将图片读取出来,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")

  • 5 将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)
  • 6 修改路径的名字,并将最后的修改文件写在标签文件里面改成这样的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)
        i+=1

8 转换成xml文件

"""conver to xml"""
import copy
from lxml.etree import Element, SubElement, tostring, ElementTree
import cv2
template_file = 'anno.xml'
target_dir = 'F:/jupyter/process/VOC2007/Annotation/'
image_dir = 'F:/jupyter/process/VOC2007/JPEGImages/'  # 图片文件夹
train_file = 'a1.txt'  # 存储了图片信息的txt文件
with open(train_file) as f:
    trainfiles = f.readlines()
file_names = []
for line in trainfiles:
    trainFile = line.split()
    file_name = trainFile[1]
    if file_name not in file_names:
        file_names.append(file_name)
        lable = trainFile[0]
        xmin = trainFile[2]
        ymin = trainFile[3]
        xmax = trainFile[4]
        ymax = trainFile[5]

        tree = ElementTree()
        tree.parse(template_file)
        root = tree.getroot()
        # filename
        root.find('filename').text = file_name
        # size
        sz = root.find('size')
        im = cv2.imread(image_dir + file_name)
        sz.find('height').text = str(300)
        sz.find('width').text = str(300)
        sz.find('depth').text = str(3)
        # object 因为我的数据集都只有一个框
        obj = root.find('object')

        obj.find('name').text = lable
        bb = obj.find('bndbox')
        bb.find('xmin').text = xmin
        bb.find('ymin').text = ymin
        bb.find('xmax').text = xmax
        bb.find('ymax').text = ymax
        # 如果重复,则需要添加object框http://localhost:8888/notebooks/process/voc2007cloth.ipynb#ImageSets\Main里的四个txt文件
        xml_file = file_name.replace('jpg', 'xml')
        tree.write(target_dir + xml_file, encoding='utf-8')     

在这里插入图片描述

  • 9 制作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张图片复制到这个文件夹下面。)
下一篇博客将会讲解如何训练这些图片。

  • 1
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值