PASCAL VOC2012数据集

PASCAL VOC2012数据集

下载的官方网址:http://host.robots.ox.ac.uk/pascal/voc/voc2012/index.html#devkit

一、介绍与下载

PASCAL VOC 挑战赛(The PASCAL Visual Object Classes)是一个世界级的计算机视觉挑战赛。PASCAL全称Pattern Analysis, Statistical modelling and Computational Learning(模式分析、统计建模和计算学习),是一个由欧盟资助的网络组织。PASCAL VOC挑战赛主要包括下面几类:

图像分类(Object Classification)
目标检测(Object Detection)
目标分割(Object Segmentation)
动作识别(Action Classification)
etc

找到Development Kit即可进行下载

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jNIcvXub-1674978186874)(C:\Users\GuoShuXian\AppData\Roaming\Typora\typora-user-images\image-20230129113748283.png)]

一共有20个类别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uZXoosWH-1674978186894)(C:\Users\GuoShuXian\AppData\Roaming\Typora\typora-user-images\image-20230129112130517.png)]

二、下载数据集的文件结构及详解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7l4Tc5Mw-1674978186896)(C:\Users\GuoShuXian\AppData\Roaming\Typora\typora-user-images\image-20230129112156244.png)]

1.Annotation

随便打开一个annotation文件:

  # 主节点
	VOC2012  # 文件夹名字
	2007_000187.jpg  # 图片名称
	  # 源
		The VOC2007 Database  # 来自VOC 2007
		PASCAL VOC2007  # 标注信息来源 VOC 2007
		flickr  # 来自网络分享
	
	  # 图片大小节点
		500  # 宽度
		375  # 高度
		3  # 深度(通道数)
	
	1  # 该节点:该图片有没有被分割过(1和0)
	  # 目标检测节点(可以有多个检测目标)
		tvmonitor  # 目标所属类别
		Frontal  # 用不到
		1  # 目标有没有被截断(如果目标在图片的边界,那么就是被截断的状态)
		0  # 目标检测的难易程度(0:容易检测; 1:难以检测)
		  # bounding box
			1  # 左上角x坐标
			95  # 左上角y坐标
			240  # 右下角x坐标
			336  # 右下角y坐标
		
	
	  # 第二个检测目标
		person
		Unspecified
		0
		0
		
			137
			78
			497
			375
		
	
	  # 三个检测目标
		person
		Unspecified
		1
		0
		
			89
			202
			129
			247
		

 
  

flickr 网络 相片分享;
truncated 英[trʌŋˈkeɪtɪd] 美[ˈtrʌŋkeɪtɪd] adj. (版本)缩减的,删节的,截短了的; v. 截短,缩短,删节(尤指掐头或去尾);
一张图片中可以有多个检测目标

2.train.txtval.txt

对于目标检测任务,我们主要关注ImageSets\Main下的train.txtval.txttrainval.txt这三个文件。

下面是train.txtval.txt的部分内容展示(trainval.txt也是下面的样式):

每一行代表图像名称

2008_000008
2008_000015
2008_000019
2008_000023
2008_000028
2008_000033
2008_000036
2008_000037
2008_000041
...

train.txtval.txt包含了训练时图片的名称和验证时图片的名称。

3.trainval.txt

trainval.txt文件包含了训练使用的训练集和验证集。

总所周知,训练集和验证集是互斥的,那么为什么会有 trainval.txt这个文件呢?

因为我们得到结果可以去PASCAL官网进行测试,而PASCAL VOC 2012的测试集是不公开的,所以官方需要知道你在训练时使用了哪些文件,这时我们就需要提交这个文件以此在测试时可以剔除掉我们训练用过的文件。

4.boat_train.txt表示船的训练集

2008_000143 -1
2008_000144 -1
2008_000148  1
2008_000151 -1
2008_000187 -1
2008_000188 -1
2008_000189 -1
2008_000191  0
2008_000192 -1
2008_000193 -1

这个文件中,除了图片的名称外,还有一列,包含三个数-1,0,1,分别表示:

  • -1:图片中没有boat这个目标
  • 0:包含boat目标,但该目标检测很困难
  • 1:图片中boat这个目标

5.文件使用流程

  • 先读取ImageSets/Maintrain.txt,获取它的每一行信息(每一张图片的名称)
  • 得到图片名称后,去Annotation找到对应的.xml文件并解析该文件,得到图片标签的信息
  • 再去ImageSet/JPEGImages找到相应的图片并载入内存

三、标注属于自己的数据集

1. 标注软件介绍与安装

标注图像的软件有很多,在GitHub上有很多开源项目,比如:

https://github.com/tzutalin/labelImg
可以生成 .xml文件

https://github.com/wkentaro/labelme
主要生成json文件

为了保持和PASCAL VOC数据集一致,这里使用labelImg

pip3 install labelImg
labelImg
labelImg ./image[IMAGE_PATH] [PRE-DEFINED CLASS FILE]./class.txt

2.标注软件使用

简单使用流程:

  1. 准备一个关于类别的文件信息
  2. 打开软件
  3. 设置图像文件夹所在目录,以及标注文件保存目录
  4. 标注图像并保存
  5. 若要修改源代码,在项目的libs -> labelFile.py文件中修改

2.1第一步:准确文件和文件夹并进入目标路径

我们先将文件夹和文件准备好,如:

├── annotation
├── classes.txt
└── images
    ├── test_1
    ├── test_1.jpg
    ├── test_2.jpg
    ├── test_3.jpg
    └── test_4.jpg

其中:

  • annotation是标注文件夹,一会儿我们会将软件标注的结果放这里面
  • classes.txt是类别的信息,内容如下:
dog
person
cat
tv
car
meatballs
marinara sauce
tomato soup
chicken noodle soup
french onion soup
chicken breast
ribs
pulled pork
hamburger
cavity

images:放图片的文件夹,里面是具体需要标注的图片

第二步:打开软件

# 进入文件夹
ls
annotation  classes.txt  images

# 打开软件	labelImg [图片文件夹路径] [标签文件]
labelImg ./images/ ./classes.txt 

第三步:设置标注文件保存目录

第四步:标注图像并保存

此时Annotation文件夹下就有一个文件test_1.xml,内容如下:


	images  # 图片所属文件夹
	test_1.jpg  # 图片的名字
	/home/leovin/PyTorchProject/A2_object_detection/faster_rcnn/label_our_datasets/images/test_1.jpg
	
		Unknown
	
	
		1032  # 图片的宽度
		795  # 图片的高度
		3  # 图片的深度
	
	0
	  # 第一个目标
		cat  # 目标的真实类别
		Unspecified
		0  # 没有被截断
		0
		  # BBox的坐标(两个点坐标)
			362
			122
			1029
			790
		
	
	  # 第二个目标
		dog
		Unspecified
		1  # 被截断
		0
		
			30
			342
			415
			795
		
	
	
		dog
		Unspecified
		0  # 没有被截断
		0
		
			684
			165
			953
			582
		
	


之后就可以进行其他图片的标注了。

快捷键(Hotkeys)

key action
Ctrl + u 选择一个目录(文件夹)加载其中所有图片
Ctrl + r 更改标注的保存目录
Ctrl + s 保存本次标注
Ctrl + d 复制当前的标注及标注框
Ctrl + Shift + d 删除当前的图片
Space 标记当前图片为验证集
w 创建一个新的矩形框
d 下一张图片
a 上一张图片
del 删除所选的矩形框
Ctrl + + 放大
Ctrl + - 缩放
↑→↓← 微调矩形框

3. 数据集划分

在得到自己标注好的数据后,如何得到像VOC 2012那样的train.txt文件呢?

import os
import random


def main():
    random.seed(0)  # 设置随机种子,保证随机结果可复现

    # 给定数据集Annotation的路径
    files_path = "./VOCdevkit/VOC2012/Annotations"
    assert os.path.exists(files_path), "path: '{}' does not exist.".format(files_path)

    # 验证集的比例
    val_rate = 0.2  # 因为测试集不公开,训练:验证集=8:2

    """
        for file in os.listdir(files_path)
            其中os.listdir(files_path)遍历该路径下所有的文件
            file就是一个一个文件
        file.split(".")[0]
            分割字符串并取出文件名
        sorted()
            排序函数
        Note: 列表表达式最后得到肯定是一个list
    """
    files_name = sorted([file.split(".")[0] for file in os.listdir(files_path)])
    files_num = len(files_name)  # 得到文件的数量

    """
        random.sample(序列,k=采样个数)
            可以简单理解为从某个list中随机采样k个点(且k不会重复)
            返回值是一个list
                >>> import random
                >>> random.sample(range(0, 10), 6)
                [8, 3, 7, 0, 6, 2]
                
        random.sample(range(0, files_num), k=int(files_num*val_rate))
            从0到files_num-1中随机采样files_num*val_rate个点组成一个list并返回
    """
    val_index = random.sample(range(0, files_num), k=int(files_num*val_rate))
    train_files = []
    val_files = []

    # files_name是一个list,list可以被enumerate
    for index, file_name in enumerate(files_name):
        if index in val_index:  # 如果这张图片是采样图片,则放入验证集
            val_files.append(file_name)
        else:
            train_files.append(file_name)  # 否则放入训练集

    try:
        # 'x'用于创建并写入新文件
        # \n 表示换行符
        train_f = open("train.txt", "x")
        eval_f = open("val.txt", "x")
        train_f.write("\n".join(train_files))
        eval_f.write("\n".join(val_files))
    except FileExistsError as e:
        print(e)
        exit(1)


if __name__ == '__main__':
    main()

你可能感兴趣的:(目标检测,深度学习,计算机视觉)