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 __iter__(self): yield DatasetItem(id=1, annotations=[ Bbox(2, 3, 4, 5, label=self._label('label_1'), id=1, group=1, attributes={ 'truncated': False, 'difficult': False, 'occluded': False, }), Bbox(1, 2, 3, 4, label=self._label('label_2'), id=2, group=2, attributes={ 'truncated': False, 'difficult': False, 'occluded': False, }), ])
def __iter__(self): return iter([ DatasetItem(id='a/b/1', subset='a', annotations=[ Bbox(2, 3, 4, 5, label=2, id=1, group=1, attributes={ 'truncated': True, 'difficult': False, 'occluded': False, # no attributes here in the label categories } ), Bbox(5, 4, 3, 2, label=self._label('person'), id=2, group=2, attributes={ 'truncated': True, 'difficult': False, 'occluded': False, VOC.VocAction(1).name: True, VOC.VocAction(2).name: True, **{ a.name: False for a in VOC.VocAction if a.value not in {1, 2} } } ), ]), ])
def __iter__(self): return iter([ DatasetItem(id=1, subset='a', annotations=[ Bbox(2, 3, 4, 5, label=2, attributes={'occluded': True}), Bbox( 2, 3, 4, 5, label=3, attributes={'truncated': True}, ), ]), DatasetItem(id=2, subset='b', annotations=[ Bbox( 5, 4, 6, 5, label=3, attributes={'difficult': True}, ), ]), ])
def test_can_find_bbox_with_wrong_label(self): detections = 3 class_count = 2 item1 = DatasetItem(id=1, annotations=[ Bbox(i * 10, 10, 10, 10, label=i) for i in range(detections) ]) item2 = DatasetItem(id=2, annotations=[ Bbox(i * 10, 10, 10, 10, label=(i + 1) % class_count) for i in range(detections) ]) iou_thresh = 0.5 comp = DistanceComparator(iou_threshold=iou_thresh) result = comp.match_boxes(item1, item2) matches, mispred, a_greater, b_greater = result self.assertEqual(len(item1.annotations), len(mispred)) self.assertEqual(0, len(a_greater)) self.assertEqual(0, len(b_greater)) self.assertEqual(0, len(matches)) for a_bbox, b_bbox in mispred: self.assertLess(iou_thresh, a_bbox.iou(b_bbox)) self.assertEqual((a_bbox.label + 1) % class_count, b_bbox.label)
def __iter__(self): yield DatasetItem(id=1, annotations=[ Bbox(2, 3, 4, 5, label=self._label( VOC.VocLabel(1).name), id=1, group=1, attributes={ 'truncated': False, 'difficult': False, 'occluded': False, }), Bbox(1, 2, 3, 4, label=self._label('non_voc_label'), id=2, group=2, attributes={ 'truncated': False, 'difficult': False, 'occluded': False, }), ])
def __iter__(self): return iter([ DatasetItem(id='a/1', subset='a', annotations=[ Bbox(2, 3, 4, 5, label=2, id=1, group=1, attributes={ 'truncated': False, 'difficult': False, 'occluded': True, } ), Bbox(2, 3, 4, 5, label=3, id=2, group=2, attributes={ 'truncated': True, 'difficult': False, 'occluded': False, }, ), ]), DatasetItem(id=2, subset='b', annotations=[ Bbox(5, 4, 6, 5, label=3, id=1, group=1, attributes={ 'truncated': False, 'difficult': True, 'occluded': False, }, ), ]), ])
def __iter__(self): return iter([ DatasetItem( id='a/b/1', subset='a', annotations=[ Bbox(2, 3, 4, 5, label=2, id=1, group=1, attributes={ 'pose': VOC.VocPose(1).name, 'truncated': True, 'difficult': False, 'occluded': False, }), Bbox(2, 3, 1, 1, label=self._label(VOC.VocBodyPart(1).name), group=1), Bbox(5, 4, 3, 2, label=self._label(VOC.VocBodyPart(2).name), group=1), ]), ])
def __iter__(self): return iter([ DatasetItem(id='a/b/1', subset='a', annotations=[ Bbox(2, 3, 4, 5, label=2, attributes={ 'truncated': True, VOC.VocAction(1).name: True, VOC.VocAction(2).name: True, }), Bbox(5, 4, 3, 2, label=self._label('person'), attributes={ 'truncated': True, VOC.VocAction(1).name: True, VOC.VocAction(2).name: True, }), ]), ])
def __iter__(self): return iter([ DatasetItem(id=1, subset='train', image=np.ones((16, 16, 3)), annotations=[ Bbox(0, 4, 4, 8, label=0, group=2, id=0, attributes={ 'occluded': False, 'username': '', } ), Polygon([0, 4, 4, 4, 5, 6], label=1, id=1, attributes={ 'occluded': True, 'username': '', 'a1': 'qwe', 'a2': True, 'a3': 123, } ), Mask(np.array([[0, 1], [1, 0], [1, 1]]), group=2, id=2, attributes={ 'occluded': False, 'username': '******' } ), Bbox(1, 2, 3, 4, group=1, id=3, attributes={ 'occluded': False, 'username': '', }), Mask(np.array([[0, 0], [0, 0], [1, 1]]), group=1, id=4, attributes={ 'occluded': True, 'username': '' } ), ] ), ])
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_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 = Dataset.import_from(DUMMY_DATASET_DIR, 'tf_detection_api') compare_datasets(self, target_dataset, dataset)
def __iter__(self): return iter([ DatasetItem(id='2007_000001', subset='train', annotations=[ Bbox(4, 5, 2, 2, label=self._label('person'), attributes={ 'truncated': False, 'difficult': False, 'occluded': False, **{ a.name: a.value % 2 == 1 for a in VOC.VocAction } }, id=2, group=2, # TODO: Actions should be excluded # as soon as correct merge is implemented ), Bbox(5.5, 6, 2, 2, label=self._label( VOC.VocBodyPart(1).name), group=2 ) ] ), DatasetItem(id='2007_000002', subset='test') ])
def test_shapes_to_boxes(self): source_dataset = Dataset.from_iterable([ DatasetItem(id=1, image=np.zeros((5, 5, 3)), annotations=[ Mask(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]], ), id=1), Polygon([1, 1, 4, 1, 4, 4, 1, 4], id=2), PolyLine([1, 1, 2, 1, 2, 2, 1, 2], id=3), Points([2, 2, 4, 2, 4, 4, 2, 4], id=4), ] ), ]) target_dataset = Dataset.from_iterable([ DatasetItem(id=1, image=np.zeros((5, 5, 3)), annotations=[ Bbox(0, 0, 4, 4, id=1), Bbox(1, 1, 3, 3, id=2), Bbox(1, 1, 1, 1, id=3), Bbox(2, 2, 2, 2, id=4), ] ), ]) actual = transforms.ShapesToBoxes(source_dataset) compare_datasets(self, target_dataset, actual)
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_annotation_comparison(self): a = Dataset.from_iterable([ DatasetItem(id=1, annotations=[ Caption('hello'), # unmatched Caption('world', group=5), Label(2, attributes={ 'x': 1, 'y': '2', }), Bbox(1, 2, 3, 4, label=4, z_order=1, attributes={ 'score': 1.0, }), Bbox(5, 6, 7, 8, group=5), Points([1, 2, 2, 0, 1, 1], label=0, z_order=4), Mask(label=3, z_order=2, image=np.ones((2, 3))), ]), ], categories=['a', 'b', 'c', 'd']) b = Dataset.from_iterable([ DatasetItem(id=1, annotations=[ Caption('world', group=5), Label(2, attributes={ 'x': 1, 'y': '2', }), Bbox(1, 2, 3, 4, label=4, z_order=1, attributes={ 'score': 1.0, }), Bbox(5, 6, 7, 8, group=5), Bbox(5, 6, 7, 8, group=5), # unmatched Points([1, 2, 2, 0, 1, 1], label=0, z_order=4), Mask(label=3, z_order=2, image=np.ones((2, 3))), ]), ], categories=['a', 'b', 'c', 'd']) comp = ExactComparator() matched, unmatched, _, _, errors = comp.compare_datasets(a, b) self.assertEqual(6, len(matched), matched) self.assertEqual(2, len(unmatched), unmatched) self.assertEqual(0, len(errors), errors)
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 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, group=1), Points([2.787, 2.898, 2.965, 2.79, 2.8, 2.456, 2.81, 2.32, 2.89, 2.3], label=0, group=1), ] ), DatasetItem(id='0002_01', subset='train', image=np.ones((10, 15, 3)), annotations=[ Bbox(1, 3, 1, 1, label=1, group=1), Points([1.2, 3.8, 1.8, 3.82, 1.51, 3.634, 1.43, 3.34, 1.65, 3.32], label=1, group=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_boxes_to_masks(self): source_dataset = Dataset.from_iterable([ DatasetItem(id=1, image=np.zeros((5, 5, 3)), annotations=[ Bbox(0, 0, 3, 3, z_order=1), Bbox(0, 0, 3, 1, z_order=2), Bbox(0, 2, 3, 1, z_order=3), ]), ]) target_dataset = Dataset.from_iterable([ DatasetItem( id=1, image=np.zeros((5, 5, 3)), annotations=[ Mask(np.array( [[1, 1, 1, 0, 0], [1, 1, 1, 0, 0], [1, 1, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]], ), z_order=1), Mask(np.array( [[1, 1, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]], ), z_order=2), Mask(np.array( [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [1, 1, 1, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]], ), z_order=3), ]), ]) actual = transforms.BoxesToMasks(source_dataset) compare_datasets(self, target_dataset, actual)
def __iter__(self): return iter([ DatasetItem( id='2007_000001', subset='train', image=Image(path='2007_000001.jpg', size=(10, 20)), annotations=[ Label(self._label(l.name)) for l in VOC.VocLabel if l.value % 2 == 1 ] + [ Bbox( 1, 2, 2, 2, label=self._label('cat'), attributes={ 'pose': VOC.VocPose(1).name, 'truncated': True, 'difficult': False, 'occluded': False, }, id=1, group=1, ), Bbox( 4, 5, 2, 2, label=self._label('person'), attributes={ 'truncated': False, 'difficult': False, 'occluded': False, **{ a.name: a.value % 2 == 1 for a in VOC.VocAction } }, id=2, group=2, ), Bbox(5.5, 6, 2, 2, label=self._label(VOC.VocBodyPart(1).name), group=2), Mask( image=np.ones([5, 10]), label=self._label(VOC.VocLabel(2).name), group=1, ), ]), DatasetItem(id='2007_000002', subset='test', image=np.ones((10, 20, 3))), ])
def DISABLED_test_roi_nms(): ROI = namedtuple('ROI', ['conf', 'x', 'y', 'w', 'h', 'label']) class_count = 3 noisy_count = 3 rois = [ ROI(0.3, 10, 40, 30, 10, 0), ROI(0.5, 70, 90, 7, 10, 0), ROI(0.7, 5, 20, 40, 60, 2), ROI(0.9, 30, 20, 10, 40, 1), ] pixel_jitter = 10 detections = [] for i, roi in enumerate(rois): detections.append( Bbox(roi.x, roi.y, roi.w, roi.h, label=roi.label, attributes={'score': roi.conf})) for j in range(noisy_count): cls_conf = roi.conf * j / noisy_count cls = (i + j) % class_count box = [roi.x, roi.y, roi.w, roi.h] offset = (np.random.rand(4) - 0.5) * pixel_jitter detections.append( Bbox(*(box + offset), label=cls, attributes={'score': cls_conf})) import cv2 image = np.zeros((100, 100, 3)) for i, det in enumerate(detections): roi = ROI(det.attributes['score'], *det.get_bbox(), det.label) p1 = (int(roi.x), int(roi.y)) p2 = (int(roi.x + roi.w), int(roi.y + roi.h)) c = (0, 1 * (i % (1 + noisy_count) == 0), 1) cv2.rectangle(image, p1, p2, c) cv2.putText(image, 'd%s-%s-%.2f' % (i, roi.label, roi.conf), p1, cv2.FONT_HERSHEY_SIMPLEX, 0.25, c) cv2.imshow('nms_image', image) cv2.waitKey(0) nms_boxes = RISE.nms(detections, iou_thresh=0.25) print(len(detections), len(nms_boxes)) for i, det in enumerate(nms_boxes): roi = ROI(det.attributes['score'], *det.get_bbox(), det.label) p1 = (int(roi.x), int(roi.y)) p2 = (int(roi.x + roi.w), int(roi.y + roi.h)) c = (0, 1, 0) cv2.rectangle(image, p1, p2, c) cv2.putText(image, 'p%s-%s-%.2f' % (i, roi.label, roi.conf), p1, cv2.FONT_HERSHEY_SIMPLEX, 0.25, c) cv2.imshow('nms_image', image) cv2.waitKey(0)
def __iter__(self): yield DatasetItem(id=1, annotations=[ Bbox(2, 3, 4, 5, label=0, id=1), Bbox(1, 2, 3, 4, label=1, id=2, group=2, attributes={'act1': True}), Bbox(2, 3, 4, 5, label=2, id=3, group=2), Bbox(2, 3, 4, 6, label=3, id=4, group=2), ])
def __iter__(self): yield DatasetItem(id=1, annotations=[ Bbox(2, 3, 4, 5, label=self._label('foreign_label'), id=1), Bbox(1, 2, 3, 4, label=self._label('label'), id=2, group=2, attributes={'act1': True}), Bbox(2, 3, 4, 5, label=self._label('label_part1'), group=2), Bbox(2, 3, 4, 6, label=self._label('label_part2'), group=2), ])
def __iter__(self): return iter([ DatasetItem(id=100, subset='train', image=np.ones((10, 6, 3)), annotations=[ Caption('hello', id=1), Caption('world', id=2, group=5), Label(2, id=3, attributes={ 'x': 1, 'y': '2', }), Bbox(1, 2, 3, 4, label=4, id=4, z_order=1, attributes={ 'score': 1.0, }), Bbox(5, 6, 7, 8, id=5, group=5), Points([1, 2, 2, 0, 1, 1], label=0, id=5, z_order=4), Mask(label=3, id=5, z_order=2, image=np.ones((2, 3))), ]), DatasetItem(id=21, subset='train', annotations=[ Caption('test'), Label(2), Bbox(1, 2, 3, 4, 5, id=42, group=42) ]), DatasetItem(id=2, subset='val', annotations=[ PolyLine([1, 2, 3, 4, 5, 6, 7, 8], id=11, z_order=1), Polygon([1, 2, 3, 4, 5, 6, 7, 8], id=12, z_order=4), ]), DatasetItem(id=42, subset='test', attributes={ 'a1': 5, 'a2': '42' }), DatasetItem(id=42), DatasetItem(id=43, image=Image(path='1/b/c.qq', size=(2, 4))), ])
def __iter__(self): return iter([ 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), ]), ])
def __iter__(self): return iter([ 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), ]), ])
def __iter__(self): return iter([ DatasetItem(id=1, image=np.zeros((5, 5, 3)), annotations=[ Bbox(0, 0, 3, 3, z_order=1), Bbox(0, 0, 3, 1, z_order=2), Bbox(0, 2, 3, 1, z_order=3), ]), ])
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 __iter__(self): return iter([ 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), ]), ])
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)