训练数据
训练数据集下载地址:
1.下载class-descriptions-boxable.csv 即 V4下的Metadata ClassNames (训练数据集的所有类别)
https://storage.googleapis.com/openimages/web/download.html
2.下载train-images-boxable.csv和train-annotations-bbox.csv (已标记的图片集)
https://www.figure-eight.com/dataset/open-images-annotated-with-bounding-boxes/
note:原始训练集有600个类别,数据量庞大,只抽取其中两个类别的图片集作为训练数据集,如Car,Person


数据集预览

import numpy as np
import time
import sys
import os
import random
from skimage import io
import pandas as pd
from matplotlib import pyplot as plt
from shutil import copyfile
import cv2
import tensorflow as tf

base_path = 'D:/data/open-image-v4'#数据集下载的主目录
images_boxable_fname = 'train-images-boxable.csv'
annotations_bbox_fname = 'train-annotations-bbox.csv'
class_descriptions_fname = 'class-descriptions-boxable.csv'

原始图片预览

images_boxable = pd.read_csv(os.path.join(base_path, images_boxable_fname))
images_boxable.head()

图片标记数据预览

annotations_bbox = pd.read_csv(os.path.join(base_path, annotations_bbox_fname))
annotations_bbox.head()

类别预览

class_descriptions = pd.read_csv(os.path.join(base_path, class_descriptions_fname))
class_descriptions.head()

通过annotations_bbox将目标/类别在原图上标记出来

image_name = images_boxable['image_name'][5]
image_url = images_boxable['image_url'][5]
print(image_name,image_url)

e17acd05b631d330.jpg https://requestor-proxy.figure-eight.com/figure_eight_datasets/open-images/train/e17acd05b631d330.jpg

img = io.imread(image_url) #读取网络图片
height, width, _ = img.shape
print(img.shape)
plt.figure(figsize=(15,10))
plt.subplot(1,2,1)
plt.title('Original Image')
plt.imshow(img)
img_id = image_name[:16]
bboxs = annotations_bbox[annotations_bbox['ImageID']==img_id]
img_bbox = img.copy()
for index, row in bboxs.iterrows():
    xmin = row['XMin']
    xmax = row['XMax']
    ymin = row['YMin']
    ymax = row['YMax']
    xmin = int(xmin*width)
    xmax = int(xmax*width)
    ymin = int(ymin*height)
    ymax = int(ymax*height)
    label_name = row['LabelName']
    class_series = class_descriptions[class_descriptions['name']==label_name]
    class_name = class_series['class'].values[0]
    cv2.rectangle(img_bbox,(xmin,ymin),(xmax,ymax),(0,255,0),2)
    font = cv2.FONT_HERSHEY_SIMPLEX
    cv2.putText(img_bbox,class_name,(xmin,ymin-10), font, 1,(0,255,0),2)
plt.subplot(1,2,2)
plt.title('Image with Bounding Box')
plt.imshow(img_bbox)
plt.show()


训练集构造(检测car、person)

抽取数据类别,Car,Person

car = class_descriptions[class_descriptions['class']=='Car']
person = class_descriptions[class_descriptions['class']=='Person']
print(car)
print(person)

570 /m/0k4j Car
68 /m/01g317 Person

抽取car、person原始图片下载地址和对应的标记框数据

#car、person全部标记框数据
car_bbox = annotations_bbox[annotations_bbox['LabelName']==car['name'].values[0]]
person_bbox = annotations_bbox[annotations_bbox['LabelName']==person['name'].values[0]]

car_ids = car_bbox['ImageID']
person_ids = person_bbox['ImageID']

#一张图片包含多个标记框,去掉重复的原始图片id
car_ids = np.unique(car_ids)
person_ids = np.unique(person_ids)

print('car_ids:'+str(len(car_ids)),'person_ids:'+str(len(person_ids)))

car_ids:89465 car_ids:248384

随机选取1000张car和1000张person图片作为训练集

#打乱次序
copy_car_ids = car_ids.copy()
random.seed(1)
random.shuffle(car_ids)

copy_person_ids = person_ids.copy()
random.seed(1)
random.shuffle(person_ids)

n = 1000
sub_car_ids = copy_car_ids[:n]
sub_person_ids = copy_person_ids[:n]

print(sub_car_ids[0:10],sub_person_ids[0:10])

[‘17729c78b866181e’ ‘7b77dbbc71105e1c’ ‘c9a719e92a035033’
‘58539243ddf350d1’ ‘b4bd75496b4880d8’ ‘6b54b697b13d6573’
‘1e8eab50c0f6ff3a’ ‘ec6ff911833016f3’ ‘a10c03baa942e135’
‘81c73298cc8d5349’] [‘763f5e853b1895df’ ‘d469ba5b2e558fc7’ ‘5348a30462ad2308’
‘751439461f7a5fd3’ ‘5734bee1abe8c58e’ ‘730c2135df540687’
‘14920852dd7e8c93’ ‘6bce959fa9db8fbc’ ‘254dbd00353a1d22’
‘f7b5eabe2c2713c8’]

获取原始图片下载地址

sub_car_urls = [images_boxable[images_boxable['image_name']==name+'.jpg'] for name in sub_car_ids]
sub_person_urls = [images_boxable[images_boxable['image_name']==name+'.jpg'] for name in sub_person_ids]

print(sub_car_urls[0].values[0][0])  
print(sub_car_urls[0].values[0][1])

17729c78b866181e.jpg
https://requestor-proxy.figure-eight.com/figure_eight_datasets/open-images/train/17729c78b866181e.jpg

保存urls到磁盘供复用

sub_car_urls_csv = pd.DataFrame()
sub_person_urls_csv = pd.DataFrame()
for i in range(1000):
    sub_car_urls_csv = sub_car_urls_csv.append(sub_car_urls[i], ignore_index = True)
    sub_person_urls_csv = sub_person_urls_csv.append(sub_person_urls[i], ignore_index = True)

sub_car_urls_csv.to_csv(os.path.join('D:/data/open-image-v4','sub_car_urls.csv'),index=False)
sub_person_urls_csv.to_csv(os.path.join('D:/data/open-image-v4','sub_person_urls.csv'),index=False)

下载图片到磁盘(D:/data/open-image-v4/下新建train-data和test-data文件夹,再分别在train-data和test-data下新建文件夹car和person)

sub_car_pd = pd.read_csv(os.path.join(base_path, 'sub_car_urls.csv'))
sub_person_pd = pd.read_csv(os.path.join(base_path, 'sub_person_urls.csv'))

print(sub_car_pd['image_name'][0])
print(sub_car_pd['image_url'][0])

#建议开启多线程下载
#训练图片
for i in range(800):
    img_car = io.imread(sub_car_pd['image_url'][i])
    car_saved_path = os.path.join('D:/data/open-image-v4/train-data/car',sub_car_pd['image_name'][i])
    io.imsave(car_saved_path, img_car)

for j in range(800):
    img_person = io.imread(sub_person_pd['image_url'][j])
    person_saved_path = os.path.join('D:/data/open-image-v4/train-data/person',sub_person_pd['image_name'][j])
    io.imsave(person_saved_path, img_person)

#测试图片
for i in range(800,1000):
    img_car = io.imread(sub_car_pd['image_url'][i])
    car_saved_path = os.path.join('D:/data/open-image-v4/test-data/car',sub_car_pd['image_name'][i])
    io.imsave(car_saved_path, img_car)

for j in range(800,1000):
    img_person = io.imread(sub_person_pd['image_url'][j])
    person_saved_path = os.path.join('D:/data/open-image-v4/test-data/person',sub_person_pd['image_name'][j])
    io.imsave(person_saved_path, img_person)

0000048549557964.jpg
https://requestor-proxy.figure-eight.com/figure_eight_datasets/open-images/train/0000048549557964.jpg

下载完成后,如图所示

将train-data/car、train-data/person合并到同一文件夹train-data/all下,train-test同理
note:由于一张图片可能同时包含car和person,因此合并时会将重复的图片剔除而只保留一张

file_names = ['car','person']
train_path = 'D:/data/open-image-v4/train-data'
for i in range(len(file_names)):
    train_images = os.listdir(os.path.join(train_path,file_names[i]))
    for j in range(len(train_images)):
        original_path = os.path.join(os.path.join(train_path, label_names[i]), train_images[j])
        new_path = os.path.join(os.path.join(train_path, 'all'), train_images[j])
        copyfile(original_path, new_path)
print('all_train_images',len(os.listdir(os.path.join(train_path, 'all'))))

test_path = 'D:/data/open-image-v4/test-data'
for i in range(len(file_names)):
    test_images = os.listdir(os.path.join(test_path,file_names[i]))
    for j in range(len(test_images)):
        original_path = os.path.join(os.path.join(test_path, label_names[i]), test_images[j])
        new_path = os.path.join(os.path.join(test_path, 'all'), test_images[j])
        copyfile(original_path, new_path)      
print('all_test_images',len(os.listdir(os.path.join(test_path, 'all'))))

all_train_images 1558
all_test_images 401

构造包含了标记框的训练集和测试集 train.csv和test.csv

class_descriptions = pd.read_csv("D:/data/open-image-v4/class-descriptions-boxable.csv")
car = class_descriptions[class_descriptions['class']=='Car']
person = class_descriptions[class_descriptions['class']=='Person']
print(car,'\n'+car['name'].values[0])
print(person,'\n'+person['name'].values[0])

570 /m/0k4j Car
/m/0k4j
68 /m/01g317 Person
/m/01g317

抽取car、person的标记框数据

annotations_bbox = pd.read_csv('D:/data/open-image-v4/train-annotations-bbox.csv')
car_bbox = annotations_bbox[annotations_bbox['LabelName']==car['name'].values[0]]
person_bbox = annotations_bbox[annotations_bbox['LabelName']==person['name'].values[0]]
annotations_bbox = pd.concat([car_bbox,person_bbox])

print(annotations_bbox.shape)

(1282796, 13)

train_df = pd.DataFrame(columns=['FileName', 'XMin', 'YMin', 'XMax', 'YMax', 'ClassName'])
train_path = 'D:/data/open-image-v4/train-data/all'
train_images = os.listdir(train_path)
for i in range(len(train_images)):
    sys.stdout.write('Parse train_imgs ' + str(i+1) + '; Number of boxes: ' + str(len(train_df)) + '\r')
    sys.stdout.flush()
    img_name = train_images[i]
    img_id = img_name[0:16]
    tmp_df = annotations_bbox[annotations_bbox['ImageID']==img_id]
    for index, row in tmp_df.iterrows():
        labelName = row['LabelName']
        if labelName == car['name'].values[0]:
            className = 'car'
        elif labelName == person['name'].values[0]:
            className = 'person'
        train_df = train_df.append({'FileName': img_name, 
                                            'XMin': row['XMin'], 
                                            'YMin': row['YMin'], 
                                            'XMax': row['XMax'], 
                                            'YMax': row['YMax'], 
                                            'ClassName':className},ignore_index=True)

train_df.to_csv(os.path.join('D:/data/open-image-v4/train-data', 'train.csv'),index=False)

Parse train_imgs 1557; Number of boxes: 5722

test_df = pd.DataFrame(columns=['FileName', 'XMin', 'YMin', 'XMax', 'YMax', 'ClassName'])
test_path = 'D:/data/open-image-v4/test-data/all'
test_images = os.listdir(test_path)
for i in range(len(test_images)):
    sys.stdout.write('Parse train_imgs ' + str(i+1) + '; Number of boxes: ' + str(len(test_df)) + '\r')
    sys.stdout.flush()
    img_name = test_images[i]
    img_id = img_name[0:16]
    tmp_df = annotations_bbox[annotations_bbox['ImageID']==img_id]
    for index, row in tmp_df.iterrows():
        labelName = row['LabelName']
        if labelName == car['name'].values[0]:
            className = 'car'
        elif labelName == person['name'].values[0]:
            className = 'person'
        test_df = test_df.append({'FileName': img_name, 
                                            'XMin': row['XMin'], 
                                            'YMin': row['YMin'], 
                                            'XMax': row['XMax'], 
                                            'YMax': row['YMax'], 
                                            'ClassName':className},ignore_index=True)

test_df.to_csv(os.path.join('D:/data/open-image-v4/test-data', 'test.csv'),index=False)

Parse train_imgs 401; Number of boxes: 1413

train_df.head()

test_df.head()



目标检测      深度学习

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!