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 = Dataset.import_from(DUMMY_IMAGE_DATASET_DIR, 'cvat') compare_datasets(self, expected_dataset, parsed_dataset)
def test_random_split_gives_error_on_wrong_ratios(self): source_dataset = Dataset.from_iterable([DatasetItem(id=1)]) with self.assertRaises(Exception): transforms.RandomSplit(source_dataset, splits=[ ('train', 0.5), ('test', 0.7), ]) with self.assertRaises(Exception): transforms.RandomSplit(source_dataset, splits=[]) with self.assertRaises(Exception): transforms.RandomSplit(source_dataset, splits=[ ('train', -0.5), ('test', 1.5), ])
def test_relative_paths(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id='1', image=np.ones((4, 2, 3)), attributes={'id': 1}), DatasetItem(id='subdir1/1', image=np.ones((2, 6, 3)), attributes={'id': 2}), DatasetItem(id='subdir2/1', image=np.ones((5, 4, 3)), attributes={'id': 3}), ]) with TestDir() as test_dir: self._test_save_and_load( expected_dataset, partial(CocoImageInfoConverter.convert, save_images=True), test_dir)
def test_can_save_dataset_with_cyrillic_and_spaces_in_filename(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id='кириллица с пробелом', image=np.ones((8, 8, 3))), ]) for importer, converter in [ ('icdar_word_recognition', IcdarWordRecognitionConverter), ('icdar_text_localization', IcdarTextLocalizationConverter), ('icdar_text_segmentation', IcdarTextSegmentationConverter), ]: with self.subTest(subformat=converter), TestDir() as test_dir: self._test_save_and_load(expected_dataset, partial(converter.convert, save_images=True), test_dir, importer, require_images=True)
def _generate_detection_segmentation_dataset(self, **kwargs): annotation_type = kwargs.get("annotation_type") with_attr = kwargs.get("with_attr", False) nimages = kwargs.get("nimages", 10) label_cat = LabelCategories() for i in range(6): label = "label%d" % (i + 1) if with_attr is True: attributes = {"attr0", "attr%d" % (i + 1)} else: attributes = {} label_cat.add(label, attributes=attributes) categories = {AnnotationType.label: label_cat} iterable = [] attr_val = 0 totals = np.zeros(3) objects = [(1, 5, 2), (3, 4, 1), (2, 3, 4), (1, 1, 1), (2, 4, 2)] for img_id in range(nimages): cnts = objects[img_id % len(objects)] totals += cnts annotations = [] for label_id, count in enumerate(cnts): attributes = {} if with_attr: attr_val += 1 attributes["attr0"] = attr_val % 3 attributes["attr%d" % (label_id + 1)] = attr_val % 2 for ann_id in range(count): annotation_type( annotations, label_id=label_id, ann_id=ann_id, attributes=attributes, ) item = DatasetItem( img_id, subset=self._get_subset(img_id), annotations=annotations, attributes={"id": img_id}, ) iterable.append(item) dataset = Dataset.from_iterable(iterable, categories) return dataset, totals
def test_can_save_and_load_with_arbitrary_extensions(self): source_dataset = Dataset.from_iterable([ DatasetItem(id='subset/1', image=Image(data=np.ones((10, 10, 3)), path='subset/1.png')), DatasetItem(id='2', image=Image(data=np.ones((4, 5, 3)), path='2.jpg')), ]) with TestDir() as test_dir: save_image(osp.join(test_dir, '2.jpg'), source_dataset.get('2').image.data) save_image(osp.join(test_dir, 'subset', '1.png'), source_dataset.get('subset/1').image.data, create_dir=True) self._test_can_save_and_load(source_dataset, test_dir)
def test_can_save_and_load_image_with_arbitrary_extension(self): dataset = Dataset.from_iterable([ DatasetItem(id='q/1', image=Image(path='q/1.JPEG', data=np.zeros( (4, 3, 3)))), DatasetItem(id='a/b/c/2', image=Image(path='a/b/c/2.bmp', data=np.zeros((3, 4, 3)))), ]) with TestDir() as test_dir: check_save_and_load(self, dataset, ImageDirConverter.convert, test_dir, importer='image_dir', require_images=True)
def _generate_dataset(self, config): # counts = {(0,0):20, (0,1):20, (0,2):30, (1,0):20, (1,1):10, (1,2):20} # attr1 = ['attr1', 'attr2'] # attr2 = ['attr1', 'attr3'] # config = { "label1": { "attrs": attr1, "counts": counts }, # "label2": { "attrs": attr2, "counts": counts }} iterable = [] label_cat = LabelCategories() idx = 0 for label_id, label in enumerate(config.keys()): anames = config[label]["attrs"] counts = config[label]["counts"] label_cat.add(label, attributes=anames) if isinstance(counts, dict): for attrs, count in counts.items(): attributes = dict() if isinstance(attrs, tuple): for aname, value in zip(anames, attrs): attributes[aname] = value else: attributes[anames[0]] = attrs for _ in range(count): idx += 1 iterable.append( DatasetItem( idx, subset=self._get_subset(idx), annotations=[ Label(label_id, attributes=attributes) ], image=np.ones((1, 1, 3)), )) else: for _ in range(counts): idx += 1 iterable.append( DatasetItem( idx, subset=self._get_subset(idx), annotations=[Label(label_id)], image=np.ones((1, 1, 3)), )) categories = {AnnotationType.label: label_cat} dataset = Dataset.from_iterable(iterable, categories) return dataset
def test_random_split(self): source_dataset = Dataset.from_iterable([ DatasetItem(id=1, subset="a"), DatasetItem(id=2, subset="a"), DatasetItem(id=3, subset="b"), DatasetItem(id=4, subset="b"), DatasetItem(id=5, subset="b"), DatasetItem(id=6, subset=""), DatasetItem(id=7, subset=""), ]) actual = transforms.RandomSplit(source_dataset, splits=[ ('train', 4.0 / 7.0), ('test', 3.0 / 7.0), ]) self.assertEqual(4, len(actual.get_subset('train'))) self.assertEqual(3, len(actual.get_subset('test')))
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 = Project.import_from(DUMMY_DATASET_DIR, 'imagenet').make_dataset() compare_datasets(self, expected_dataset, dataset, require_images=True)
def test_can_save_and_load_bboxes_with_no_save_images(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id=3, subset='train', image=np.ones((10, 15, 3)), annotations=[ Polygon([2, 2, 8, 3, 7, 10, 2, 9], attributes={'text': 'word_2'}), Bbox(0, 2, 5, 9, attributes={'text': 'word_3'}), ]), ]) with TestDir() as test_dir: self._test_save_and_load( expected_dataset, partial(IcdarTextLocalizationConverter.convert, save_images=False), test_dir, 'icdar_text_localization')
def test_can_save_and_load_image_with_arbitrary_extension(self): expected = Dataset.from_iterable([ DatasetItem('q/1', image=Image(path='q/1.JPEG', data=np.zeros((4, 3, 3))), attributes={'frame': 1}), DatasetItem('a/b/c/2', image=Image(path='a/b/c/2.bmp', data=np.zeros((3, 4, 3))), attributes={'frame': 2}), ], categories=[]) with TestDir() as test_dir: self._test_save_and_load(expected, partial(CvatConverter.convert, save_images=True), test_dir, require_images=True)
def test_inplace_save_writes_only_updated_data(self): with TestDir() as path: dataset = Dataset.from_iterable([ DatasetItem(id='frame1', annotations=[ Cuboid3d(id=215, position=[320.59, 979.48, 1.03], label=0) ], point_cloud=self.pcd1, related_images=[self.image1], attributes={'frame': 0}) ], categories=['car', 'bus']) dataset.export(path, 'sly_pointcloud', save_images=True) dataset.put( DatasetItem(id='frame2', annotations=[ Cuboid3d(id=216, position=[0.59, 14.41, -0.61], label=1) ], point_cloud=self.pcd2, related_images=[self.image2], attributes={'frame': 1})) dataset.remove('frame1') dataset.save(save_images=True) self.assertEqual({'frame2.pcd.json'}, set(os.listdir(osp.join(path, 'ds0', 'ann')))) self.assertEqual({'frame2.pcd'}, set( os.listdir(osp.join(path, 'ds0', 'pointcloud')))) self.assertTrue( osp.isfile( osp.join(path, 'ds0', 'related_images', 'frame2_pcd', 'img1.png'))) self.assertFalse( osp.isfile( osp.join(path, 'ds0', 'related_images', 'frame1_pcd', 'img2.png')))
def _generate_classification_dataset(self, config, subset=None, empty_scores=False, out_range=False, no_attr=False, no_img=False): probs = self._get_probs(out_range) if subset is None: self.subset = ["train", "val", "test"] else: self.subset = subset iterable = [] label_cat = LabelCategories() idx = 0 for label_id, label in enumerate(config.keys()): num_item = config[label] label_cat.add(label, attributes=None) for _ in range(num_item): scores = probs[idx] idx += 1 if empty_scores: scores = [] attr = {"scores": scores} if no_attr: attr = {} img = Image(path=f"test/dataset/{idx}.jpg", size=(90, 90)) if no_img: img = None iterable.append( DatasetItem( idx, subset=self.subset[idx % len(self.subset)], annotations=[Label( label_id, attributes=attr, )], image=img, )) categories = {AnnotationType.label: label_cat} dataset = Dataset.from_iterable(iterable, categories) return dataset
def test_mean_std(self): expected_mean = [100, 50, 150] expected_std = [20, 50, 10] dataset = Dataset.from_iterable([ DatasetItem(id=1, image=np.random.normal(expected_mean, expected_std, size=(w, h, 3))) for i, (w, h) in enumerate([(3000, 100), (800, 600), (400, 200), (700, 300)]) ]) actual_mean, actual_std = mean_std(dataset) for em, am in zip(expected_mean, actual_mean): self.assertAlmostEqual(em, am, places=0) for estd, astd in zip(expected_std, actual_std): self.assertAlmostEqual(estd, astd, places=0)
def test_can_import(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id='000000000001', image=np.ones((10, 5, 3)), subset='val', attributes={'id': 1}, annotations=[ Polygon([0, 0, 1, 0, 1, 2, 0, 2], label=0, id=1, group=1, attributes={'is_crowd': False}), Mask(np.array( [[1, 0, 0, 1, 0]] * 5 + [[1, 1, 1, 1, 0]] * 5 ), label=0, id=2, group=2, attributes={'is_crowd': True}), ] ), ], categories=['TEST',]) dataset = Project.import_from(DUMMY_DATASET_DIR, 'coco') \ .make_dataset() compare_datasets(self, expected_dataset, dataset)
def test_can_import_captions(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id='word_1', subset='train', image=np.ones((10, 15, 3)), annotations=[ Caption('PROPER'), ] ), DatasetItem(id='word_2', subset='train', image=np.ones((10, 15, 3)), annotations=[ Caption("Canon"), ] ), ]) dataset = Dataset.import_from( osp.join(DUMMY_DATASET_DIR, 'word_recognition'), 'icdar') compare_datasets(self, expected_dataset, dataset)
def test_can_import_masks(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id='1', subset='train', image=np.ones((2, 5, 3)), annotations=[ Mask(group=0, image=np.array([[0, 1, 1, 0, 0], [0, 0, 0, 0, 0]]), attributes={ 'index': 0, 'color': '108 225 132', 'text': 'F', 'center': '0 1' }), Mask(group=1, image=np.array([[0, 0, 0, 1, 0], [0, 0, 0, 1, 0]]), attributes={ 'index': 1, 'color': '82 174 214', 'text': 'T', 'center': '1 3' }), Mask(group=1, image=np.array([[0, 0, 0, 0, 0], [0, 0, 0, 0, 1]]), attributes={ 'index': 2, 'color': '241 73 144', 'text': 'h', 'center': '1 4' }), ]), ]) dataset = Dataset.import_from( osp.join(DUMMY_DATASET_DIR, 'text_segmentation'), 'icdar_text_segmentation') compare_datasets(self, expected_dataset, dataset)
def test_can_save_and_load_captions(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id=1, subset='train', annotations=[ Caption('hello', id=1, group=1), Caption('world', id=2, group=2), ], attributes={'id': 1}), DatasetItem(id=2, subset='train', annotations=[ Caption('test', id=3, group=3), ], attributes={'id': 2}), DatasetItem(id=3, subset='val', annotations=[ Caption('word', id=1, group=1), ], attributes={'id': 1}), ]) with TestDir() as test_dir: self._test_save_and_load(expected_dataset, CocoCaptionsConverter.convert, test_dir)
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 = Project.import_from(DUMMY_DATASET_DIR, 'mot_seq') \ .make_dataset() compare_datasets(self, expected_dataset, dataset)
def test_can_save_and_load_captions(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id='a/b/1', subset='train', image=np.ones((10, 15, 3)), annotations=[ Caption('caption 0'), ]), DatasetItem(id=2, subset='train', image=np.ones((10, 15, 3)), annotations=[ Caption('caption_1'), ]), ]) with TestDir() as test_dir: self._test_save_and_load( expected_dataset, partial(IcdarWordRecognitionConverter.convert, save_images=True), test_dir, 'icdar_word_recognition')
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 = Project.import_from(DUMMY_DATASET_DIR, 'yolo') \ .make_dataset() compare_datasets(self, expected_dataset, 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 = ImagenetImporter()(test_dir).make_dataset() compare_datasets(self, source_dataset, parsed_dataset, require_images=True)
def test_can_change_sequence(self): source = Dataset.from_iterable([ DatasetItem('1', subset='a', annotations=[Label(0), Label(1)]), DatasetItem('2', subset='a', annotations=[Label(1)]), DatasetItem('3', subset='a', annotations=[Label(2)]), DatasetItem('4', subset='a', annotations=[Label(1), Label(2)]), DatasetItem('5', subset='b', annotations=[Label(0)]), DatasetItem('6', subset='b', annotations=[Label(0), Label(2)]), DatasetItem('7', subset='b', annotations=[Label(1), Label(2)]), DatasetItem('8', subset='b', annotations=[Label(2)]), ], categories=['a', 'b', 'c']) actual1 = LabelRandomSampler(source, count=2, seed=1) actual2 = LabelRandomSampler(source, count=2, seed=2) with self.assertRaises(AssertionError): compare_datasets_strict(self, actual1, actual2)
def test_can_reproduce_sequence(self): source = Dataset.from_iterable([ DatasetItem('1', subset='a', annotations=[Label(0), Label(1)]), DatasetItem('2', subset='a', annotations=[Label(1)]), DatasetItem('3', subset='a', annotations=[Label(2)]), DatasetItem('4', subset='a', annotations=[Label(1), Label(2)]), DatasetItem('5', subset='b', annotations=[Label(0)]), DatasetItem('6', subset='b', annotations=[Label(0), Label(2)]), DatasetItem('7', subset='b', annotations=[Label(1), Label(2)]), DatasetItem('8', subset='b', annotations=[Label(2)]), ], categories=['a', 'b', 'c']) seed = 42 actual1 = LabelRandomSampler(source, count=2, seed=seed) actual2 = LabelRandomSampler(source, count=2, seed=seed) compare_datasets_strict(self, actual1, actual2)
def test_can_save_and_load_image_with_arbitrary_extension(self): expected = Dataset.from_iterable([ DatasetItem(id='q/1', image=Image(path='q/1.JPEG', data=np.zeros( (4, 3, 3)))), DatasetItem(id='a/b/c/2', image=Image(path='a/b/c/2.bmp', data=np.zeros((3, 4, 3)))), ]) for importer, converter in [ ('icdar_word_recognition', IcdarWordRecognitionConverter), ('icdar_text_localization', IcdarTextLocalizationConverter), ('icdar_text_segmentation', IcdarTextSegmentationConverter), ]: with self.subTest(subformat=converter), TestDir() as test_dir: self._test_save_and_load(expected, partial(converter.convert, save_images=True), test_dir, importer, require_images=True)
def test_can_import(self): target = Dataset.from_iterable([ DatasetItem(id=1, subset='train', image=np.ones((5, 1)), annotations=[ Mask(np.array([[0, 0, 0, 1, 0]]), label=3, attributes={'track_id': 1}), Mask(np.array([[0, 0, 1, 0, 0]]), label=2, attributes={'track_id': 2}), Mask(np.array([[1, 1, 0, 0, 0]]), label=3, attributes={'track_id': 3}), ]), DatasetItem(id=2, subset='train', image=np.ones((5, 1)), annotations=[ Mask(np.array([[1, 0, 0, 0, 0]]), label=3, attributes={'track_id': 2}), ]), DatasetItem(id=3, subset='val', image=np.ones((5, 1)), annotations=[ Mask(np.array([[0, 1, 0, 0, 0]]), label=0, attributes={'track_id': 1}), ]), ], categories=['a', 'b', 'c', 'd']) parsed = Project.import_from(DUMMY_DATASET_DIR, 'mots').make_dataset() compare_datasets(self, expected=target, actual=parsed)
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 _generate_dataset(self, config, num_duplicate, dataset='classification'): subsets = ["train", "val", "test"] if dataset == 'classification': dummy_images = [ np.random.randint(0, 255, size=(224, 224, 3)) for _ in range(num_duplicate) ] if dataset == 'invalid_channel': dummy_images = [ np.random.randint(0, 255, size=(224, 224, 2)) for _ in range(num_duplicate) ] if dataset == 'invalid_dimension': dummy_images = [ np.random.randint(0, 255, size=(224, 224, 3, 3)) for _ in range(num_duplicate) ] iterable = [] label_cat = LabelCategories() idx = 0 for label_id, label in enumerate(config.keys()): label_cat.add(label, attributes=None) num_item = config[label] for subset in subsets: for _ in range(num_item): idx += 1 iterable.append( DatasetItem( idx, subset=subset, annotations=[Label(label_id)], image=dummy_images[idx % num_duplicate], )) categories = {AnnotationType.label: label_cat} dataset = Dataset.from_iterable(iterable, categories) return dataset
def test_can_import_bboxes(self): expected_dataset = Dataset.from_iterable([ DatasetItem(id='img_1', subset='train', image=np.ones((10, 15, 3)), annotations=[ Polygon([0, 0, 3, 1, 4, 6, 1, 7], attributes={'text': 'FOOD'}), ] ), DatasetItem(id='img_2', subset='train', image=np.ones((10, 15, 3)), annotations=[ Bbox(0, 0, 2, 3, attributes={'text': 'RED'}), Bbox(3, 3, 2, 3, attributes={'text': 'LION'}), ] ), ]) dataset = Dataset.import_from( osp.join(DUMMY_DATASET_DIR, 'text_localization'), 'icdar') compare_datasets(self, expected_dataset, dataset)