|
|
|
|
@ -160,28 +160,33 @@ class CocoConverterTest(TestCase):
|
|
|
|
|
self.assertFalse(item_b is None)
|
|
|
|
|
self.assertEqual(len(item_a.annotations), len(item_b.annotations))
|
|
|
|
|
for ann_a in item_a.annotations:
|
|
|
|
|
ann_b = find(item_b.annotations, lambda x: \
|
|
|
|
|
x.id == ann_a.id and \
|
|
|
|
|
x.type == ann_a.type and x.group == ann_a.group)
|
|
|
|
|
self.assertEqual(ann_a, ann_b, 'id: ' + str(ann_a.id))
|
|
|
|
|
# We might find few corresponding items, so check them all
|
|
|
|
|
ann_b_matches = [x for x in item_b.annotations
|
|
|
|
|
if x.id == ann_a.id and \
|
|
|
|
|
x.type == ann_a.type and x.group == ann_a.group]
|
|
|
|
|
self.assertFalse(len(ann_b_matches) == 0, 'aid: %s' % ann_a.id)
|
|
|
|
|
|
|
|
|
|
ann_b = find(ann_b_matches, lambda x: x == ann_a)
|
|
|
|
|
self.assertEqual(ann_a, ann_b, 'aid: %s' % ann_a.id)
|
|
|
|
|
item_b.annotations.remove(ann_b) # avoid repeats
|
|
|
|
|
|
|
|
|
|
def test_can_save_and_load_captions(self):
|
|
|
|
|
class TestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
return iter([
|
|
|
|
|
DatasetItem(id=0, subset='train',
|
|
|
|
|
DatasetItem(id=1, subset='train',
|
|
|
|
|
annotations=[
|
|
|
|
|
CaptionObject('hello', id=1),
|
|
|
|
|
CaptionObject('world', id=2),
|
|
|
|
|
CaptionObject('hello', id=1, group=1),
|
|
|
|
|
CaptionObject('world', id=2, group=2),
|
|
|
|
|
]),
|
|
|
|
|
DatasetItem(id=1, subset='train',
|
|
|
|
|
DatasetItem(id=2, subset='train',
|
|
|
|
|
annotations=[
|
|
|
|
|
CaptionObject('test', id=3),
|
|
|
|
|
CaptionObject('test', id=3, group=3),
|
|
|
|
|
]),
|
|
|
|
|
|
|
|
|
|
DatasetItem(id=2, subset='val',
|
|
|
|
|
DatasetItem(id=3, subset='val',
|
|
|
|
|
annotations=[
|
|
|
|
|
CaptionObject('word', id=1),
|
|
|
|
|
CaptionObject('word', id=1, group=1),
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
])
|
|
|
|
|
@ -191,95 +196,185 @@ class CocoConverterTest(TestCase):
|
|
|
|
|
CocoCaptionsConverter(), test_dir)
|
|
|
|
|
|
|
|
|
|
def test_can_save_and_load_instances(self):
|
|
|
|
|
label_categories = LabelCategories()
|
|
|
|
|
for i in range(10):
|
|
|
|
|
label_categories.add(str(i))
|
|
|
|
|
categories = { AnnotationType.label: label_categories }
|
|
|
|
|
|
|
|
|
|
class TestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
return iter([
|
|
|
|
|
DatasetItem(id=0, subset='train', image=np.ones((4, 4, 3)),
|
|
|
|
|
DatasetItem(id=1, subset='train', image=np.ones((4, 4, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
# Bbox + single polygon
|
|
|
|
|
BboxObject(0, 1, 2, 3, label=2, group=1, id=1,
|
|
|
|
|
BboxObject(0, 1, 2, 2,
|
|
|
|
|
label=2, group=1, id=1,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
PolygonObject([0, 1, 2, 1, 2, 3, 0, 3],
|
|
|
|
|
attributes={ 'is_crowd': False },
|
|
|
|
|
label=2, group=1, id=1),
|
|
|
|
|
]),
|
|
|
|
|
DatasetItem(id=1, subset='train',
|
|
|
|
|
DatasetItem(id=2, subset='train', image=np.ones((4, 4, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
# Mask + bbox
|
|
|
|
|
MaskObject(np.array([[0, 0, 0, 0], [1, 0, 1, 0],
|
|
|
|
|
[1, 1, 0, 0], [0, 0, 1, 0]],
|
|
|
|
|
dtype=np.bool),
|
|
|
|
|
MaskObject(np.array([
|
|
|
|
|
[0, 1, 0, 0],
|
|
|
|
|
[0, 1, 0, 0],
|
|
|
|
|
[0, 1, 1, 1],
|
|
|
|
|
[0, 0, 0, 0]],
|
|
|
|
|
),
|
|
|
|
|
attributes={ 'is_crowd': True },
|
|
|
|
|
label=4, group=3, id=3),
|
|
|
|
|
BboxObject(0, 1, 3, 3, label=4, group=3, id=3,
|
|
|
|
|
BboxObject(1, 0, 2, 2, label=4, group=3, id=3,
|
|
|
|
|
attributes={ 'is_crowd': True }),
|
|
|
|
|
]),
|
|
|
|
|
|
|
|
|
|
DatasetItem(id=3, subset='val',
|
|
|
|
|
DatasetItem(id=3, subset='val', image=np.ones((4, 4, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
# Bbox + mask
|
|
|
|
|
BboxObject(0, 1, 3, 2, label=4, group=3, id=3,
|
|
|
|
|
BboxObject(0, 1, 2, 2, label=4, group=3, id=3,
|
|
|
|
|
attributes={ 'is_crowd': True }),
|
|
|
|
|
MaskObject(np.array([[0, 0, 0, 0], [1, 0, 1, 0],
|
|
|
|
|
[1, 1, 0, 0], [0, 0, 0, 0]],
|
|
|
|
|
dtype=np.bool),
|
|
|
|
|
MaskObject(np.array([
|
|
|
|
|
[0, 0, 0, 0],
|
|
|
|
|
[1, 1, 1, 0],
|
|
|
|
|
[1, 1, 0, 0],
|
|
|
|
|
[0, 0, 0, 0]],
|
|
|
|
|
),
|
|
|
|
|
attributes={ 'is_crowd': True },
|
|
|
|
|
label=4, group=3, id=3),
|
|
|
|
|
]),
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
def categories(self):
|
|
|
|
|
label_categories = LabelCategories()
|
|
|
|
|
for i in range(10):
|
|
|
|
|
label_categories.add(str(i))
|
|
|
|
|
return {
|
|
|
|
|
AnnotationType.label: label_categories,
|
|
|
|
|
}
|
|
|
|
|
return categories
|
|
|
|
|
|
|
|
|
|
with TestDir() as test_dir:
|
|
|
|
|
self._test_save_and_load(TestExtractor(),
|
|
|
|
|
CocoInstancesConverter(), test_dir)
|
|
|
|
|
|
|
|
|
|
def test_can_save_and_load_instances_with_mask_conversion(self):
|
|
|
|
|
def test_can_merge_polygons_on_loading(self):
|
|
|
|
|
label_categories = LabelCategories()
|
|
|
|
|
for i in range(10):
|
|
|
|
|
label_categories.add(str(i))
|
|
|
|
|
categories = { AnnotationType.label: label_categories }
|
|
|
|
|
|
|
|
|
|
class TestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
return iter([
|
|
|
|
|
DatasetItem(id=0, image=np.zeros((5, 5, 3)), subset='train',
|
|
|
|
|
DatasetItem(id=1, image=np.zeros((6, 10, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
BboxObject(0, 0, 5, 5, label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
PolygonObject([0, 0, 4, 0, 4, 4],
|
|
|
|
|
label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
MaskObject(np.array([
|
|
|
|
|
[0, 1, 1, 1, 0],
|
|
|
|
|
[0, 0, 1, 1, 0],
|
|
|
|
|
[0, 0, 0, 1, 0],
|
|
|
|
|
[0, 0, 0, 0, 0],
|
|
|
|
|
[0, 0, 0, 0, 0]],
|
|
|
|
|
# only internal fragment (without the border),
|
|
|
|
|
# but not everywhere...
|
|
|
|
|
dtype=np.bool),
|
|
|
|
|
attributes={ 'is_crowd': False },
|
|
|
|
|
label=3, id=4, group=4),
|
|
|
|
|
PolygonObject([5, 0, 9, 0, 5, 5],
|
|
|
|
|
label=3, id=4, group=4),
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
def categories(self):
|
|
|
|
|
label_categories = LabelCategories()
|
|
|
|
|
for i in range(10):
|
|
|
|
|
label_categories.add(str(i))
|
|
|
|
|
return {
|
|
|
|
|
AnnotationType.label: label_categories,
|
|
|
|
|
}
|
|
|
|
|
return categories
|
|
|
|
|
|
|
|
|
|
class TargetExtractor(TestExtractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
items = list(super().__iter__())
|
|
|
|
|
items[0]._annotations = [
|
|
|
|
|
BboxObject(0, 0, 9, 5,
|
|
|
|
|
label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
PolygonObject([0, 0, 4, 0, 4, 4],
|
|
|
|
|
label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
PolygonObject([5, 0, 9, 0, 5, 5],
|
|
|
|
|
label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
MaskObject(np.array([
|
|
|
|
|
[0, 1, 1, 1, 0, 1, 1, 1, 1, 0],
|
|
|
|
|
[0, 0, 1, 1, 0, 1, 1, 1, 0, 0],
|
|
|
|
|
[0, 0, 0, 1, 0, 1, 1, 0, 0, 0],
|
|
|
|
|
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
|
|
|
|
|
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
|
|
|
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
|
|
|
|
|
# only internal fragment (without the border),
|
|
|
|
|
# but not everywhere...
|
|
|
|
|
),
|
|
|
|
|
label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
]
|
|
|
|
|
return iter(items)
|
|
|
|
|
|
|
|
|
|
with TestDir() as test_dir:
|
|
|
|
|
self._test_save_and_load(TestExtractor(),
|
|
|
|
|
CocoInstancesConverter(), test_dir,
|
|
|
|
|
{'merge_instance_polygons': True})
|
|
|
|
|
importer_params={'merge_instance_polygons': True},
|
|
|
|
|
target_dataset=TargetExtractor())
|
|
|
|
|
|
|
|
|
|
def test_can_crop_covered_segments(self):
|
|
|
|
|
label_categories = LabelCategories()
|
|
|
|
|
for i in range(10):
|
|
|
|
|
label_categories.add(str(i))
|
|
|
|
|
|
|
|
|
|
class SrcTestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
items = [
|
|
|
|
|
DatasetItem(id=1, image=np.zeros((5, 5, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
MaskObject(np.array([
|
|
|
|
|
[0, 0, 1, 1, 1],
|
|
|
|
|
[0, 0, 1, 1, 1],
|
|
|
|
|
[1, 1, 0, 1, 1],
|
|
|
|
|
[1, 1, 1, 0, 0],
|
|
|
|
|
[1, 1, 1, 0, 0]],
|
|
|
|
|
),
|
|
|
|
|
label=2, id=1, z_order=0),
|
|
|
|
|
PolygonObject([1, 1, 4, 1, 4, 4, 1, 4],
|
|
|
|
|
label=1, id=2, z_order=1),
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
]
|
|
|
|
|
return iter(items)
|
|
|
|
|
|
|
|
|
|
def categories(self):
|
|
|
|
|
return { AnnotationType.label: label_categories }
|
|
|
|
|
|
|
|
|
|
class DstTestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
items = [
|
|
|
|
|
DatasetItem(id=1, image=np.zeros((5, 5, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
BboxObject(0, 0, 4, 4,
|
|
|
|
|
label=2, id=1, group=1,
|
|
|
|
|
attributes={ 'is_crowd': True }),
|
|
|
|
|
MaskObject(np.array([
|
|
|
|
|
[0, 0, 1, 1, 1],
|
|
|
|
|
[0, 0, 0, 0, 1],
|
|
|
|
|
[1, 0, 0, 0, 1],
|
|
|
|
|
[1, 0, 0, 0, 0],
|
|
|
|
|
[1, 1, 1, 0, 0]],
|
|
|
|
|
),
|
|
|
|
|
attributes={ 'is_crowd': True },
|
|
|
|
|
label=2, id=1, group=1),
|
|
|
|
|
|
|
|
|
|
BboxObject(1, 1, 3, 3,
|
|
|
|
|
label=1, id=2, group=2,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
PolygonObject([1, 1, 4, 1, 4, 4, 1, 4],
|
|
|
|
|
label=1, id=2, group=2,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
# NOTE: Why it's 4 in COCOapi?..
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
]
|
|
|
|
|
return iter(items)
|
|
|
|
|
|
|
|
|
|
def test_can_merge_instance_polygons_to_mask_in_coverter(self):
|
|
|
|
|
def categories(self):
|
|
|
|
|
return { AnnotationType.label: label_categories }
|
|
|
|
|
|
|
|
|
|
with TestDir() as test_dir:
|
|
|
|
|
self._test_save_and_load(SrcTestExtractor(),
|
|
|
|
|
CocoInstancesConverter(crop_covered=True), test_dir,
|
|
|
|
|
target_dataset=DstTestExtractor())
|
|
|
|
|
|
|
|
|
|
def test_can_convert_polygons_to_mask(self):
|
|
|
|
|
label_categories = LabelCategories()
|
|
|
|
|
for i in range(10):
|
|
|
|
|
label_categories.add(str(i))
|
|
|
|
|
@ -287,14 +382,12 @@ class CocoConverterTest(TestCase):
|
|
|
|
|
class SrcTestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
return iter([
|
|
|
|
|
DatasetItem(id=0, image=np.zeros((5, 10, 3)),
|
|
|
|
|
DatasetItem(id=1, image=np.zeros((6, 10, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
PolygonObject([0, 0, 4, 0, 4, 4],
|
|
|
|
|
label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
label=3, id=4, group=4),
|
|
|
|
|
PolygonObject([5, 0, 9, 0, 5, 5],
|
|
|
|
|
label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
label=3, id=4, group=4),
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
])
|
|
|
|
|
@ -305,19 +398,20 @@ class CocoConverterTest(TestCase):
|
|
|
|
|
class DstTestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
return iter([
|
|
|
|
|
DatasetItem(id=0, image=np.zeros((5, 10, 3)),
|
|
|
|
|
DatasetItem(id=1, image=np.zeros((6, 10, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
BboxObject(1, 0, 8, 4, label=3, id=4, group=4,
|
|
|
|
|
BboxObject(0, 0, 9, 5, label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': True }),
|
|
|
|
|
MaskObject(np.array([
|
|
|
|
|
[0, 1, 1, 1, 0, 1, 1, 1, 1, 0],
|
|
|
|
|
[0, 0, 1, 1, 0, 1, 1, 1, 0, 0],
|
|
|
|
|
[0, 0, 0, 1, 0, 1, 1, 0, 0, 0],
|
|
|
|
|
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
|
|
|
|
|
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
|
|
|
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
|
|
|
|
|
# only internal fragment (without the border),
|
|
|
|
|
# but not everywhere...
|
|
|
|
|
dtype=np.bool),
|
|
|
|
|
),
|
|
|
|
|
attributes={ 'is_crowd': True },
|
|
|
|
|
label=3, id=4, group=4),
|
|
|
|
|
]
|
|
|
|
|
@ -329,15 +423,69 @@ class CocoConverterTest(TestCase):
|
|
|
|
|
|
|
|
|
|
with TestDir() as test_dir:
|
|
|
|
|
self._test_save_and_load(SrcTestExtractor(),
|
|
|
|
|
CocoInstancesConverter(merge_polygons=True), test_dir,
|
|
|
|
|
CocoInstancesConverter(segmentation_mode='mask'), test_dir,
|
|
|
|
|
target_dataset=DstTestExtractor())
|
|
|
|
|
|
|
|
|
|
def test_can_convert_masks_to_polygons(self):
|
|
|
|
|
label_categories = LabelCategories()
|
|
|
|
|
for i in range(10):
|
|
|
|
|
label_categories.add(str(i))
|
|
|
|
|
|
|
|
|
|
class SrcTestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
items = [
|
|
|
|
|
DatasetItem(id=1, image=np.zeros((5, 10, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
MaskObject(np.array([
|
|
|
|
|
[0, 1, 1, 1, 0, 1, 1, 1, 1, 0],
|
|
|
|
|
[0, 0, 1, 1, 0, 1, 1, 1, 0, 0],
|
|
|
|
|
[0, 0, 0, 1, 0, 1, 1, 0, 0, 0],
|
|
|
|
|
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
|
|
|
|
|
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
label=3, id=4, group=4),
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
]
|
|
|
|
|
return iter(items)
|
|
|
|
|
|
|
|
|
|
def categories(self):
|
|
|
|
|
return { AnnotationType.label: label_categories }
|
|
|
|
|
|
|
|
|
|
class DstTestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
return iter([
|
|
|
|
|
DatasetItem(id=1, image=np.zeros((5, 10, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
BboxObject(1, 0, 7, 3, label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
PolygonObject(
|
|
|
|
|
[3.0, 2.5, 1.0, 0.0, 3.5, 0.0, 3.0, 2.5],
|
|
|
|
|
label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
PolygonObject(
|
|
|
|
|
[5.0, 3.5, 4.5, 0.0, 8.0, 0.0, 5.0, 3.5],
|
|
|
|
|
label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
def categories(self):
|
|
|
|
|
return { AnnotationType.label: label_categories }
|
|
|
|
|
|
|
|
|
|
with TestDir() as test_dir:
|
|
|
|
|
self._test_save_and_load(SrcTestExtractor(),
|
|
|
|
|
CocoInstancesConverter(segmentation_mode='polygons'), test_dir,
|
|
|
|
|
target_dataset=DstTestExtractor())
|
|
|
|
|
|
|
|
|
|
def test_can_save_and_load_images(self):
|
|
|
|
|
class TestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
return iter([
|
|
|
|
|
DatasetItem(id=0, subset='train'),
|
|
|
|
|
DatasetItem(id=1, subset='train'),
|
|
|
|
|
DatasetItem(id=2, subset='train'),
|
|
|
|
|
|
|
|
|
|
DatasetItem(id=2, subset='val'),
|
|
|
|
|
DatasetItem(id=3, subset='val'),
|
|
|
|
|
@ -354,19 +502,19 @@ class CocoConverterTest(TestCase):
|
|
|
|
|
class TestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
return iter([
|
|
|
|
|
DatasetItem(id=0, subset='train',
|
|
|
|
|
DatasetItem(id=1, subset='train',
|
|
|
|
|
annotations=[
|
|
|
|
|
LabelObject(4, id=1),
|
|
|
|
|
LabelObject(9, id=2),
|
|
|
|
|
LabelObject(4, id=1, group=1),
|
|
|
|
|
LabelObject(9, id=2, group=2),
|
|
|
|
|
]),
|
|
|
|
|
DatasetItem(id=1, subset='train',
|
|
|
|
|
DatasetItem(id=2, subset='train',
|
|
|
|
|
annotations=[
|
|
|
|
|
LabelObject(4, id=4),
|
|
|
|
|
LabelObject(4, id=4, group=4),
|
|
|
|
|
]),
|
|
|
|
|
|
|
|
|
|
DatasetItem(id=2, subset='val',
|
|
|
|
|
DatasetItem(id=3, subset='val',
|
|
|
|
|
annotations=[
|
|
|
|
|
LabelObject(2, id=1),
|
|
|
|
|
LabelObject(2, id=1, group=1),
|
|
|
|
|
]),
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
@ -383,62 +531,114 @@ class CocoConverterTest(TestCase):
|
|
|
|
|
CocoLabelsConverter(), test_dir)
|
|
|
|
|
|
|
|
|
|
def test_can_save_and_load_keypoints(self):
|
|
|
|
|
label_categories = LabelCategories()
|
|
|
|
|
points_categories = PointsCategories()
|
|
|
|
|
for i in range(10):
|
|
|
|
|
label_categories.add(str(i))
|
|
|
|
|
points_categories.add(i, [])
|
|
|
|
|
categories = {
|
|
|
|
|
AnnotationType.label: label_categories,
|
|
|
|
|
AnnotationType.points: points_categories,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class TestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
return iter([
|
|
|
|
|
DatasetItem(id=0, subset='train',
|
|
|
|
|
DatasetItem(id=1, subset='train', image=np.zeros((5, 5, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
PointsObject([1, 2, 0, 2, 4, 1], [0, 1, 2],
|
|
|
|
|
# Full instance annotations: polygon + keypoints
|
|
|
|
|
PointsObject([0, 0, 0, 2, 4, 1], [0, 1, 2],
|
|
|
|
|
label=3, group=1, id=1),
|
|
|
|
|
PolygonObject([0, 0, 4, 0, 4, 4],
|
|
|
|
|
label=3, group=1, id=1),
|
|
|
|
|
BboxObject(1, 2, 3, 4, label=3, group=1),
|
|
|
|
|
PointsObject([5, 6, 0, 7], group=2, id=2),
|
|
|
|
|
BboxObject(1, 2, 3, 4, group=2),
|
|
|
|
|
|
|
|
|
|
# Full instance annotations: bbox + keypoints
|
|
|
|
|
PointsObject([1, 2, 3, 4, 2, 3], group=2, id=2),
|
|
|
|
|
BboxObject(1, 2, 2, 2, group=2, id=2),
|
|
|
|
|
]),
|
|
|
|
|
DatasetItem(id=1, subset='train',
|
|
|
|
|
DatasetItem(id=2, subset='train',
|
|
|
|
|
annotations=[
|
|
|
|
|
PointsObject([1, 2, 0, 2, 4, 1], label=5,
|
|
|
|
|
group=3, id=3),
|
|
|
|
|
BboxObject(1, 2, 3, 4, label=5, group=3),
|
|
|
|
|
# Solitary keypoints
|
|
|
|
|
PointsObject([1, 2, 0, 2, 4, 1], label=5, id=3),
|
|
|
|
|
]),
|
|
|
|
|
|
|
|
|
|
DatasetItem(id=2, subset='val',
|
|
|
|
|
DatasetItem(id=3, subset='val',
|
|
|
|
|
annotations=[
|
|
|
|
|
PointsObject([0, 2, 0, 2, 4, 1], label=2,
|
|
|
|
|
group=3, id=3),
|
|
|
|
|
BboxObject(0, 2, 4, 4, label=2, group=3),
|
|
|
|
|
# Solitary keypoints with no label
|
|
|
|
|
PointsObject([0, 0, 1, 2, 3, 4], [0, 1, 2], id=3),
|
|
|
|
|
]),
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
def categories(self):
|
|
|
|
|
label_categories = LabelCategories()
|
|
|
|
|
points_categories = PointsCategories()
|
|
|
|
|
for i in range(10):
|
|
|
|
|
label_categories.add(str(i))
|
|
|
|
|
points_categories.add(i, [])
|
|
|
|
|
return categories
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
AnnotationType.label: label_categories,
|
|
|
|
|
AnnotationType.points: points_categories,
|
|
|
|
|
}
|
|
|
|
|
class DstTestExtractor(TestExtractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
return iter([
|
|
|
|
|
DatasetItem(id=1, subset='train', image=np.zeros((5, 5, 3)),
|
|
|
|
|
annotations=[
|
|
|
|
|
PointsObject([0, 0, 0, 2, 4, 1], [0, 1, 2],
|
|
|
|
|
label=3, group=1, id=1,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
PolygonObject([0, 0, 4, 0, 4, 4],
|
|
|
|
|
label=3, group=1, id=1,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
BboxObject(0, 0, 4, 4,
|
|
|
|
|
label=3, group=1, id=1,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
|
|
|
|
|
PointsObject([1, 2, 3, 4, 2, 3],
|
|
|
|
|
group=2, id=2,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
PolygonObject([1, 2, 3, 2, 3, 4, 1, 4],
|
|
|
|
|
group=2, id=2,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
BboxObject(1, 2, 2, 2,
|
|
|
|
|
group=2, id=2,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
]),
|
|
|
|
|
DatasetItem(id=2, subset='train',
|
|
|
|
|
annotations=[
|
|
|
|
|
PointsObject([1, 2, 0, 2, 4, 1],
|
|
|
|
|
label=5, group=3, id=3,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
PolygonObject([0, 1, 4, 1, 4, 2, 0, 2],
|
|
|
|
|
label=5, group=3, id=3,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
BboxObject(0, 1, 4, 1,
|
|
|
|
|
label=5, group=3, id=3,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
]),
|
|
|
|
|
|
|
|
|
|
DatasetItem(id=3, subset='val',
|
|
|
|
|
annotations=[
|
|
|
|
|
PointsObject([0, 0, 1, 2, 3, 4], [0, 1, 2],
|
|
|
|
|
group=3, id=3,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
PolygonObject([1, 2, 3, 2, 3, 4, 1, 4],
|
|
|
|
|
group=3, id=3,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
BboxObject(1, 2, 2, 2,
|
|
|
|
|
group=3, id=3,
|
|
|
|
|
attributes={'is_crowd': False}),
|
|
|
|
|
]),
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
with TestDir() as test_dir:
|
|
|
|
|
self._test_save_and_load(TestExtractor(),
|
|
|
|
|
CocoPersonKeypointsConverter(), test_dir)
|
|
|
|
|
CocoPersonKeypointsConverter(), test_dir,
|
|
|
|
|
target_dataset=DstTestExtractor())
|
|
|
|
|
|
|
|
|
|
def test_can_save_dataset_with_no_subsets(self):
|
|
|
|
|
class TestExtractor(Extractor):
|
|
|
|
|
def __iter__(self):
|
|
|
|
|
return iter([
|
|
|
|
|
DatasetItem(id=1, annotations=[
|
|
|
|
|
LabelObject(2, id=1),
|
|
|
|
|
LabelObject(2, id=1, group=1),
|
|
|
|
|
]),
|
|
|
|
|
|
|
|
|
|
DatasetItem(id=2, image=np.zeros((5, 5, 3)), annotations=[
|
|
|
|
|
LabelObject(3, id=3),
|
|
|
|
|
BboxObject(0, 0, 5, 5, label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
PolygonObject([0, 0, 4, 0, 4, 4], label=3, id=4, group=4,
|
|
|
|
|
attributes={ 'is_crowd': False }),
|
|
|
|
|
DatasetItem(id=2, annotations=[
|
|
|
|
|
LabelObject(3, id=2, group=2),
|
|
|
|
|
]),
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|