forked from rykov8/ssd_keras
-
Notifications
You must be signed in to change notification settings - Fork 86
/
data_coco.py
131 lines (115 loc) · 4.54 KB
/
data_coco.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import numpy as np
import os
import json
from ssd_data import BaseGTUtility
class GTUtility(BaseGTUtility):
"""Utility for Microsoft Common Objects in Context (COCO) dataset.
# Arguments
data_path: Path to ground truth and image data.
validation: Boolean for using training or validation set.
"""
def __init__(self, data_path, validation=False):
self.data_path = data_path
if validation:
gt_path = os.path.join(data_path, 'annotations', 'instances_val2014.json')
image_path = os.path.join(data_path, 'val2014')
else:
gt_path = os.path.join(data_path, 'annotations', 'instances_train2014.json')
image_path = os.path.join(data_path, 'train2014')
self.gt_path = gt_path
self.image_path = image_path
with open(gt_path) as f:
data = json.load(f)
classes = ['Background']
class_map = {} # id to index
for category in data['categories']:
#{'id': 78, 'name': 'microwave', 'supercategory': 'appliance'}
class_map[category['id']] = len(classes)
classes.append(category['name'])
self.classes = classes
self.image_names = []
self.data = []
images = {}
num_classes = len(self.classes)
for image in data['images']:
#{'coco_url': 'http://mscoco.org/images/222304',
# 'date_captured': '2013-11-24 19:03:15',
# 'file_name': 'COCO_val2014_000000222304.jpg',
# 'flickr_url': 'http://farm6.staticflickr.com/5146/5639268918_7256fccf23_z.jpg',
# 'height': 640, 'id': 222304, 'license': 1, 'width': 359}
image['annotations'] = []
images[image['id']] = image
for annotation in data['annotations']:
#{'area': 4776.439799999999, 'bbox': [46.72, 252.43, 75.77, 114.94],
# 'category_id': 44, 'id': 79459, 'image_id': 506310, 'iscrowd': 0,
# 'segmentation': [[48.88, 291.18, 61.79, ...]]}
images[annotation['image_id']]['annotations'].append(annotation)
bounding_boxes = {}
for image in images.values():
image_name = image['file_name']
img_width = float(image['width'])
img_height = float(image['height'])
boxes = []
for annotation in image['annotations']:
bbox = annotation['bbox']
x1 = bbox[0]
y1 = bbox[1]
x2 = bbox[0] + bbox[2]
y2 = bbox[1] + bbox[3]
box = [x1, y1, x2, y2]
box[0] /= img_width
box[1] /= img_height
box[2] /= img_width
box[3] /= img_height
class_idx = class_map[annotation['category_id']]
#class_one_hot = [0] * num_classes
#class_one_hot[class_idx] = 1
#box = box + class_one_hot
box = box + [class_idx]
boxes.append(box)
if len(boxes) == 0:
#print(image_name)
continue # do not add images that contain no object
boxes = np.empty((0,4+num_classes))
else:
boxes = np.asarray(boxes)
self.image_names.append(image_name)
self.data.append(boxes)
self.init()
def convert_to_voc(self):
voc_classes = [
'Background',
'Aeroplane',
'Bicycle',
'Bird',
'Boat',
'Bottle',
'Bus',
'Car',
'Cat',
'Chair',
'Cow',
'Diningtable',
'Dog',
'Horse',
'Motorbike',
'Person',
'Pottedplant',
'Sheep',
'Sofa',
'Train',
'Tvmonitor',
]
# only for classes with different names
coco_to_voc_map = [
['airplane', 'aeroplane', ],
['dining table', 'diningtable', ],
['motorcycle', 'motorbike', ],
['potted plant', 'pottedplant', ],
['couch', 'sofa', ],
['tv', 'tvmonitor' ],
]
return self.convert(voc_classes, coco_to_voc_map)
if __name__ == '__main__':
gt_util = GTUtility('data/COCO', validation=True)
gt_util.print_stats()