Skip to content

Commit 7b662c1

Browse files
committed
Supervisely coverage increased
1 parent 78573c6 commit 7b662c1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1744
-626
lines changed

superannotate/input_converters/conversion.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,13 @@
4242
('Vector', 'object_detection'), ('Vector', 'instance_segmentation'),
4343
('Vector', 'vector_annotation')
4444
],
45-
'Supervisely': [('Vector', 'vector_annotation')],
45+
'Supervisely':
46+
[
47+
('Vector', 'vector_annotation'), ('Vector', 'object_detection'),
48+
('Vector', 'instance_segmentation'),
49+
('Pixel', 'instance_segmentation'),
50+
('Vector', 'keypoint_detection')
51+
],
4652
'VoTT':
4753
[
4854
('Vector', 'object_detection'), ('Vector', 'instance_segmentation'),

superannotate/input_converters/converters/converters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def _select_strategy(self, args):
5757
if args.task == 'object_detection' or args.task == 'instance_segmentation' or args.task == 'vector_annotation':
5858
c_strategy = DataLoopObjectDetectionStrategy(args)
5959
elif args.dataset_format == "Supervisely":
60-
if args.task == 'vector_annotation':
60+
if args.task == 'vector_annotation' or args.task == 'instance_segmentation' or args.task == 'object_detection' or args.task == 'keypoint_detection':
6161
c_strategy = SuperviselyObjectDetectionStrategy(args)
6262
elif args.dataset_format == "VoTT":
6363
if args.task == 'object_detection' or args.task == 'instance_segmentation' or args.task == 'vector_annotation':

superannotate/input_converters/converters/supervisely_converters/supervisely_strategies.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
import json
33

44
from .supervisely_converter import SuperviselyConverter
5-
from .supervisely_to_sa_vector import supervisely_to_sa
5+
from .supervisely_to_sa_vector import (
6+
supervisely_to_sa, supervisely_instance_segmentation_to_sa_vector,
7+
supervisely_object_detection_to_sa_vector,
8+
supervisely_keypoint_detection_to_sa_vector
9+
)
10+
from .supervisely_to_sa_pixel import supervisely_instance_segmentation_to_sa_pixel
611

712

813
class SuperviselyObjectDetectionStrategy(SuperviselyConverter):
@@ -18,9 +23,18 @@ def __setup_conversion_algorithm(self):
1823
else:
1924
if self.project_type == "Vector":
2025
if self.task == 'vector_annotation':
21-
self.converion_algorithm = supervisely_to_sa
26+
self.conversion_algorithm = supervisely_to_sa
27+
elif self.task == 'object_detection':
28+
self.conversion_algorithm = supervisely_object_detection_to_sa_vector
29+
elif self.task == 'instance_segmentation':
30+
self.conversion_algorithm = supervisely_instance_segmentation_to_sa_vector
31+
elif self.task == 'keypoint_detection':
32+
self.conversion_algorithm = supervisely_keypoint_detection_to_sa_vector
2233
elif self.project_type == "Pixel":
23-
raise NotImplementedError("Doesn't support yet")
34+
if self.task == 'instance_segmentation':
35+
self.conversion_algorithm = supervisely_instance_segmentation_to_sa_pixel
36+
else:
37+
raise NotImplementedError("Doesn't support yet")
2438

2539
def __str__(self):
2640
return '{} object'.format(self.name)
@@ -46,7 +60,19 @@ def to_sa_format(self):
4660
os.path.join(self.export_root, 'ds', 'ann', file)
4761
for file in files
4862
]
49-
sa_jsons = self.converion_algorithm(json_files, classes_id_map)
63+
if self.conversion_algorithm.__name__ == 'supervisely_keypoint_detection_to_sa_vector':
64+
meta_json = json.load(
65+
open(os.path.join(self.export_root, 'meta.json'))
66+
)
67+
sa_jsons = self.conversion_algorithm(
68+
json_files, classes_id_map, meta_json
69+
)
70+
elif self.conversion_algorithm.__name__ == 'supervisely_instance_segmentation_to_sa_pixel':
71+
sa_jsons = self.conversion_algorithm(
72+
json_files, classes_id_map, self.output_dir
73+
)
74+
else:
75+
sa_jsons = self.conversion_algorithm(json_files, classes_id_map)
5076
self.dump_output(sa_classes, sa_jsons)
5177

5278
def _make_id_generator(self):
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import numpy as np
2+
import os
3+
import json
4+
import zlib
5+
import base64
6+
import cv2
7+
8+
from ....common import hex_to_rgb, blue_color_generator
9+
10+
11+
# Converts bitmaps to polygon
12+
def _base64_to_polygon(bitmap):
13+
z = zlib.decompress(base64.b64decode(bitmap))
14+
n = np.frombuffer(z, np.uint8)
15+
mask = cv2.imdecode(n, cv2.IMREAD_UNCHANGED)[:, :, 3].astype(bool)
16+
contours, hierarchy = cv2.findContours(
17+
mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
18+
)
19+
segmentation = []
20+
21+
for contour in contours:
22+
contour = contour.flatten().tolist()
23+
if len(contour) > 4:
24+
segmentation.append(contour)
25+
if len(segmentation) == 0:
26+
continue
27+
return segmentation
28+
29+
30+
def supervisely_instance_segmentation_to_sa_pixel(
31+
json_files, class_id_map, output_path
32+
):
33+
sa_jsons = {}
34+
for json_file in json_files:
35+
file_name = os.path.splitext(os.path.basename(json_file)
36+
)[0] + '___pixel.json'
37+
38+
json_data = json.load(open(json_file))
39+
sa_loader = []
40+
41+
H, W = json_data['size']['height'], json_data['size']['width']
42+
mask = np.zeros((H, W, 4))
43+
44+
hex_colors = blue_color_generator(10 * len(json_data['objects']))
45+
index = 0
46+
for obj in json_data['objects']:
47+
if 'classTitle' in obj and obj['classTitle'] in class_id_map.keys():
48+
attributes = []
49+
if 'tags' in obj.keys():
50+
for tag in obj['tags']:
51+
group_id = class_id_map[obj['classTitle']
52+
]['attr_group']['id']
53+
group_name = class_id_map[obj['classTitle']
54+
]['attr_group']['group_name']
55+
attr_id = class_id_map[obj['classTitle']]['attr_group'][
56+
'attributes'][tag['name']]
57+
attr_name = tag['name']
58+
attributes.append(
59+
{
60+
'id': attr_id,
61+
'name': attr_name,
62+
'groupId': group_id,
63+
'groupName': group_name
64+
}
65+
)
66+
67+
sa_obj = {
68+
'className': obj['classTitle'],
69+
'classId': class_id_map[obj['classTitle']]['id'],
70+
'attributes': attributes,
71+
'probability': 100,
72+
'locked': False,
73+
'visible': True,
74+
'parts': [],
75+
}
76+
77+
if obj['geometryType'] == 'bitmap':
78+
segments = _base64_to_polygon(obj['bitmap']['data'])
79+
for segment in segments:
80+
ppoints = [
81+
x + obj['bitmap']['origin'][0] if i %
82+
2 == 0 else x + obj['bitmap']['origin'][1]
83+
for i, x in enumerate(segment)
84+
]
85+
bitmask = np.zeros((H, W)).astype(np.uint8)
86+
pts = np.array(
87+
[
88+
ppoints[2 * i:2 * (i + 1)]
89+
for i in range(len(ppoints) // 2)
90+
],
91+
dtype=np.int32
92+
)
93+
cv2.fillPoly(bitmask, [pts], 1)
94+
color = hex_to_rgb(hex_colors[index])
95+
mask[bitmask == 1] = list(color[::-1]) + [255]
96+
sa_obj['parts'].append({'color': hex_colors[index]})
97+
index += 1
98+
cv2.imwrite(
99+
os.path.join(
100+
output_path,
101+
file_name.replace(
102+
'___pixel.json', '___save.png'
103+
)
104+
), mask
105+
)
106+
sa_loader.append(sa_obj)
107+
108+
sa_jsons[file_name] = sa_loader
109+
return sa_jsons

0 commit comments

Comments
 (0)