(三)Google Open Images Dataset V5 下载

(三)Google Open Images Dataset V5 下载

(三)Google Open Images Dataset V5 下载

 

 

第一行:是指源图片本身下载,就是一张张图,不包含边界框等信息,主要两个地方可下,CVDF是指通用视觉数据基金会。

(三)Google Open Images Dataset V5 下载

(三)Google Open Images Dataset V5 下载

 

(三)Google Open Images Dataset V5 下载

第二行:train-annotations-bbox.csv、validation-annotations-bbox.csv、test-annotations-bbox.csv

指边界框等信息。我们试着下载一个下来,是个csv文件,我们暂称它为边界框表,打开以后像这样:

(三)Google Open Images Dataset V5 下载

 

 

(三)Google Open Images Dataset V5 下载

第五行:就是标签类别,一幅图上有几个对象,就给你打几个标签,我们暂称它为分类标签表,可做图像分类用。

train-annotations-human-imagelabels-boxable.csv、validation-annotations-human-imagelabels-boxable.csv、test-annotations-human-imagelabels-boxable.csv

(三)Google Open Images Dataset V5 下载

 

(三)Google Open Images Dataset V5 下载

第六行:就是图像的相关信息,它包含图片网址,OpenImages ID,轮换信息,标题,作者和许可证信息,我们暂称它为图片表,可以看得出来,几乎所有的图像都来自flickr网站

train-images-boxable-with-rotation.csv、validation-images-with-rotation.csv、test-images-with-rotation.csv

(三)Google Open Images Dataset V5 下载

 

(三)Google Open Images Dataset V5 下载

 

第七行就是元数据了,比较简单,就是分类实际名称,我们暂称它为标签表。可以将MID格式的类名转换为简短描述

class-descriptions-boxable.csv

(三)Google Open Images Dataset V5 下载

 

表格之间的关系

从上面四个表可以看出,它们形成了一个小小的数据库表关系:

(三)Google Open Images Dataset V5 下载

 

非常简单的外键关系,图片表描述图片信息,最重要是下载地址,边界框表主要描述一张图有几个边框,它与图片表通过外键ImageID关联,同时每个边框具体属于哪个分类,又要通过LabelName外键和标签表关联。

 

(三)Google Open Images Dataset V5 下载

 

使用open image v5 进行目标检测训练,训练单类目标检测器,比如雪人检测器。

下载snowman图片的代码:

下载数据[约1小时]

首先,我们需要安装awscli

sudo pip3 install awscli

然后,我们需要获得相关的openImages文件、class-descriptions-boxable.csv and train-annotations-bbox.csv(1.11GB),这些文件用于定位包含我们感兴趣的对象的文件。

wget https://storage.googleapis.com/openimages/2018_04/class-descriptions-boxable.csv

wget https://storage.googleapis.com/openimages/2018_04/train/train-annotations-bbox.csv

 

接下来,将上面的.csv文件移动到与脚本 getDataFromOpenImages_snowman.py 相同的文件夹中,然后使用下面的脚本下载数据

python3 getDataFromOpenImages_snowman.py

图像被下载到JPEGImages文件夹中,相应的标签文件被写入到labels文件夹中。下载将获得539张图片上的770个雪人实例。下载大约需要一个小时,这取决于互联网的速度。JPEGImages 和 labels 加在一起应该小于136 MB。

import csv
import subprocess
import os

#下载训练集图片
runMode = "train"
#只下载snowman图片
classes = ["Snowman"]

#class-descriptions-boxable.csv文件可以将LabelName转换为简短描述,现在用其创建一个字典,
#通过简短描述查询其LabelName,例如:Snowman-->/m/0152hh
with open('class-descriptions-boxable.csv', mode='r') as infile:
    reader = csv.reader(infile)
    dict_list = {rows[1]:rows[0] for rows in reader}

#如果之前创建了JPEGImages文件夹,将其删除,并重新创建
subprocess.run(['rm', '-rf', 'JPEGImages'])
subprocess.run([ 'mkdir', 'JPEGImages'])

#如果之前创建了labels文件夹,将其删除,并重新创建
subprocess.run(['rm', '-rf', 'labels'])
subprocess.run([ 'mkdir', 'labels'])

#循环下载所需的每个类别的图片
for ind in range(0, len(classes)):
    
    #Class 0 : snowman
    className = classes[ind]
    print("Class " + str(ind) + " : " + className)

    #"grep /m/0152hh train-annotations-bbox.csv",查找含有/m/0152hh的行
    commandStr = "grep " + dict_list[className] + " " + runMode + "-annotations-bbox.csv"
    print(commandStr)
    class_annotations = subprocess.run(commandStr.split(), stdout=subprocess.PIPE).stdout.decode('utf-8')
    #splitlines()返回包含各行作为元素的列表,总共有770个类标注(class annotations)
    #总共有538张图片,边界框共有770个
    class_annotations = class_annotations.splitlines()  

    totalNumOfAnnotations = len(class_annotations)
    print("Total number of annotations : "+str(totalNumOfAnnotations))

    cnt = 0
    for line in class_annotations[0:totalNumOfAnnotations]:
        cnt = cnt + 1
        print("annotation count : " + str(cnt))
        lineParts = line.split(',')
        #使用aws命令下载图片:aws s3 --no-sign-request --only-show-errors cp s3://open-images-dataset/train/lineParts[0].jpg JPEGImages/lineParts[0].jpg
        #lineParts[0]是每张图片的名称,即ImageID
        subprocess.run([ 'aws', 's3', '--no-sign-request', '--only-show-errors', 'cp', 's3://open-images-dataset/'+runMode+'/'+lineParts[0]+".jpg", 'JPEGImages/'+lineParts[0]+".jpg"])
        #将每个标注(框的坐标标注)写入labels文件夹中的与图片同名,后缀为.txt的文件中,一张图片有多个框,就将每个标注都写入同一个文件
        #第一个值表示该标注所属类别的索引,在此都是0,只有一个类别
        #转换box的坐标,原来的是用左上角和右下角的两个点的坐标表示一个框,现在转换为用框的中心点坐标,框的宽,框的高这四个值来表示一个框
        with open('labels/%s.txt'%(lineParts[0]),'a') as f:
            f.write(' '.join([str(ind),str((float(lineParts[5]) + float(lineParts[4]))/2), str((float(lineParts[7]) + float(lineParts[6]))/2), str(float(lineParts[5])-float(lineParts[4])),str(float(lineParts[7])-float(lineParts[6]))])+'\n')

对于多类对象检测器,您将需要为每个类提供更多的示例,您可能希望获得test-annotations-bbox.csv和validation-annotations-bbox.csv文件,然后修改python脚本中的runMode并重新运行它,以便为每个类获得更多的图像。但是在我们当前的雪人案例中,770个实例就足够了。

 

训练集-测试集划分

我们将JPEGImages文件夹中的图像分割为训练和测试集。您可以使用以下splitTrainAndTest.py脚本来实现这一点,并将JPEGImages文件夹的完整路径作为参数传递。

python3 splitTrainAndTest.py /full/path/to/snowman/JPEGImages/

上面的脚本将数据分割为一个训练(90%)和一个测试集(10%),并生成两个文件 snowman_train.txtsnowman_test.txt

import random
import os
import subprocess
import sys

def split_data_set(image_dir):

    f_val = open("snowman_test.txt", 'w')
    f_train = open("snowman_train.txt", 'w')
    
    path, dirs, files = next(os.walk(image_dir))
    data_size = len(files)

    ind = 0
    #10%的数据用作测试集
    data_test_size = int(0.1 * data_size)
    #从整数序列(这里range返回的是可迭代对象)[0, 1, 2, 3,...,data_size]中选择n个随机且独立的元素,返回列表
    test_array = random.sample(range(data_size), k=data_test_size)
    
    for f in os.listdir(image_dir):
        if(f.split(".")[1] == "jpg"):
            ind += 1
            
            if ind in test_array:
                f_val.write(image_dir+'/'+f+'\n')
            else:
                f_train.write(image_dir+'/'+f+'\n')


split_data_set(sys.argv[1])