voc2007数据集_【目标检测数据集】PASCAL VOC制作

【VOC2007+2012】

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

PASCAL VOC为图像识别和分类提供了一整套标准化的优秀的数据集,用于构建和评估用于图像分类(Classification)检测(Object Detection)和分割(Segmentation)的算法,从2005年到2012年每年都会举行一场图像识别challenge。

数据集类别(20类):

Person: person;

Animal: bird, cat, cow, dog, horse, sheep;

Vehicle: aeroplane, bicycle, boat, bus, car, motorbike, train;

Indoor: bottle, chair, dining table, potted plant, sofa, tv/monitor;

数据集目录(VOC2007为例,只列出目标检测所用到的):

-VOCdevkit
      -VOC2007
        -Annotations         #存放xml标注文件,每个xml文件都对应于JPEGImages文件夹的一张图片,文件命名格式为:<图片编号.xml>
        -JPEGImages          #存放训练图片和测试图片,文件命名格式为:<图片编号.jpg>
        -ImageSets           #存放的是challenge对应的图像数据
          -Main              #存放的是图像物体识别的数据,包含下列4个文件,文件内容格式均为:<图片编号>
            -train.txt       #记录训练集所包含的图片编号
            -test.txt        #记录测试集所包含的图片编号
            -val.txt         #记录验证集所包含的图片编号
            -trainval.txt    #记录验证集和训练集所包含的图片编号

把上述目录所列的文件夹建好,接下来制作自己的VOC格式数据集。

【标注工具labelImg】

labelImg软件是一款免费的图像标注工具,常用来为目标检测任务标注数据集。labelImg的安装和使用参考GitHub项目:

https://github.com/tzutalin/labelImg​github.com

记录下自己Mac版本的安装过程:

conda activate 环境名称         #可选
pip install pyqt5
pip install libxml2
pip install labelImg
labelImg                      #运行

【制作自己的数据集】

1.JPEGImages文件夹

搜集并删选出自定类别的图片数据,将所有的.jpg图像文件放入JPEGImages文件夹,命名格式统一为“%6d.jpg”,(000001.jpg)

# -*- coding:utf8 -*-
    '''
    批量重命名文件夹中的图片文件
    '''
import os
class BatchRename():
    def __init__(self):
        self.path = './JPEGImages'  # 修改成自己JPEGImages文件夹路径

    def rename(self):
        filelist = os.listdir(self.path)
        total_num = len(filelist)
        i = 1
        n = 6
        for item in filelist:
            if item.endswith('.jpg'):
                n = 6 - len(str(i))
                src = os.path.join(os.path.abspath(self.path), item)
                dst = os.path.join(os.path.abspath(self.path), str(0) * n + str(i) + '.jpg')
                try:
                    os.rename(src, dst)
                    print
                    'converting %s to %s ...' % (src, dst)
                    i = i + 1

                except:
                    continue
        print
        'total %d to rename & converted %d jpgs' % (total_num, i)
if __name__ == '__main__':
    demo = BatchRename()
    demo.rename()

2.Annotations文件夹

使用labelImg工具标注图片中的目标,选择好图片存放文件夹(JPEGImages)和标注文件夹(Annotations),接下来就是无止尽的标注。。。

3.ImageSets文件夹

在ImageSets文件夹下新建Main文件夹,执行下面代码生成test.txt , train.txt , trainval.txt , val.txt。

# -*- coding:utf-8 -*-

import os  
import random  

trainval_percent = 0.7    # 自己设定(训练集+验证集)所占(训练集+验证集+测试集)的比重  
train_percent = 0.8       # 自己设定(训练集)所占(训练集+验证集)的比重
xmlfilepath = 'Annotations/'     #注意自己地址是否正确
txtsavepath = 'ImageSets/Main'   #注意自己地址是否正确
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(txtsavepath+'/trainval.txt', 'w')  
ftest = open(txtsavepath+'/test.txt', 'w')  
ftrain = open(txtsavepath+'/train.txt', 'w')  
fval = open(txtsavepath+'/val.txt', 'w')  

for i in list:  
    name = total_xml[i][:-4]+'n'  
    if i in trainval:  
        ftrainval.write(name)  
        if i in train:  
            ftrain.write(name)  
        else:  
            fval.write(name)  
    else:  
        ftest.write(name)  

ftrainval.close()  
ftrain.close()  
fval.close()  
ftest .close()
print('Done')

【数据集常用代码】

1.批量修改xml标签

import os
import xml.etree.ElementTree as ET

#程序功能:批量修改VOC数据集中xml标签文件的标签名称
def changelabelname(inputpath):
    listdir = os.listdir(inputpath)
    for file in listdir:
        if file.endswith('xml'):
            file = os.path.join(inputpath,file)
            tree = ET.parse(file)
            root = tree.getroot()
            for object1 in root.findall('object'):
                for sku in object1.findall('name'):           #查找需要修改的名称
                    if (sku.text == 'type2_03'):               #‘preName’为修改前的名称
                        sku.text = 'type2_02'                 #‘TESTNAME’为修改后的名称
                        tree.write(file,encoding='utf-8')     #写进原始的xml文件并避免原始xml中文字符乱码
                    else:
                        pass
        else:
            pass

if __name__ == '__main__':
    inputpath = 'anno/'  #此处替换为自己的路径
    changelabelname(inputpath)

2.批量统计每个类别的图片数量及目标数量

import re
import os
import xml.etree.ElementTree as ET

class1 = 'type1_01'    #根据自己的类别修改(以下要均修改)
class2 = 'type2_02'
class3 = 'type2_03'
class4 = 'type1_02'
'''
class20 = 'tvmonitor'
'''
annotation_folder = './Annotations/'  # 改为自己标签文件夹的路径
# annotation_folder = '/home/.../VOC2007/Annotations/'
list = os.listdir(annotation_folder)


def file_name(file_dir):
    L = []
    for root, dirs, files in os.walk(file_dir):
        for file in files:
            if os.path.splitext(file)[1] == '.xml':
                L.append(os.path.join(root, file))
    return L


total_number1 = 0    
total_number2 = 0
total_number3 = 0
total_number4 = 0
'''
total_number20 = 0
'''
total = 0
total_pic = 0

pic_num1 = 0
pic_num2 = 0
pic_num3 = 0
pic_num4 = 0
'''
pic_num20 = 0
'''

flag1 = 0
flag2 = 0
flag3 = 0
flag4 = 0
'''
flag20 = 0
'''

xml_dirs = file_name(annotation_folder)

for i in range(0, len(xml_dirs)):
    print(xml_dirs[i])

    annotation_file = open(xml_dirs[i]).read()

    root = ET.fromstring(annotation_file)

    total_pic = total_pic + 1
    for obj in root.findall('object'):
        label = obj.find('name').text
        if label == class1:
            total_number1 = total_number1 + 1
            flag1 = 1
            total = total + 1
        if label == class2:
            total_number2 = total_number2 + 1
            flag2 = 1
            total = total + 1
        if label == class3:
            total_number3 = total_number3 + 1
            flag3 = 1
            total = total + 1
        if label == class4:
            total_number4 = total_number4 + 1
            flag4 = 1
            total = total + 1
        '''
        if label == class20:
            total_number20=total_number20+1
            flag20=1
            total = total + 1
        '''

    if flag1 == 1:
        pic_num1 = pic_num1 + 1
        # print("pic number:", pic_num1)
        flag1 = 0
    if flag2 == 1:
        pic_num2 = pic_num2 + 1
        flag2 = 0
    if flag3 == 1:
        pic_num3 = pic_num3 + 1
        flag3 = 0
    if flag4 == 1:
        pic_num4 = pic_num4 + 1
        flag4 = 0
    '''
    if flag20==1:
        pic_num20=pic_num20+1
        flag20=0
    '''

print(class1, pic_num1, total_number1)
print(class2, pic_num2, total_number2)
print(class3, pic_num3, total_number3)
print(class4, pic_num4, total_number4)
'''
print(class20,pic_num20, total_number20)
'''

print("total", total_pic, total)

3.图片批量增广(水平、上下翻转等)

"""
图片批量翻转
"""
from PIL import Image
import os
import os.path

# 指明被遍历的文件夹
rootdir = r'Rust_01/'
for parent, dirnames, filenames in os.walk(rootdir):  # 遍历图片
    for filename in filenames:
        print('parent is :' + parent)
        print('filename is :' + filename)
        currentPath = os.path.join(parent, filename)
        print('the fulll name of the file is :' + currentPath)

        im = Image.open(currentPath)
        # Image.FLIP_LEFT_RIGHT,表示将图像左右翻转
        out = im.transpose(Image.FLIP_LEFT_RIGHT)

        # Image.FLIP_TOP_BOTTOM,表示将图像上下翻转
        # out = im.transpose(Image.FLIP_TOP_BOTTOM)

        # Image.ROTATE_90,表示将图像逆时针旋转90°
        # out = im.transpose(Image.ROTATE_90)

        # Image.ROTATE_180,表示将图像逆时针旋转180°
        # out = im.transpose(Image.ROTATE_180)

        # Image.ROTATE_270,表示将图像逆时针旋转270°
        # out = im.transpose(Image.ROTATE_270)

        # Image.TRANSPOSE,表示将图像进行转置(相当于顺时针旋转90°)
        # out = im.transpose(Image.TRANSPOSE)

        # Image.TRANSVERSE,表示将图像进行转置,再水平翻转
        # out = im.transpose(Image.TRANSVERSE)

        # 新建文件夹保存翻转后图片
        newname = r"Rust_01/" + '' + filename
        out.save(newname)  # 保存结束

说明:研一初学目标检测,本文记录自己制作数据集的过程,以上参考、摘抄于以下文章,推荐阅读。有些代码忘记在哪里借鉴的了,如有读者见到,联系,加入参考链接。

参考:

转载:VOC2007数据集制作 - _harvey - 博客园​www.cnblogs.com CSDN-专业IT技术社区-登录​blog.csdn.net CSDN-专业IT技术社区-登录​blog.csdn.net
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值