def test_remap_labels(self): src_dataset = Dataset.from_iterable( [ DatasetItem( id=1, annotations=[ # Should be remapped Label(1), Bbox(1, 2, 3, 4, label=2), Mask(image=np.array([1]), label=3), # Should be kept Polygon([1, 1, 2, 2, 3, 4], label=4), PolyLine([1, 3, 4, 2, 5, 6]) ]) ], categories={ AnnotationType.label: LabelCategories.from_iterable('label%s' % i for i in range(5)), AnnotationType.mask: MaskCategories(colormap=mask_tools.generate_colormap(5)), }) dst_dataset = Dataset.from_iterable( [ DatasetItem(id=1, annotations=[ Label(1), Bbox(1, 2, 3, 4, label=0), Mask(image=np.array([1]), label=1), Polygon([1, 1, 2, 2, 3, 4], label=2), PolyLine([1, 3, 4, 2, 5, 6], label=None) ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable(['label0', 'label9', 'label4']), AnnotationType.mask: MaskCategories( colormap={ k: v for k, v in mask_tools.generate_colormap(5).items() if k in {0, 1, 3, 4} }) }) actual = transforms.RemapLabels(src_dataset, mapping={ 'label1': 'label9', 'label2': 'label0', 'label3': 'label9', }, default='keep') compare_datasets(self, dst_dataset, actual)
def test_can_save_dataset_with_cyrillic_and_spaces_in_filename(self): source_dataset = Dataset.from_iterable( [ DatasetItem(id='кириллица с пробелом', subset='train', image=np.ones((16, 16, 3)), annotations=[ Polygon( [0, 4, 4, 4, 5, 6], label=3, attributes={ 'occluded': True, 'a1': 'qwe', 'a2': True, 'a3': 123, }), ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable('label_' + str(label) for label in range(10)), }) target_dataset = Dataset.from_iterable( [ DatasetItem(id='кириллица с пробелом', subset='train', image=np.ones((16, 16, 3)), annotations=[ Polygon( [0, 4, 4, 4, 5, 6], label=0, id=0, attributes={ 'occluded': True, 'username': '', 'a1': 'qwe', 'a2': True, 'a3': 123, }), ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable(['label_3']), }) with TestDir() as test_dir: self._test_save_and_load(source_dataset, partial(LabelMeConverter.convert, save_images=True), test_dir, target_dataset=target_dataset, require_images=True)
def from_iterable(cls, iterable, categories=None): """Generation of Dataset from iterable object Args: iterable: Iterable object contains DatasetItems categories (dict, optional): You can pass dict of categories or you can pass list of names. It'll interpreted as list of names of LabelCategories. Defaults to {}. Returns: Dataset: Dataset object """ if isinstance(categories, list): categories = { AnnotationType.label: LabelCategories.from_iterable(categories) } if not categories: categories = {} class tmpExtractor(Extractor): def __iter__(self): return iter(iterable) def categories(self): return categories return cls.from_extractors(tmpExtractor())
def test_can_import(self): expected_dataset = Dataset.from_iterable( [ DatasetItem(id=1, image=np.ones((16, 16, 3)), annotations=[ Bbox(0, 4, 4, 8, label=2, attributes={ 'occluded': False, 'visibility': 1.0, 'ignored': False, }), ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable('label_' + str(label) for label in range(10)), }) dataset = Dataset.import_from(DUMMY_DATASET_DIR, 'mot_seq') compare_datasets(self, expected_dataset, dataset)
def test_can_save_dataset_with_no_subsets(self): source_dataset = Dataset.from_iterable( [ DatasetItem(id='a/b/1', image=np.ones((8, 8, 3)), annotations=[ Bbox(0, 2, 4, 2, label=2), Bbox(0, 1, 2, 3, label=1, attributes={ 'blur': '2', 'expression': '0', 'illumination': '0', 'occluded': '0', 'pose': '2', 'invalid': '0' }), ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable('label_' + str(i) for i in range(3)), }) with TestDir() as test_dir: WiderFaceConverter.convert(source_dataset, test_dir, save_images=True) parsed_dataset = Dataset.import_from(test_dir, 'wider_face') compare_datasets(self, source_dataset, parsed_dataset)
def test_can_save_and_load(self): source_dataset = Dataset.from_iterable([ DatasetItem(id=1, subset='train', image=np.ones((8, 8, 3)), annotations=[ Bbox(0, 2, 4, 2, label=2), Bbox(0, 1, 2, 3, label=4), ]), DatasetItem(id=2, subset='train', image=np.ones((10, 10, 3)), annotations=[ Bbox(0, 2, 4, 2, label=2), Bbox(3, 3, 2, 3, label=4), Bbox(2, 1, 2, 3, label=4), ]), DatasetItem(id=3, subset='valid', image=np.ones((8, 8, 3)), annotations=[ Bbox(0, 1, 5, 2, label=2), Bbox(0, 2, 3, 2, label=5), Bbox(0, 2, 4, 2, label=6), Bbox(0, 7, 3, 2, label=7), ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable( 'label_' + str(i) for i in range(10)), }) with TestDir() as test_dir: YoloConverter.convert(source_dataset, test_dir, save_images=True) parsed_dataset = YoloImporter()(test_dir).make_dataset() compare_datasets(self, source_dataset, parsed_dataset)
def test_can_save_and_load_with_multiple_labels(self): source_dataset = Dataset.from_iterable( [ DatasetItem(id='1', subset='train', annotations=[Label(1), Label(3)]), DatasetItem(id='2', subset='train', image=np.zeros((8, 6, 3)), annotations=[Label(0)]), DatasetItem( id='3', subset='train', image=np.zeros((2, 8, 3)), ), ], categories={ AnnotationType.label: LabelCategories.from_iterable('label_' + str(label) for label in range(10)), }) with TestDir() as test_dir: ImagenetTxtConverter.convert(source_dataset, test_dir, save_images=True) parsed_dataset = ImagenetTxtImporter()(test_dir).make_dataset() compare_datasets(self, source_dataset, parsed_dataset, require_images=True)
def test_can_save_dataset_with_image_info(self): source_dataset = Dataset.from_iterable( [ DatasetItem(id=1, subset='train', image=Image(path='1.jpg', size=(10, 15)), annotations=[ Bbox(0, 2, 4, 2, label=2), Bbox(3, 3, 2, 3, label=4), ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable('label_' + str(i) for i in range(10)), }) with TestDir() as test_dir: YoloConverter.convert(source_dataset, test_dir) save_image(osp.join(test_dir, 'obj_train_data', '1.jpg'), np.ones((10, 15, 3))) # put the image for dataset parsed_dataset = Dataset.import_from(test_dir, 'yolo') compare_datasets(self, source_dataset, parsed_dataset)
def _parse_categories(self, path): if osp.isfile(path): with open(path) as f: labels = [l.strip() for l in f] else: labels = [l.name for l in MotsLabels] return {AnnotationType.label: LabelCategories.from_iterable(labels)}
def test_can_import(self): target_dataset = Dataset.from_iterable( [ DatasetItem(id=1, subset='train', image=np.ones((16, 16, 3)), annotations=[ Bbox(0, 4, 4, 8, label=2), Bbox(0, 4, 4, 4, label=3), Bbox(2, 4, 4, 4), ], attributes={'source_id': '1'}), DatasetItem(id=2, subset='val', image=np.ones((8, 8, 3)), annotations=[ Bbox(1, 2, 4, 2, label=3), ], attributes={'source_id': '2'}), DatasetItem(id=3, subset='test', image=np.ones((5, 4, 3)) * 3, attributes={'source_id': '3'}), ], categories={ AnnotationType.label: LabelCategories.from_iterable('label_' + str(label) for label in range(10)), }) dataset = Project.import_from(DUMMY_DATASET_DIR, 'tf_detection_api') \ .make_dataset() compare_datasets(self, target_dataset, dataset)
def test_can_save_and_load(self): source_dataset = Dataset.from_iterable([ DatasetItem(id='1', subset='train', annotations=[Label(0)] ), DatasetItem(id='2', subset='train', annotations=[Label(0)] ), DatasetItem(id='3', subset='train', image=np.zeros((8, 8, 3)), annotations=[Label(0)] ), DatasetItem(id='4', subset='train', annotations=[Label(1)] ), DatasetItem(id='5', subset='train', image=np.zeros((4, 8, 3)), annotations=[Label(1)] ), DatasetItem(id='6', subset='train', annotations=[Label(5)] ), ], categories={ AnnotationType.label: LabelCategories.from_iterable( 'label_' + str(label) for label in range(10)), }) with TestDir() as test_dir: ImagenetTxtConverter.convert(source_dataset, test_dir, save_images=True) parsed_dataset = Dataset.import_from(test_dir, 'imagenet_txt') compare_datasets(self, source_dataset, parsed_dataset, require_images=True)
def test_can_save_masks(self): test_dataset = Dataset.from_iterable( [ DatasetItem(id=1, subset='train', image=np.ones((4, 5, 3)), annotations=[ Mask(image=np.array([ [1, 0, 0, 1], [0, 1, 1, 0], [0, 1, 1, 0], [1, 0, 0, 1], ]), label=1), ], attributes={'source_id': ''}), ], categories={ AnnotationType.label: LabelCategories.from_iterable('label_' + str(label) for label in range(10)), }) with TestDir() as test_dir: self._test_save_and_load( test_dataset, partial(TfDetectionApiConverter.convert, save_masks=True), test_dir)
def test_can_save_and_load(self): source_dataset = Dataset.from_iterable([ DatasetItem(id='1', image=np.ones((8, 8, 3)), annotations=[Label(0)] ), DatasetItem(id='2', image=np.ones((10, 10, 3)), annotations=[Label(1)] ), DatasetItem(id='3', image=np.ones((10, 10, 3)), annotations=[Label(0)] ), DatasetItem(id='4', image=np.ones((8, 8, 3)), annotations=[Label(2)] ), ], categories={ AnnotationType.label: LabelCategories.from_iterable( 'label_' + str(label) for label in range(3)), }) with TestDir() as test_dir: ImagenetConverter.convert(source_dataset, test_dir, save_images=True) parsed_dataset = ImagenetImporter()(test_dir).make_dataset() compare_datasets(self, source_dataset, parsed_dataset, require_images=True)
def test_can_save_dataset_with_no_subsets(self): test_dataset = Dataset.from_iterable( [ DatasetItem(id=1, image=np.ones((16, 16, 3)), annotations=[ Bbox(2, 1, 4, 4, label=2), Bbox(4, 2, 8, 4, label=3), ], attributes={'source_id': ''}), DatasetItem(id=2, image=np.ones((8, 8, 3)) * 2, annotations=[ Bbox(4, 4, 4, 4, label=3), ], attributes={'source_id': ''}), DatasetItem(id=3, image=np.ones((8, 4, 3)) * 3, attributes={'source_id': ''}), ], categories={ AnnotationType.label: LabelCategories.from_iterable('label_' + str(label) for label in range(10)), }) with TestDir() as test_dir: self._test_save_and_load( test_dataset, partial(TfDetectionApiConverter.convert, save_images=True), test_dir)
def test_can_load_image(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id='img0', subset='train', image=np.ones((8, 8, 3)), annotations=[ Bbox(0, 2, 4, 2, label=0, z_order=1, attributes={ 'occluded': True, 'a1': True, 'a2': 'v3' }), PolyLine([1, 2, 3, 4, 5, 6, 7, 8], attributes={'occluded': False}), ], attributes={'frame': 0}), DatasetItem(id='img1', subset='train', image=np.ones((10, 10, 3)), annotations=[ Polygon([1, 2, 3, 4, 6, 5], z_order=1, attributes={'occluded': False}), Points([1, 2, 3, 4, 5, 6], label=1, z_order=2, attributes={'occluded': False}), ], attributes={'frame': 1}), ], categories={ AnnotationType.label: LabelCategories.from_iterable([ ['label1', '', {'a1', 'a2'}], ['label2'], ]) }) parsed_dataset = CvatImporter()(DUMMY_IMAGE_DATASET_DIR).make_dataset() compare_datasets(self, expected_dataset, parsed_dataset)
def test_can_import(self): expected_dataset = Dataset.from_iterable( [ DatasetItem(id='0001_01', subset='train', image=np.ones((10, 15, 3)), annotations=[ Bbox(2, 2, 1, 2, label=0), Points([ 2.787, 2.898, 2.965, 2.79, 2.8, 2.456, 2.81, 2.32, 2.89, 2.3 ], label=0), ]), DatasetItem(id='0002_01', subset='train', image=np.ones((10, 15, 3)), annotations=[ Bbox(1, 3, 1, 1, label=1), Points([ 1.2, 3.8, 1.8, 3.82, 1.51, 3.634, 1.43, 3.34, 1.65, 3.32 ], label=1) ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable([('n000001', 'car'), ('n000002', 'person')]), }) dataset = Dataset.import_from(DUMMY_DATASET_DIR, 'vgg_face2') compare_datasets(self, expected_dataset, dataset)
def test_can_load_dataset_with_exact_image_info(self): source_dataset = Dataset.from_iterable( [ DatasetItem(id=1, subset='train', image=Image(path='1.jpg', size=(10, 15)), annotations=[ Bbox(0, 2, 4, 2, label=2), Bbox(3, 3, 2, 3, label=4), ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable('label_' + str(i) for i in range(10)), }) with TestDir() as test_dir: YoloConverter.convert(source_dataset, test_dir) parsed_dataset = Dataset.import_from(test_dir, 'yolo', image_info={'1': (10, 15)}) compare_datasets(self, source_dataset, parsed_dataset)
def test_can_save_dataset_with_cyrillic_and_spaces_in_filename(self): source_dataset = Dataset.from_iterable( [ DatasetItem(id='кириллица с пробелом', subset='train', image=np.ones((8, 8, 3)), annotations=[ Bbox(0, 2, 4, 2, label=2), Bbox(0, 1, 2, 3, label=4), ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable('label_' + str(i) for i in range(10)), }) with TestDir() as test_dir: YoloConverter.convert(source_dataset, test_dir, save_images=True) parsed_dataset = Dataset.import_from(test_dir, 'yolo') compare_datasets(self, source_dataset, parsed_dataset, require_images=True)
def test_can_import(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id=1, subset='train', image=np.ones((10, 15, 3)), annotations=[ Bbox(0, 2, 4, 2, label=2), Bbox(3, 3, 2, 3, label=4), ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable( 'label_' + str(i) for i in range(10)), }) dataset = Dataset.import_from(DUMMY_DATASET_DIR, 'yolo') compare_datasets(self, expected_dataset, dataset)
def test_remap_labels_delete_unspecified(self): source_dataset = Dataset.from_iterable([ DatasetItem(id=1, annotations=[ Label(0) ]) ], categories={ AnnotationType.label: LabelCategories.from_iterable('label0'), }) target_dataset = Dataset.from_iterable([ DatasetItem(id=1, annotations=[]), ], categories={ AnnotationType.label: LabelCategories(), }) actual = transforms.RemapLabels(source_dataset, mapping={}, default='delete') compare_datasets(self, target_dataset, actual)
def test_can_save_dataset_with_no_subsets(self): source_dataset = Dataset.from_iterable([ DatasetItem(id='a/b/c', image=np.zeros((8, 4, 3)), annotations=[Label(1)] ), ], categories={ AnnotationType.label: LabelCategories.from_iterable( 'label_' + str(label) for label in range(10)), }) with TestDir() as test_dir: ImagenetTxtConverter.convert(source_dataset, test_dir, save_images=True) parsed_dataset = ImagenetTxtImporter()(test_dir).make_dataset() compare_datasets(self, source_dataset, parsed_dataset, require_images=True)
def test_can_import(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id='1', image=np.ones((8, 8, 3)), annotations=[Label(0), Label(1)] ), DatasetItem(id='2', image=np.ones((10, 10, 3)), annotations=[Label(0)] ), ], categories={ AnnotationType.label: LabelCategories.from_iterable( 'label_' + str(label) for label in range(2)), }) dataset = Dataset.import_from(DUMMY_DATASET_DIR, 'imagenet') compare_datasets(self, expected_dataset, dataset, require_images=True)
def test_can_save_dataset_with_cyrillic_and_spaces_in_filename(self): source_dataset = Dataset.from_iterable([ DatasetItem(id="кириллица с пробелом", image=np.ones((8, 8, 3)), annotations=[Label(0), Label(1)] ), ], categories={ AnnotationType.label: LabelCategories.from_iterable( 'label_' + str(label) for label in range(2)), }) with TestDir() as test_dir: ImagenetConverter.convert(source_dataset, test_dir, save_images=True) parsed_dataset = Dataset.import_from(test_dir, 'imagenet') compare_datasets(self, source_dataset, parsed_dataset, require_images=True)
def from_iterable(cls, iterable: Iterable[DatasetItem], categories: Union[Dict, List[str]] = None): if isinstance(categories, list): categories = { AnnotationType.label: LabelCategories.from_iterable(categories) } if not categories: categories = {} class _extractor(Extractor): def __iter__(self): return iter(iterable) def categories(self): return categories return cls.from_extractors(_extractor())
def test_can_import_points(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id=1, subset='train', image=Image(path='1.jpg', size=(5, 5)), annotations=[ Points([0, 0, 0, 2, 4, 1], [0, 1, 2], label=1, group=1, id=1, attributes={'is_crowd': False}), Polygon([0, 0, 4, 0, 4, 4], label=1, group=1, id=1, attributes={'is_crowd': False}), Points([1, 2, 3, 4, 2, 3], group=2, id=2, attributes={'is_crowd': False}), Bbox(1, 2, 2, 2, group=2, id=2, attributes={'is_crowd': False}), Points([1, 2, 0, 2, 4, 1], label=0, group=3, id=3, attributes={'is_crowd': False}), Bbox(0, 1, 4, 1, label=0, group=3, id=3, attributes={'is_crowd': False}), Points([0, 0, 1, 2, 3, 4], [0, 1, 2], group=5, id=5, attributes={'is_crowd': False}), Bbox(1, 2, 2, 2, group=5, id=5, attributes={'is_crowd': False}), ], attributes={'id': 1}), ], categories={ AnnotationType.label: LabelCategories.from_iterable(['a', 'b']), AnnotationType.points: PointsCategories.from_iterable( (i, None, [[0, 1], [1, 2]]) for i in range(2) ), }) dataset = Dataset.import_from( osp.join(DUMMY_DATASET_DIR, 'coco_person_keypoints'), 'coco') compare_datasets(self, expected_dataset, dataset)
def test_can_save_and_load(self): source_dataset = Dataset.from_iterable([ DatasetItem(id='1', subset='train', image=np.ones((8, 8, 3)), annotations=[ Bbox(0, 2, 4, 2, label=0, group=1), Points([3.2, 3.12, 4.11, 3.2, 2.11, 2.5, 3.5, 2.11, 3.8, 2.13], label=0, group=1), ] ), DatasetItem(id='2', subset='train', image=np.ones((10, 10, 3)), annotations=[ Points([4.23, 4.32, 5.34, 4.45, 3.54, 3.56, 4.52, 3.51, 4.78, 3.34], label=1, group=1), ] ), DatasetItem(id='3', subset='train', image=np.ones((8, 8, 3)), annotations=[Label(2, group=1)] ), DatasetItem(id='4', subset='train', image=np.ones((10, 10, 3)), annotations=[ Bbox(0, 2, 4, 2, label=3, group=1), Points([3.2, 3.12, 4.11, 3.2, 2.11, 2.5, 3.5, 2.11, 3.8, 2.13], label=3, group=1), ] ), DatasetItem(id='a/5', subset='train', image=np.ones((8, 8, 3)), annotations=[ Bbox(2, 2, 2, 2, group=1), ] ), DatasetItem(id='label_0', subset='train', image=np.ones((8, 8, 3)), ), ], categories={ AnnotationType.label: LabelCategories.from_iterable( [('label_%s' % i, 'class_%s' % i) for i in range(5)]), }) with TestDir() as test_dir: VggFace2Converter.convert(source_dataset, test_dir, save_images=True) parsed_dataset = Dataset.import_from(test_dir, 'vgg_face2') compare_datasets(self, source_dataset, parsed_dataset)
def test_can_save_and_load_with_multiple_labels(self): source_dataset = Dataset.from_iterable( [ DatasetItem(id='1', image=np.ones((8, 8, 3)), annotations=[Label(0), Label(1)]), DatasetItem(id='2', image=np.ones((10, 10, 3)), annotations=[Label(0), Label(1)]), DatasetItem(id='3', image=np.ones((10, 10, 3)), annotations=[Label(0), Label(2)]), DatasetItem(id='4', image=np.ones((8, 8, 3)), annotations=[Label(2), Label(4)]), DatasetItem(id='5', image=np.ones((10, 10, 3)), annotations=[Label(3), Label(4)]), DatasetItem( id='6', image=np.ones((10, 10, 3)), ), DatasetItem(id='7', image=np.ones((8, 8, 3))), ], categories={ AnnotationType.label: LabelCategories.from_iterable('label_' + str(label) for label in range(5)), }) with TestDir() as test_dir: ImagenetConverter.convert(source_dataset, test_dir, save_images=True) parsed_dataset = Dataset.import_from(test_dir, 'imagenet') compare_datasets(self, source_dataset, parsed_dataset, require_images=True)
def test_can_import(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id='1', subset='train', image=np.zeros((8, 6, 3)), annotations=[Label(0)] ), DatasetItem(id='2', subset='train', image=np.zeros((2, 8, 3)), annotations=[Label(5)] ), DatasetItem(id='3', subset='train', annotations=[Label(3)] ), DatasetItem(id='4', subset='train', annotations=[Label(5)] ), ], categories={ AnnotationType.label: LabelCategories.from_iterable( 'label_%s' % label for label in range(10)), }) dataset = Dataset.import_from(DUMMY_DATASET_DIR, 'imagenet_txt') compare_datasets(self, expected_dataset, dataset, require_images=True)
def from_iterable(cls, iterable: Iterable[DatasetItem], categories: Union[CategoriesInfo, List[str]] = None, env: Environment = None): if isinstance(categories, list): categories = { AnnotationType.label: LabelCategories.from_iterable(categories) } if not categories: categories = {} class _extractor(Extractor): def __init__(self): super().__init__(length=len(iterable) \ if hasattr(iterable, '__len__') else None) def __iter__(self): return iter(iterable) def categories(self): return categories return cls.from_extractors(_extractor(), env=env)
def test_can_save_and_load_keypoints(self): source_dataset = Dataset.from_iterable( [ DatasetItem( id=1, subset='train', image=np.zeros((5, 5, 3)), annotations=[ # Full instance annotations: polygon + keypoints Points([0, 0, 0, 2, 4, 1], [0, 1, 2], label=3, group=1, id=1), Polygon([0, 0, 4, 0, 4, 4], label=3, group=1, id=1), # Full instance annotations: bbox + keypoints Points([1, 2, 3, 4, 2, 3], group=2, id=2), Bbox(1, 2, 2, 2, group=2, id=2), # Solitary keypoints Points([1, 2, 0, 2, 4, 1], label=5, id=3), # Some other solitary annotations (bug #1387) Polygon([0, 0, 4, 0, 4, 4], label=3, id=4), # Solitary keypoints with no label Points([0, 0, 1, 2, 3, 4], [0, 1, 2], id=5), ]), ], categories={ AnnotationType.label: LabelCategories.from_iterable(str(i) for i in range(10)), AnnotationType.points: PointsCategories.from_iterable( (i, None, [[0, 1], [1, 2]]) for i in range(10)), }) target_dataset = Dataset.from_iterable( [ DatasetItem(id=1, subset='train', image=np.zeros((5, 5, 3)), annotations=[ Points([0, 0, 0, 2, 4, 1], [0, 1, 2], label=3, group=1, id=1, attributes={'is_crowd': False}), Polygon([0, 0, 4, 0, 4, 4], label=3, group=1, id=1, attributes={'is_crowd': False}), Points([1, 2, 3, 4, 2, 3], group=2, id=2, attributes={'is_crowd': False}), Bbox(1, 2, 2, 2, group=2, id=2, attributes={'is_crowd': False}), Points([1, 2, 0, 2, 4, 1], label=5, group=3, id=3, attributes={'is_crowd': False}), Bbox(0, 1, 4, 1, label=5, group=3, id=3, attributes={'is_crowd': False}), Points([0, 0, 1, 2, 3, 4], [0, 1, 2], group=5, id=5, attributes={'is_crowd': False}), Bbox(1, 2, 2, 2, group=5, id=5, attributes={'is_crowd': False}), ], attributes={'id': 1}), ], categories={ AnnotationType.label: LabelCategories.from_iterable(str(i) for i in range(10)), AnnotationType.points: PointsCategories.from_iterable( (i, None, [[0, 1], [1, 2]]) for i in range(10)), }) with TestDir() as test_dir: self._test_save_and_load(source_dataset, CocoPersonKeypointsConverter.convert, test_dir, target_dataset=target_dataset)