-
Notifications
You must be signed in to change notification settings - Fork 33
/
voc_loader.py
121 lines (100 loc) · 4.15 KB
/
voc_loader.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
from scipy.io import loadmat
from loader import Loader, DATASETS_ROOT
import cv2
import numpy as np
import xml.etree.ElementTree as ET
VOC_CATS = ['__background__', 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle',
'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse',
'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train',
'tvmonitor']
class VOCLoader(Loader):
def __init__(self, year, proposals, split, num_proposals=2000, excluded=[],
cats=VOC_CATS):
super().__init__()
assert year in ['07', '12']
self.dataset = 'voc'
self.year = year
self.root = DATASETS_ROOT + ('voc/VOCdevkit/VOC20%s/' % year)
self.split = split
assert split in ['train', 'val', 'trainval', 'test']
self.proposals = proposals
self.num_proposals = num_proposals
assert num_proposals >= 0
self.excluded_cats = excluded
self.cats_to_ids = dict(map(reversed, enumerate(cats)))
self.ids_to_cats = dict(enumerate(cats))
self.num_classes = len(cats)
self.categories = cats[1:]
def load_image(self, name, resize=True):
im = cv2.imread('%sJPEGImages/%s.jpg' % (self.root, name))
out = self.convert_and_maybe_resize(im, resize)
return out
def get_filenames(self):
with open(self.root+'ImageSets/Main/%s.txt' % self.split, 'r') as f:
return f.read().split('\n')[:-1]
def read_proposals(self, name):
if self.proposals == 'edgeboxes':
mat = loadmat('%sEdgeBoxesProposals/%s.mat' % (self.root, name))
bboxes = mat['bbs'][:, :4]
if self.proposals == 'selective_search':
bboxes = np.load('%sSelectiveSearchProposals/%s.npy' % (self.root, name))
if self.num_proposals == 0:
return bboxes
else:
return bboxes[:self.num_proposals]
def read_annotations(self, name, exclude=True):
bboxes = []
cats = []
tree = ET.parse('%sAnnotations/%s.xml' % (self.root, name))
root = tree.getroot()
# image_path = images_dir+root.find('filename').text
width = int(root.find('size/width').text)
height = int(root.find('size/height').text)
difficulty = []
for obj in root.findall('object'):
cat = self.cats_to_ids[obj.find('name').text]
difficult = (int(obj.find('difficult').text) != 0)
difficulty.append(difficult)
cats.append(cat)
bbox_tag = obj.find('bndbox')
x = int(bbox_tag.find('xmin').text)
y = int(bbox_tag.find('ymin').text)
w = int(bbox_tag.find('xmax').text)-x
h = int(bbox_tag.find('ymax').text)-y
bboxes.append((x, y, w, h))
gt_cats = np.array(cats)
gt_bboxes = np.array(bboxes)
difficulty = np.array(difficulty)
if exclude:
incl_mask = np.array([cat not in self.excluded_cats for cat in gt_cats])
gt_bboxes = gt_bboxes[np.logical_and(~difficulty, incl_mask)]
gt_cats = gt_cats[np.logical_and(~difficulty, incl_mask)]
difficulty = None
return gt_bboxes, gt_cats, width, height, difficulty
def create_permutation(last_class):
cats = list(VOC_CATS)
i = cats.index(last_class)
j = cats.index('tvmonitor')
cats[i], cats[j] = cats[j], cats[i]
cats[:-1] = sorted(cats[:-1])
return cats
def class_stats(ids, start_id, end_id):
common = set()
for i in range(start_id, end_id+1):
common = common | ids[i]
print("Classes from {} to {} are in {} images".format(start_id, end_id, len(common)))
if __name__ == '__main__':
print("Statistics per class: ")
ids = {i: set() for i in range(1, 21)}
loader = VOCLoader('07', 'edgeboxes', 'trainval')
total = 0
for name in loader.get_filenames():
gt_cats = loader.read_annotations(name)[1]
for cid in gt_cats:
ids[cid].add(name)
for i in ids.keys():
print("%s: %i" % (VOC_CATS[i], len(ids[i])))
total += len(ids[i])
print("TOTAL: %i" % total)
class_stats(ids, 1, 10)
class_stats(ids, 11, 20)