pascal_voc 数据集制作与解析

pascal_voc数据集是一套标准的目标检测数据集。

数据下载地址:https://pjreddie.com/projects/pascal-voc-dataset-mirror/

下载解压后的文件结构:

JPEGImages文件夹下存放的是图片:

Annotation文件夹下存放的是含有每一张图片的object坐标,类别信息的xml文件,并且每一个xml文件与每张图片一一对应:

其数据格式为:

其数据格式为:

ImageSet当中存放的是每各种不同类型图片的文件名,可以在这个文件夹中找到训练和验证集的.txt文件,文件格式如下图所示:左边的000123等代表的是图像文件名称,+1,-1代表的是有还是没有object,下图是boat_val.txt文件。+1代表对应的图中有boat,-1代表对应的图中没有boat

想要使用Pascal_voc数据集,首先就要对这个数据集进行解析。相应的代码:

# -*- coding: utf-8 -*-
"""
Created on Thu Sep 27 21:55:21 2018

@author: LongJun
"""
import os
import xml.etree.ElementTree as ET
import numpy as np
#print (filename)
def get_index(filename):
    with open (filename) as f:
            indexs=[index.strip() for index in f.readlines()]
    return indexs

def load_annoation(root_path,index):
    roidbs = {}
    filename = index
    filename = os.path.join(root_path,'VOCdevkit','VOC2007','Annotations',index+'.xml')
    tree = ET.parse(filename)
    objs = tree.findall('object')
    len_objs = len(objs)
    boxes = np.zeros([len_objs, 4], dtype=np.uint16)
    obj_class = []
    for ix, obj in enumerate(objs):
        bbox = obj.find('bndbox')
        x1 = float(bbox.find('xmin').text) - 1
        x2 = float(bbox.find('xmax').text) - 1
        y1 = float(bbox.find('ymin').text) - 1
        y2 = float(bbox.find('ymax').text) - 1
        boxes[ix, :] = [x1, y1, x2, y2]
        print (boxes[ix, :])
        print (obj.find('name').text)
        obj_class.append(obj.find('name').text)
    roidbs['boxes'] = boxes
    roidbs['obj_class'] = obj_class
    return roidbs, len_objs
    
    
    
if __name__ == '__main__':
    root_dir = os.path.abspath('.')
    filename = 'val' + '.txt'
    filename = os.path.join(root_dir,'VOCdevkit','VOC2007','ImageSets','Main',filename)
    writefile = 'tmp' + '.txt'
    wfilename = os.path.join(root_dir, writefile)
    indexs = get_index(filename)
    for index in indexs:
        roidbs, len_objs= load_annoation(root_dir, index)
        with open(wfilename,"a") as f:
            #print (roidbs['boxes'][0,0])
            for ix in range(len_objs):
                f.writelines(roidbs['obj_class'][ix] + "\n")
                for i in range(4):
                    f.write(str(roidbs['boxes'][ix][i]) + "\n")

解析文件后可以得到每张图片中object的class名称,以及对应的坐标。

在使用自己的图片进行训练时,首先要做的是将自己的图片制作成pascal_voc的数据格式。这里推荐使用labelImg软件用于标签并生成pascal_voc数据集的格式。

首先在github上下载https://github.com/tzutalin/labelImg源码,然后在anaconda中进行安装:

conda install pyqt=5

pyrcc5 -o resources.py resources.qrc

之后就可以运行labelImg进行标签。首先建立和pascal_voc数据集格式一样的文件夹:

这里写图片描述

然后将图片放入JPEGImages中,

labelimg窗口的使用方法:
• 修改默认的XML文件保存位置,可以用“Ctrl+R”,改为自定义位置,这里的路径不能包含中文,否则无法保存。

• 可以修改源码目录下的data/predefined_classes.txt,修改默认类别,比如改成bus、car、building三个类别。

•“Open Dir”打开需要标注的样本图片文件夹,会自动打开第一张图片,开始进行标注

• 使用“Create RectBox”开始画框

• 完成一张图片后点击“Save”,此时XML文件已经保存到本地了。

• 点击“Next Image”转到下一张图片。

• 标注过程中可随时返回进行修改,后保存的文件会覆盖之前的。

• 完成标注后打开XML文件,发现确实和PASCAL VOC所用格式一样。

之后还应制作.txt文件,这里可以选择从.xml文件生成训练集和验证集:

%注意修改下面四个值  
xmlfilepath='E:\Annotations';  
txtsavepath='E:\ImageSets\Main\';  
trainval_percent=0.5; #trainval占整个数据集的百分比,剩下部分就是test所占百分比  
train_percent=0.5; #train占trainval的百分比,剩下部分就是val所占百分比  

xmlfile=dir(xmlfilepath);  
numOfxml=length(xmlfile)-2;#减去.和..  总的数据集大小  

trainval=sort(randperm(numOfxml,floor(numOfxml*trainval_percent)));  
test=sort(setdiff(1:numOfxml,trainval));  

trainvalsize=length(trainval); #trainval的大小  
train=sort(trainval(randperm(trainvalsize,floor(trainvalsize*train_percent))));  
val=sort(setdiff(trainval,train));  

ftrainval=fopen([txtsavepath 'trainval.txt'],'w');  
ftest=fopen([txtsavepath 'test.txt'],'w');  
ftrain=fopen([txtsavepath 'train.txt'],'w');  
fval=fopen([txtsavepath 'val.txt'],'w');  

for i=1:numOfxml  
    if ismember(i,trainval)  
        fprintf(ftrainval,'%s\n',xmlfile(i+2).name(1:end-4));  
        if ismember(i,train)  
            fprintf(ftrain,'%s\n',xmlfile(i+2).name(1:end-4));  
        else  
            fprintf(fval,'%s\n',xmlfile(i+2).name(1:end-4));  
        end  
    else  
        fprintf(ftest,'%s\n',xmlfile(i+2).name(1:end-4));  
    end  
end  
fclose(ftrainval);  
fclose(ftrain);  
fclose(fval);  
fclose(ftest);  


猜你喜欢

转载自blog.csdn.net/weixin_40446651/article/details/82889299
今日推荐