深度学习(Deep Learning)免费开源数据集汇总(持续更新)

上世纪50年代,几位计算机科学家齐聚达特茅斯,举行了一场人类科技史上具有里程碑意义的重大会议。会场上,他们提出了“人工智能(Artificial Intelligence)”的概念,想象着用当时刚刚出现的计算机来制造与人类智能具有相同本质特征的复杂机器。

此后,人工智能一直萦绕在人们的脑海之中。在计算机技术发展早期,由于受限于计算机算力以及对于数据的缺乏,该学科的发展在很长一段时间里都极其缓慢。值得庆幸的是,从2012年开始,得益于计算机技术以及数据学科的发展,人工智能最终在科研实验室中得以慢慢孵化成形。

从此以后,人工智能的研究领域不断扩大,其研究分支得到了空前的扩充,包括专家系统、机器学习、进化计算、模糊逻辑、计算机视觉、自然语言处理、推荐系统等等。

机器学习(Machine Learning)作为人工智能领域重要学科分支及重要组成,正在被越来越多的领域所使用,以解决传统计算机技术无法解决的复杂问题。其本质就是利用概率论、统计学等数学方法结合计算机技术通过对历史数据进行分析(挖掘),从而获得隐藏的难以被发现的规律(模型),并利用这些规律对未知数据进行预测的一项新兴技术。

而深度学习(Deep Learning),已然成为了当前最热的一门机器学习方法。然而,深度学习模型需要大量的训练数据,才能展现出其强大的威力。数据在深度学习中占据着极其重要的地位,模型训练的质量和预测的准确率离不开高质量的数据集作为支撑

鉴于数据集的重要性及其较高的创作成本及难度,本文致力于汇总并整理国内外高质量开源数据集供大家学习和使用。这些开源免费数据集将涵盖目标检测、图像分割与分类、自动驾驶、姿态估计、自然语言处理、人脸及目标跟踪等领域

LVIS数据集

LVIS(Large Vocabulary Instance Segmentation),大规模的词汇实例分割数据集,来自 FaceBook AI 研究院,用于解决图像分割问题

其中包含了164K图像,并对1000多种物体分类进行了约200万个高质量的实例分割标注。由于数据集中包含自然图像中的物体分布,天然具有长尾属性,该数据集将促进深度学习在图像分割领域的进一步发展。

LVIS数据集最大的特点在于,采集过程中没有预先确定的类别(无类别先验)。首先采集图像,然后根据图像中目标的自然分布进行标注。使用了大量人工标注代替机器自动标注,从而可以有效识别图像中自然存在的长尾分布。

LVIS数据集官方下载地址:https://www.lvisdataset.org/dataset

Crowd Segmentation 数据集

Crowd Segmentation Dataset 由来自不同的公共数据集整合而来,总共包含20组视频数据,由高密度人群和移动物体组成,视频来自于 BBC Motion Gallery 和 Getty Images 网站。

对于数量较大的移动目标进行特征识别,难度较大。为解决这类难点,该数据集采用了将低级运动特征转换为全局相似性结构的思路。这类结构通常被用于拥挤场景中,因其能够展现运动动力学的内在流形,这种特性是低级特征无法捕获的。

官方下载地址:https://www.crcv.ucf.edu/data/UCF_CrowdsDataset.zip

DAVIS 数据集

DAVIS(Densely Annotated Video Segmentation),是一组重要的视频分割数据集。由DAVIS官方团队发布。

DAVIS公开数据集当总前共分为3个版本发布:

  1. DAVIS 2016
  2. DAVIS 2017
  3. DAVIS 2017 Unsupervised

其中,DAVIS 2016 是是一个面向目标级分割的 VOS 数据集,数据标注都是只区分前后景的二元标注(Binary Annotation)。

DAVIS 2017 是面向实例级分割的数据集,它比 DAVIS 2016 具有更多的视频图片序列和帧数量,且在每个视频内可能出现多个目标,该数据集最大的特点在于每个目标都被作为单独的个体标注区分开来。

而 DAVIS 2017 Unsupervised 则是一个针对无监督视频目标分割的数据集。该数据集在上述第二项 2017 版本之上重新标注了分割标签,因此,分割标注的语义关联一致性得到了显著提升,并且针对原有数据集对 Semi-Supervised Segmentation 的偏好性做了弱化和消除。

官方下载地址:

COCO2017 数据集

COCO通过大量使用 Amazon Mechanical Turk 来收集数据,是一个大规模的目标检测、分割、图注数据集。

COCO2017 Dataset 是2017年发布的COCO数据集的一个版本,主要用于物体检测任务、关键点检测任务和全景分割任务。

COCO2017数据集一共有五种标注类型:

  1. 目标检测
  2. 关键点检测
  3. 素材分割
  4. 全景分割
  5. 图像说明

标注信息使用 JSON 格式存储,预处理通过 COCO API 用于访问和操作所有“标注”。

官方下载地址:COCO - Common Objects in Context

IMDB-WIKI 数据集

IMDB-WIKI Dataset 500k+ 是一个包含名人人脸图像、年龄、性别的数据集,是目前为止最大的用于年龄检测的数据集。

图像和年龄、性别信息从 IMDB 和 WiKi 网站抓取,总计 524230 张名人人脸图像及对应的年龄和性别。其中,获取自 IMDB 的 460723 张,获取自 WiKi 的 62328 张。

官方下载地址:https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/

MNIST 数据集

MNIST(Mixed National Institute of Standards and Technology) Dataset 是一个大型手写阿拉伯数字图像识别数据集,由美国国家标准与技术研究院收集及整理。

MNIST 数据集中图片分辨率为 20x20 灰度图图片,包含“0-9”十组手写阿拉伯数字的图片。该数据集一共包含 4 个文件,分别是训练集、训练集标签、测试集、测试集标签。

数据集总共包含训练样本60000,测试样本10000,数据为图片的像素点值,并且数据集都已经过了压缩。

直接下载下来的数据无法通过解压软件或者图像处理软件直接打开,因为这些文件不是任何标准的图像格式而是以字节的形式进行存储的,所以必须编写特定的程序来打开它

使用 TensorFlow 解压 MNIST 数据集

可以使用 TensorFlow 中 input_data.py 脚本来读取数据及标签,此方法可以不用事先下载数据集,Python 脚本能够自动下载并将数据集存放到你指定的位置。

代码如下:

from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt

mnist = input_data.read_data_sets('MNIST_data',one_hot=True)    # MNIST_data指的是存放数据的文件夹路径,one_hot=True 为采用one_hot的编码方式编码标签

#load data
train_X = mnist.train.images                #训练集样本
validation_X = mnist.validation.images      #验证集样本
test_X = mnist.test.images                  #测试集样本
#labels
train_Y = mnist.train.labels                #训练集标签
validation_Y = mnist.validation.labels      #验证集标签
test_Y = mnist.test.labels                  #测试集标签

print(train_X.shape,train_Y.shape)          #输出训练集样本和标签的大小

#查看数据,例如训练集中第一个样本的内容和标签
print(train_X[0])       #是一个包含784个元素且值在[0,1]之间的向量
print(train_Y[0])

#可视化样本,下面是输出了训练集中前20个样本
fig, ax = plt.subplots(nrows=4,ncols=5,sharex='all',sharey='all')
ax = ax.flatten()
for i in range(20):
    img = train_X[i].reshape(28, 28)
    ax[i].imshow(img,cmap='Greys')
ax[0].set_xticks([])
ax[0].set_yticks([])
plt.tight_layout()
plt.show()

输出结果:

(55000, 784) (55000, 10)        #训练集样本和标签的大小
第一个样本的内容输出较多,省略
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]   #第一个样本的标签,one-hot编码,只有对应位置的值是1,其余都是0

MNIST 训练集中前20个图像样本如下:

官方下载地址:MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges

ALOV300++ 数据集

ALOV++,Amsterdam Library of Ordinary Videos for tracking 是一个物体追踪视频数据集,以短视频为主(平均长度为9.2秒,最长35秒),用于对处于不同光线、通透度、泛着条件、背景杂乱程度、焦距下的相似物体进行追踪。

该视频数据集主要来自 YouTube,包含64个不同类型的目标,包括人脸、人体、球、章鱼、微观细胞、塑料袋或罐子。

数据集中的视频被分为13个难度状况,其中有许多困难乃至非常困难的视频,如舞者、音乐会中的摇滚歌手、完全透明的玻璃、章鱼、鸟群、穿着迷彩服的士兵、完全被遮挡的物体以及运动目标突然突然进入视野并且被极端放大的视频。

ALOV++还包括11个来自现有数据集的标准跟踪视频序列,以涵盖平滑度和遮挡方面,从而与其他跟踪基准向上兼容。此外,我们还选择了11个标准视频序列,这些序列在最近的跟踪论文中经常使用,涉及光线、反照率、透明度、运动平滑度、混淆、遮挡和相机晃动等方面。

65个序列已经在PETS研讨会上报告过,250个是新的,总共有315个视频序列。

官方下载地址:http://alov300pp.joomlafree.it/

HMDB 数据集

HMDB(Human Motion Database)是由布朗大学发布的人类动作视频数据集,该数据集是动作识别研究领域最为重要的几个数据集之一。

到目前为止,尽管人们在收集和注释包含数千种图像类别的大型可伸缩静态图像数据集方面付出了大量努力,但人类行为数据集却远远落后于此。

为解决此问题,HMDB数据库由此而生。数据集中视频多数来源于电影,还有一部分来自公共数据库以及YouTube等网络视频库。

HMDB数据库包含有6849段样本,分为51类,每类至少包含有101段样本,因此该数据集也被称为HMDB51。

HMDB数据集人类动作主要分为以下五类:

  1. 一般面部动作:微笑,大笑,咀嚼,交谈。
  2. 面部操作与对象操作:吸烟,吃,喝。
  3. 一般的身体动作:侧手翻,拍手,爬,爬楼梯,跳,落在地板上,反手翻转、倒立、跳、拉、推、跑,坐下来,坐起来,翻跟头,站起来,转身,走,波。
  4. 与对象交互动作:梳头,抓,抽出宝剑,运球、高尔夫、打东西,球、挑、倒、推东西,骑自行车,骑马,射球,射弓、枪、摆棒球棍、剑锻炼,扔。
  5. 人体动作:击剑,拥抱,踢某人,亲吻,拳打,握手,剑战。

HMDB 51种动作示例如下:

HMDB 测试样本示例如下:

除了动作类别的标签之外,每个剪辑还带有动作标签以及描述剪辑属性的元标签。由于环境以及摄像设备及环境差别,对于全方位的覆盖,可以从正面,侧面(左右)和向后的角度观察运动。视频质量的3级分级适用于评估大量剪辑。

另外,还包括两个不同的类别,即“不运动”和“相机运动”。后者是变焦,旅行镜头和相机晃动等的结果。

为了消除可能存在重大的相机/背景运动,数据集在加工过程中使用了标准的图像拼接技术来对齐剪辑的帧。

官方下载地址:

Kaggle 数据集

Kaggle Garbage Classification Dataset 为图片数据集,主要用于垃圾分类,该数据集包含总共2527张图片,其中O代表Organic(有机垃圾),R代表Recycle(可回收)。

数据集详细分为6类生活垃圾,分别为:

  • Cardboard (403张)
  • Glass (501张)
  • Metal (410张)
  • Paper (594张)
  • Plastic (482张)
  • Trash (137张)

该数据集的图片具有相同的规格尺寸,且要检测的垃圾大多数位于图片中央,因此非常适合于训练深度学习模型。数据集85%为训练集(Train),15%为测试集(Test)。

由于该数据集是一个较小的数据集,仅有两千多张图片,但通常训练深度学习模型都要求有上万张乃至更多的图片。去网上采集更多的图片扩充数据集显然是最理想的方法,但那样会花费大量的时间与精力,因此通过数据增强扩充数据集成了我们的选择。

扩充数据集可以使用 keras.preprocessing.image 模块中的 ImageDataGenerator() 图片生成器函数,同时也可以在batch中对数据进行增强,从而增强模型的泛化能力。比如对图片进行平移、旋转、缩放、翻转等。

在将图片输入模型之前,为了提高模型的准确率,还需将图片进行归一化处理,即将每个像素的值映射到 (0,1) 之间。

实验中我们随机选择90%的图片作为训练集,对训练集进行数据增强操作,剩下10%的图片作为测试集,测试集不做数据增强处理。

Kaggle 数据集使用方法

网络可使用四层卷积层,每一卷积层后接一最大池化层,最后紧跟两层 Dense 层将输出转化为 6×1 的向量。

CNN网络结构示例如下所示:

model = Sequential([
    Conv2D(filters=32, kernel_size=3, padding='same', activation='relu', input_shape=(300, 300, 3)),
    MaxPooling2D(pool_size=2),

    Conv2D(filters=64, kernel_size=3, padding='same', activation='relu'),
    MaxPooling2D(pool_size=2),
    
    Conv2D(filters=32, kernel_size=3, padding='same', activation='relu'),
    MaxPooling2D(pool_size=2),
    
    Conv2D(filters=32, kernel_size=3, padding='same', activation='relu'),
    MaxPooling2D(pool_size=2),

    Flatten(),

    Dense(64, activation='relu'),

    Dense(6, activation='softmax')
])

示例结果展示

CNN模型训练过程的学习率曲线

上图中可见模型在 epoch 达到 40 时便开始趋向收敛,之后随着训练次数的增加,模型效果也没有提升,在整个训练过程中测试集上取得的最好的准确率为 79.4%。而学习率曲线波动很大原因是测试集太小,仅含两百多涨图片存在较大的偶然性。

上图为部分分类结果展示,Pred 为模型所判断的每张图片的所属垃圾类别,Truth 为每张图片真实的所属垃圾类别。从图中可见,模型对大部分的垃圾图片分类结果都比较准确,仅第四张将一个玻璃瓶误判为了金属,这也情有可原,因为该图片中玻璃瓶的反光因素使得该玻璃瓶确实看起来有点像银白色金属。

官方下载地址:

更多 Kaggle 项目:2022年最值得推荐的20个 Kaggle 机器学习项目

Wider Face 数据集

Wider Face 数据集最早于2015年公开首个版本。该数据集挑选出了 32203 张图片并进行了人脸标注,总共标注了 393703 个人脸数据。其中,158989 个标注人脸位于训练集,39496 个位于验证集。每一个子集都包含3个级别的检测难度:Easy,Medium,Hard。

数据集对于每张人脸都附带有更加详细的信息,包扩blur(模糊程度), expression(表情), illumination(光照), occlusion(遮挡), pose(姿态)等信息。

在数据集中,根据事件场景的类型分为了61个类。接着根据每个类别按照40% / 10% / 50%的比例划分到训练集,验证集以及测试集中。如下图:

数据集结构

数据集包括训练集(Training Images),验证集(Validation Images)以及标注文件(Face annotations)。建议按照下图目录结构摆放。

标注文件解析

在标注文件中分.mat.txt 两个版本,随便用哪一个都可以。这里,我们以分析txt格式为例。

首先看下readme.txt 文件里的说明:

在说明文件中,给出了详细的标签格式说明:

  • 第一行File name为图片的路径名称
  • 第二行Number of bounding box为该图片中标注人脸的个数
  • 接下来的Number of bounding box行信息为每个人脸的详细信息x1, y1, w, h, blur, expression, illumination, invalid, occlusion, pose

我们进一步看下每个人脸的详细信息x1, y1, w, h, blur, expression, illumination, invalid, occlusion, pose:

  • 其中x1, y1, w, h代表人脸边界框的左上角x、y坐标,以及宽、高信息,注意这里是绝对坐标。
  • blur代表人脸的模糊程度,0代表清晰,1代表有点模糊,2代表很模糊。
  • expression代表表情,0代表正常的表情,1代表夸张的表情。
  • illumination代表光照条件,0代表正常光照,1代表极端的光照条件。
  • invalid这个参数其实有点迷,我通过绘制了一些invalid人脸图片发现,基本都是很小,很难分辨的人脸(不仔细看,看不出来的那种),个人觉得在使用时可以忽略掉invalid的人脸即为1的情况。
  • occlusion代表人脸的遮挡程度,0代表没有遮挡,1代表部分遮挡(1%-30%),2代表严重遮挡(30%以上)。
  • pose代表人脸的姿态,0代表典型姿态,1代表非典型姿态。论文中给出的解释Face is annotated as atypical under two conditions: either the roll or pitch degree is larger than 30-degree; or the yaw is larger than 90-degree.。不好理解的可以看下面图示标注的Atypical pose。

解析标签文件 Python 代码

在调用 parse_wider_txt 时,传入 data_root 指向 wider_face 的路径,split 表示要解析训练集还是验证集的标签文件(传入 trainval )。

import os

from tqdm import tqdm
import cv2
from create_xml import create_pascal_voc_xml


def create_xml(labels: list, img_root: str, img_path: str, save_root: str) -> bool:
    source_dict = {'database': 'The WIDERFACE2017 Database',
                   'annotation': 'WIDERFACE 2017',
                   'image': 'WIDERFACE'}

    img_full_path = os.path.join(img_root, img_path)
    if os.path.exists(img_full_path):
        im = cv2.imread(img_full_path)
        im_shape = im.shape
    else:
        print(f"Warning: {img_path} does not exist, can't read image shape.")
        im_shape = (0, 0, 0)

    ob_list = []
    for ob in labels:
        if ob[7] == '1':
            # invalid face image, skip
            continue

        if int(ob[2]) <= 0 or int(ob[3]) <= 0:
            print(f"Warning: find bbox w or h <= 0, in {img_path}, skip.")
            continue

        ob_dict = {'name': 'face',
                   'truncated': '0' if ob[8] == '0' else '1',
                   'difficult': '1' if ob[4] == '2' or ob[8] == '2' else '0',
                   'xmin': ob[0], 'ymin': ob[1],
                   'xmax': str(int(ob[0]) + int(ob[2])),
                   'ymax': str(int(ob[1]) + int(ob[3])),
                   'blur': ob[4], 'expression': ob[5],
                   'illumination': ob[6], 'invalid': ob[7],
                   'occlusion': ob[8], 'pose': ob[9]}

        # if ob[7] == '1':
        #     cv2.rectangle(im, (int(ob_dict['xmin']), int(ob_dict['ymin'])),
        #                   (int(ob_dict['xmax']), int(ob_dict['ymax'])),
        #                   (0, 0, 255))
        #     cv2.imshow("s", im)
        #     cv2.waitKey(0)

        ob_list.append(ob_dict)
    
    if len(ob_list) == 0: 
        print(f"in {img_path}, no object, skip.")
        return False

    create_pascal_voc_xml(filename=img_path,
                          years="WIDERFACE2017",
                          source_dict=source_dict,
                          objects_list=ob_list,
                          im_shape=im_shape,
                          save_root=save_root)

    return True


def parse_wider_txt(data_root: str, split: str, save_root: str):
    """
    refer to: torchvision.dataset.widerface.py
    :param data_root:
    :param split:
    :param save_root:
    :return:
    """
    assert split in ['train', 'val'], f"split must be in ['train', 'val'], got {split}"

    if os.path.exists(save_root) is False:
        os.makedirs(save_root)

    txt_path = os.path.join(data_root, 'wider_face_split', f'wider_face_{split}_bbx_gt.txt')
    img_root = os.path.join(data_root, f'WIDER_{split}', 'images')
    with open(txt_path, "r") as f:
        lines = f.readlines()
        file_name_line, num_boxes_line, box_annotation_line = True, False, False
        num_boxes, box_counter, idx = 0, 0, 0
        labels = []
        xml_list = []
        progress_bar = tqdm(lines)
        for line in progress_bar:
            line = line.rstrip()
            if file_name_line:
                img_path = line
                file_name_line = False
                num_boxes_line = True
            elif num_boxes_line:
                num_boxes = int(line)
                num_boxes_line = False
                box_annotation_line = True
            elif box_annotation_line:
                box_counter += 1
                line_split = line.split(" ")
                line_values = [x for x in line_split]
                labels.append(line_values)
                if box_counter >= num_boxes:
                    box_annotation_line = False
                    file_name_line = True

                    if num_boxes == 0:
                        print(f"in {img_path}, no object, skip.")
                    else:
                        if create_xml(labels, img_root, img_path, save_root):
                            # 只记录有目标的xml文件
                            xml_list.append(img_path.split("/")[-1].split(".")[0])

                    box_counter = 0
                    labels.clear()
                    idx += 1
                    progress_bar.set_description(f"{idx} images")
            else:
                raise RuntimeError("Error parsing annotation file {}".format(txt_path))

        with open(split+'.txt', 'w') as w:
            w.write("\n".join(xml_list))


parse_wider_txt("/data/wider_face/",
                "val",
                "./annotation/")

如果想把标注文件转化为XML格式,代码如下:

import copy
import os
from xml.dom import minidom as dom


class XMLGenerator(object):
    def __init__(self, xml_name: str):
        self.doc = dom.Document()
        self.xml_name = xml_name

    def create_append_node(self, node_name, root_node=None):
        """创建一个新node并将node添加到root_node下"""
        new_node = self.doc.createElement(node_name)
        if root_node is not None:
            root_node.appendChild(new_node)
        else:
            self.doc.appendChild(new_node)
        return new_node

    def create_text_node(self, node_name, node_value, root_node):
        """
        创建一个新node,然后在该node中添加一个text_node,
        最后将node添加到root_node下
        """
        new_node = self.doc.createElement(node_name)
        node_data = self.doc.createTextNode(node_value)
        new_node.appendChild(node_data)
        root_node.appendChild(new_node)

    def create_object_node(self, info_dict: dict = None, root_node: str = None):
        if (info_dict is None) or (root_node is None):
            return

        object_node = self.create_append_node('object', root_node)
        box_node = self.create_append_node('bndbox', object_node)
        self.create_text_node("xmin", info_dict.pop("xmin"), box_node)
        self.create_text_node("ymin", info_dict.pop("ymin"), box_node)
        self.create_text_node("xmax", info_dict.pop("xmax"), box_node)
        self.create_text_node("ymax", info_dict.pop("ymax"), box_node)

        for k, v in info_dict.items():
            self.create_text_node(k, v, object_node)

    def save_xml(self):
        f = open(self.xml_name, "w")
        self.doc.writexml(f, addindent="\t", newl="\n")
        f.close()


def create_pascal_voc_xml(filename: str = None,
                          years: str = 'VOC2012',
                          source_dict: dict = None,
                          objects_list: list = None,
                          im_shape: tuple = None,
                          save_root: str = os.getcwd(),
                          cover: bool = False):
    if not (filename and source_dict and objects_list and im_shape):
        return

    # 0--Parade/0_Parade_marchingband_1_849.jpg -> 0_Parade_marchingband_1_849.xml
    xml_name = filename.split(os.sep)[-1].split(".")[0] + '.xml'
    xml_full_path = os.path.join(save_root, xml_name)
    if os.path.exists(xml_full_path) and (cover is False):
        print(f"{xml_full_path} already exist, skip.")
        return

    xml_generator = XMLGenerator(xml_full_path)

    # xml root node
    node_root = xml_generator.create_append_node('annotation')
    xml_generator.create_text_node(node_name='folder', node_value=years, root_node=node_root)
    xml_generator.create_text_node(node_name='filename', node_value=filename, root_node=node_root)

    # source
    node_source = xml_generator.create_append_node('source', root_node=node_root)
    xml_generator.create_text_node(node_name='database', node_value=source_dict['database'], root_node=node_source)
    xml_generator.create_text_node(node_name='annotation', node_value=source_dict['annotation'], root_node=node_source)
    xml_generator.create_text_node(node_name='image', node_value=source_dict['image'], root_node=node_source)

    # size
    node_size = xml_generator.create_append_node('size', root_node=node_root)
    xml_generator.create_text_node(node_name='height', node_value=str(im_shape[0]), root_node=node_size)
    xml_generator.create_text_node(node_name='width', node_value=str(im_shape[1]), root_node=node_size)
    xml_generator.create_text_node(node_name='depth', node_value=str(im_shape[2]), root_node=node_size)

    # segmented
    xml_generator.create_text_node(node_name='segmented', node_value='0', root_node=node_root)

    # object
    for i, ob in enumerate(objects_list):
        xml_generator.create_object_node(info_dict=ob, root_node=node_root)

    # XML write
    xml_generator.save_xml()


def create_xml_test():
    objects = []
    ob = {'name': 'person', 'pose': 'Unspecified', 'truncated': '0', 'difficult': '0',
          'xmin': '174', 'ymin': '101', 'xmax': '349', 'ymax': '351'}
    objects.append(ob)
    objects.append(copy.deepcopy(ob))

    years = 'VOC2012'
    filename = 'test.jpg'
    source_dict = {'database': 'The VOC2007 Database', 'annotation': 'PASCAL VOC2007', 'image': 'flickr'}
    im_width = '500'
    im_height = '700'
    im_depth = '3'
    im_shape = (im_width, im_height, im_depth)
    create_pascal_voc_xml(filename=filename, years=years,
                          source_dict=source_dict, objects_list=objects,
                          im_shape=im_shape)

转换为XML后样本如下:

Wider Face数据集下载地址:

LFW 人脸数据集

LFW(Labeled Faces in the Wild)人脸数据集是用于研究无约束面部识别问题的面部照片数据库。数据集包含从网络收集的13000多张图像。每张脸都贴上了所画的人的名字,图片中的1680人在数据集中有两个或更多不同的照片。

该数据集当前包含四组不同的 LFW 图像,包括原始图像和三种不同类型的 aligned 图像。对齐的图像包括 funneled images(ICCV 2007),以及使用未公开对齐方法的 LFW-adeep funneled images(NIPS 2012)。

其中,LFW-adeep funneled 图像为大多数人脸验证算法提供了优于原始图像和funneled 图像的优异结果(ICCV 2007)。

LFW 数据集下载地址:https://vis-www.cs.umass.edu/lfw/#download

GENKI 数据集

GENKI人脸数据集主要用于笑脸识别,由加利福尼亚大学的机器概念实验室收集。该数据集包含GENKI-R2009a、GENKI-4K、GENKI-SZSL 三个部分。

GENKI-4K 数据集样本

GENKI-R2009a包含11159个图像,GENKI-4K包含4000个图像,分为“笑”和“不笑”两种,每个图片的人脸的尺度大小,姿势,光照变化,头的转动等都不一样,专门用于做笑脸识别。GENKI-SZSL包含3500个图像,这些图像包括广泛的背景,光照条件,地理位置,个人身份和种族等。

数据集文件下载:GENKI-R2009a.tgz