-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsuperviselyboxes.py
104 lines (85 loc) · 3.26 KB
/
superviselyboxes.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
import os
import glob
import json
import torch
from torch.utils import data
from PIL import Image
from torchvision import transforms
class SuperviselyBoxes(data.Dataset):
def __init__(self, root, dataset_name, transform=None):
'''
Root directory of downloaded supervisely datasets include:
- dataset_name
- - ann
- - img
- meta.json
- obj_class_to_machine_color.json
'''
self.root = root
self.name = dataset_name
self.transform = transform
self.filenames = []
all_ann_files = glob.glob(os.path.join(root+dataset_name+'/ann/', '*.json'))
# filter out images without annotations
for json_path in all_ann_files:
with open(json_path) as fs:
json_suprv = json.load(fs)
if len(json_suprv['objects']) > 0:
self.filenames.append(json_path)
def __getitem__(self, index):
ann_path = self.filenames[index]
# loading image by changing the path:
# before: /path/to/dataset/ann/example.png.json
# after: /path/to/dataset/img/example.png
img_path = ann_path[:-5].split('/')
img_path[-2] = 'img'
img_path = '/'.join(img_path)
image = Image.open(img_path)
image = transforms.ToTensor()(image)
# loading supervisely file
with open(ann_path) as fs:
json_suprv = json.load(fs)
# loading boxes
rectangles = [obj for obj in json_suprv['objects'] if obj['geometryType'] == 'rectangle']
rect_labels = {}
i = 1
for rect in rectangles:
lab = rect['classTitle']
if lab not in rect_labels.keys():
rect_labels[lab] = i
i = i+1
# number of objects in the image
num_objs = len(rectangles)
# Bounding boxes for objects:
# In supervisely format, rectangle in points exterior = [left, top],[right, bottom]
# In pytorch, the input should be [xmin, ymin, xmax, ymax]
boxes = []
labels = []
for rect in rectangles:
exterior = rect['points']['exterior']
xmin = exterior[0][0]
ymin = exterior[0][1]
xmax = exterior[1][0]
ymax = exterior[1][1]
boxes.append([xmin, ymin, xmax, ymax])
labels.append(rect_labels[rect['classTitle']])
boxes = torch.as_tensor(boxes, dtype=torch.float32)
labels = torch.as_tensor(labels, dtype=torch.int64)
# Tensorise img_id
img_id = torch.tensor([index])
# Areas
areas = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
# Iscrowd
iscrowd = torch.zeros((num_objs,), dtype=torch.int64)
# Annotation is in dictionary format
my_annotation = {}
my_annotation["boxes"] = boxes
my_annotation["labels"] = labels
my_annotation["image_id"] = img_id
my_annotation["area"] = areas
my_annotation["iscrowd"] = iscrowd
if self.transform is not None:
image = self.transform(image)
return image, my_annotation
def __len__(self):
return len(self.filenames)