def construct_toy_data(poly2mask=True): img = np.array([[1, 2, 3, 4], [5, 6, 7, 8]], dtype=np.uint8) img = np.stack([img, img, img], axis=-1) results = dict() # image results['img'] = img results['img_shape'] = img.shape results['img_fields'] = ['img'] # bboxes results['bbox_fields'] = ['gt_bboxes', 'gt_bboxes_ignore'] results['gt_bboxes'] = np.array([[0., 0., 2., 1.]], dtype=np.float32) results['gt_bboxes_ignore'] = np.array([[2., 0., 3., 1.]], dtype=np.float32) # labels results['gt_labels'] = np.array([1], dtype=np.int64) # masks results['mask_fields'] = ['gt_masks'] if poly2mask: gt_masks = np.array([[0, 1, 1, 0], [0, 1, 0, 0]], dtype=np.uint8)[None, :, :] results['gt_masks'] = BitmapMasks(gt_masks, 2, 4) else: raw_masks = [[np.array([1, 0, 2, 0, 2, 1, 1, 1], dtype=np.float)]] results['gt_masks'] = PolygonMasks(raw_masks, 2, 4) # segmentations results['seg_fields'] = ['gt_semantic_seg'] results['gt_semantic_seg'] = img[..., 0] return results
def _translated_gt(masks, direction, offset, out_shape): translated_masks = [] for poly_per_obj in masks: translated_poly_per_obj = [] for p in poly_per_obj: p = p.copy() if direction == 'horizontal': p[0::2] = np.clip(p[0::2] + offset, 0, out_shape[1]) elif direction == 'vertical': p[1::2] = np.clip(p[1::2] + offset, 0, out_shape[0]) if PolygonMasks([[p]], *out_shape).areas[0] > 0: # filter invalid (area=0) translated_poly_per_obj.append(p) if len(translated_poly_per_obj): translated_masks.append(translated_poly_per_obj) translated_masks = PolygonMasks(translated_masks, *out_shape) return translated_masks
def _load_masks(results, poly2mask=True): h, w = results['img_info']['height'], results['img_info']['width'] gt_masks = results['ann_info']['masks'] if poly2mask: gt_masks = BitmapMasks([_poly2mask(mask, h, w) for mask in gt_masks], h, w) else: gt_masks = PolygonMasks( [_process_polygons(polygons) for polygons in gt_masks], h, w) results['gt_masks'] = gt_masks results['mask_fields'] = ['gt_masks']
def may_augment_annotation(self, aug, shape, target_shape, results): if aug is None: return results # augment polygon mask for key in results['mask_fields']: if self.clip_invalid_polys: masks = self.may_augment_poly(aug, shape, results[key]) results[key] = PolygonMasks(masks, *target_shape[:2]) else: masks = self.may_augment_poly_legacy(aug, shape, results[key]) if len(masks) > 0: results[key] = PolygonMasks(masks, *target_shape[:2]) # augment bbox for key in results['bbox_fields']: bboxes = self.may_augment_bbox(aug, shape, results[key]) results[key] = np.zeros(0) if len(bboxes) > 0: results[key] = np.stack(bboxes) return results
def __call__(self, results): # sampling crop # crop image, boxes, masks img = results['img'] crop_x, crop_y, crop_w, crop_h = self.crop_area( img, results['gt_masks']) scale_w = self.target_size[0] / crop_w scale_h = self.target_size[1] / crop_h scale = min(scale_w, scale_h) h = int(crop_h * scale) w = int(crop_w * scale) padded_img = np.zeros( (self.target_size[1], self.target_size[0], img.shape[2]), img.dtype) padded_img[:h, :w] = mmcv.imresize( img[crop_y:crop_y + crop_h, crop_x:crop_x + crop_w], (w, h)) # for bboxes for key in results['bbox_fields']: lines = [] for box in results[key]: box = box.reshape(2, 2) poly = ((box - (crop_x, crop_y)) * scale) if not self.is_poly_outside_rect(poly, 0, 0, w, h): lines.append(poly.flatten()) results[key] = np.array(lines) # for masks for key in results['mask_fields']: polys = [] polys_label = [] for poly in results[key]: poly = np.array(poly).reshape(-1, 2) poly = ((poly - (crop_x, crop_y)) * scale) if not self.is_poly_outside_rect(poly, 0, 0, w, h): polys.append([poly]) polys_label.append(0) results[key] = PolygonMasks(polys, *self.target_size) if key == 'gt_masks': results['gt_labels'] = polys_label results['img'] = padded_img results['img_shape'] = padded_img.shape return results
def may_augment_annotation(self, aug, shape, target_shape, results): if aug is None: return results # augment polygon mask for key in results['mask_fields']: masks = self.may_augment_poly(aug, shape, results[key]) if len(masks) > 0: results[key] = PolygonMasks(masks, *target_shape[:2]) # augment bbox for key in results['bbox_fields']: bboxes = self.may_augment_poly(aug, shape, results[key], mask_flag=False) results[key] = np.zeros(0) if len(bboxes) > 0: results[key] = np.stack(bboxes) return results
def may_augment_annotation(self, aug, shape, target_shape, results): if aug is None: return results for key in results['mask_fields']: # augment polygon mask masks = [] for mask in results[key]: masks.append( [self.may_augment_poly(aug, shape, target_shape, mask[0])]) if len(masks) > 0: results[key] = PolygonMasks(masks, *target_shape[:2]) for key in results['bbox_fields']: # augment bbox bboxes = [] for bbox in results[key]: bbox = self.may_augment_poly(aug, shape, target_shape, bbox) bboxes.append(bbox) results[key] = np.zeros(0) if len(bboxes) > 0: results[key] = np.stack(bboxes) return results
def test_shear(): # test assertion for invalid type of max_shear_magnitude with pytest.raises(AssertionError): transform = dict(type='Shear', level=1, max_shear_magnitude=(0.5, )) build_from_cfg(transform, PIPELINES) # test assertion for invalid value of max_shear_magnitude with pytest.raises(AssertionError): transform = dict(type='Shear', level=2, max_shear_magnitude=1.2) build_from_cfg(transform, PIPELINES) # test ValueError for invalid type of img_fill_val with pytest.raises(ValueError): transform = dict(type='Shear', level=2, img_fill_val=[128]) build_from_cfg(transform, PIPELINES) results = construct_toy_data() # test case when no shear aug (level=0, direction='horizontal') img_fill_val = (104, 116, 124) seg_ignore_label = 255 transform = dict( type='Shear', level=0, prob=1., img_fill_val=img_fill_val, seg_ignore_label=seg_ignore_label, direction='horizontal') shear_module = build_from_cfg(transform, PIPELINES) results_wo_shear = shear_module(copy.deepcopy(results)) check_shear(results, results_wo_shear) # test case when no shear aug (level=0, direction='vertical') transform = dict( type='Shear', level=0, prob=1., img_fill_val=img_fill_val, seg_ignore_label=seg_ignore_label, direction='vertical') shear_module = build_from_cfg(transform, PIPELINES) results_wo_shear = shear_module(copy.deepcopy(results)) check_shear(results, results_wo_shear) # test case when no shear aug (prob<=0) transform = dict( type='Shear', level=10, prob=0., img_fill_val=img_fill_val, direction='vertical') shear_module = build_from_cfg(transform, PIPELINES) results_wo_shear = shear_module(copy.deepcopy(results)) check_shear(results, results_wo_shear) # test shear horizontally, magnitude=1 transform = dict( type='Shear', level=10, prob=1., img_fill_val=img_fill_val, direction='horizontal', max_shear_magnitude=1., random_negative_prob=0.) shear_module = build_from_cfg(transform, PIPELINES) results_sheared = shear_module(copy.deepcopy(results)) results_gt = copy.deepcopy(results) img_s = np.array([[1, 2, 3, 4], [0, 5, 6, 7]], dtype=np.uint8) img_s = np.stack([img_s, img_s, img_s], axis=-1) img_s[1, 0, :] = np.array(img_fill_val) results_gt['img'] = img_s results_gt['gt_bboxes'] = np.array([[0., 0., 3., 1.]], dtype=np.float32) results_gt['gt_bboxes_ignore'] = np.array([[2., 0., 4., 1.]], dtype=np.float32) gt_masks = np.array([[0, 1, 1, 0], [0, 0, 1, 0]], dtype=np.uint8)[None, :, :] results_gt['gt_masks'] = BitmapMasks(gt_masks, 2, 4) results_gt['gt_semantic_seg'] = np.array( [[1, 2, 3, 4], [255, 5, 6, 7]], dtype=results['gt_semantic_seg'].dtype) check_shear(results_gt, results_sheared) # test PolygonMasks with shear horizontally, magnitude=1 results = construct_toy_data(poly2mask=False) results_sheared = shear_module(copy.deepcopy(results)) gt_masks = [[np.array([1, 0, 2, 0, 3, 1, 2, 1], dtype=np.float)]] results_gt['gt_masks'] = PolygonMasks(gt_masks, 2, 4) check_shear(results_gt, results_sheared) # test shear vertically, magnitude=-1 img_fill_val = 128 results = construct_toy_data() transform = dict( type='Shear', level=10, prob=1., img_fill_val=img_fill_val, direction='vertical', max_shear_magnitude=1., random_negative_prob=1.) shear_module = build_from_cfg(transform, PIPELINES) results_sheared = shear_module(copy.deepcopy(results)) results_gt = copy.deepcopy(results) img_s = np.array([[1, 6, img_fill_val, img_fill_val], [5, img_fill_val, img_fill_val, img_fill_val]], dtype=np.uint8) img_s = np.stack([img_s, img_s, img_s], axis=-1) results_gt['img'] = img_s results_gt['gt_bboxes'] = np.empty((0, 4), dtype=np.float32) results_gt['gt_labels'] = np.empty((0, ), dtype=np.int64) results_gt['gt_bboxes_ignore'] = np.empty((0, 4), dtype=np.float32) gt_masks = np.array([[0, 1, 0, 0], [0, 0, 0, 0]], dtype=np.uint8)[None, :, :] results_gt['gt_masks'] = BitmapMasks(gt_masks, 2, 4) results_gt['gt_semantic_seg'] = np.array( [[1, 6, 255, 255], [5, 255, 255, 255]], dtype=results['gt_semantic_seg'].dtype) check_shear(results_gt, results_sheared) # test PolygonMasks with shear vertically, magnitude=-1 results = construct_toy_data(poly2mask=False) results_sheared = shear_module(copy.deepcopy(results)) gt_masks = [[np.array([1, 0, 2, 0, 2, 0, 1, 0], dtype=np.float)]] results_gt['gt_masks'] = PolygonMasks(gt_masks, 2, 4) check_shear(results_gt, results_sheared) results = construct_toy_data() # same mask for BitmapMasks and PolygonMasks results['gt_masks'] = BitmapMasks( np.array([[0, 1, 1, 0], [0, 1, 1, 0]], dtype=np.uint8)[None, :, :], 2, 4) results['gt_bboxes'] = np.array([[1., 0., 2., 1.]], dtype=np.float32) results_sheared_bitmap = shear_module(copy.deepcopy(results)) check_shear(results_sheared_bitmap, results_sheared) # test AutoAugment equipped with Shear policies = [[dict(type='Shear', level=10, prob=1.)]] autoaug = dict(type='AutoAugment', policies=policies) autoaug_module = build_from_cfg(autoaug, PIPELINES) autoaug_module(copy.deepcopy(results)) policies = [[ dict(type='Shear', level=10, prob=1.), dict( type='Shear', level=8, img_fill_val=img_fill_val, direction='vertical', max_shear_magnitude=1.) ]] autoaug = dict(type='AutoAugment', policies=policies) autoaug_module = build_from_cfg(autoaug, PIPELINES) autoaug_module(copy.deepcopy(results))
def test_rotate(): # test assertion for invalid type of max_rotate_angle with pytest.raises(AssertionError): transform = dict(type='Rotate', level=1, max_rotate_angle=(30, )) build_from_cfg(transform, PIPELINES) # test assertion for invalid type of scale with pytest.raises(AssertionError): transform = dict(type='Rotate', level=2, scale=(1.2, )) build_from_cfg(transform, PIPELINES) # test ValueError for invalid type of img_fill_val with pytest.raises(ValueError): transform = dict(type='Rotate', level=2, img_fill_val=[ 128, ]) build_from_cfg(transform, PIPELINES) # test assertion for invalid number of elements in center with pytest.raises(AssertionError): transform = dict(type='Rotate', level=2, center=(0.5, )) build_from_cfg(transform, PIPELINES) # test assertion for invalid type of center with pytest.raises(AssertionError): transform = dict(type='Rotate', level=2, center=[0, 0]) build_from_cfg(transform, PIPELINES) # test case when no rotate aug (level=0) results = construct_toy_data() img_fill_val = (104, 116, 124) seg_ignore_label = 255 transform = dict( type='Rotate', level=0, prob=1., img_fill_val=img_fill_val, seg_ignore_label=seg_ignore_label, ) rotate_module = build_from_cfg(transform, PIPELINES) results_wo_rotate = rotate_module(copy.deepcopy(results)) check_result_same(results, results_wo_rotate) # test case when no rotate aug (prob<=0) transform = dict(type='Rotate', level=10, prob=0., img_fill_val=img_fill_val, scale=0.6) rotate_module = build_from_cfg(transform, PIPELINES) results_wo_rotate = rotate_module(copy.deepcopy(results)) check_result_same(results, results_wo_rotate) # test clockwise rotation with angle 90 results = construct_toy_data() img_fill_val = 128 transform = dict( type='Rotate', level=10, max_rotate_angle=90, img_fill_val=img_fill_val, # set random_negative_prob to 0 for clockwise rotation random_negative_prob=0., prob=1.) rotate_module = build_from_cfg(transform, PIPELINES) results_rotated = rotate_module(copy.deepcopy(results)) img_r = np.array([[img_fill_val, 6, 2, img_fill_val], [img_fill_val, 7, 3, img_fill_val]]).astype(np.uint8) img_r = np.stack([img_r, img_r, img_r], axis=-1) results_gt = copy.deepcopy(results) results_gt['img'] = img_r results_gt['gt_bboxes'] = np.array([[1., 0., 2., 1.]], dtype=np.float32) results_gt['gt_bboxes_ignore'] = np.empty((0, 4), dtype=np.float32) gt_masks = np.array([[0, 1, 1, 0], [0, 0, 1, 0]], dtype=np.uint8)[None, :, :] results_gt['gt_masks'] = BitmapMasks(gt_masks, 2, 4) results_gt['gt_semantic_seg'] = np.array( [[255, 6, 2, 255], [255, 7, 3, 255]]).astype(results['gt_semantic_seg'].dtype) check_result_same(results_gt, results_rotated) # test clockwise rotation with angle 90, PolygonMasks results = construct_toy_data(poly2mask=False) results_rotated = rotate_module(copy.deepcopy(results)) gt_masks = [[np.array([2, 0, 2, 1, 1, 1, 1, 0], dtype=np.float)]] results_gt['gt_masks'] = PolygonMasks(gt_masks, 2, 4) check_result_same(results_gt, results_rotated) # test counter-clockwise roatation with angle 90, # and specify the ratation center img_fill_val = (104, 116, 124) transform = dict( type='Rotate', level=10, max_rotate_angle=90, center=(0, 0), img_fill_val=img_fill_val, # set random_negative_prob to 1 for counter-clockwise rotation random_negative_prob=1., prob=1.) results = construct_toy_data() rotate_module = build_from_cfg(transform, PIPELINES) results_rotated = rotate_module(copy.deepcopy(results)) results_gt = copy.deepcopy(results) h, w = results['img'].shape[:2] img_r = np.stack([ np.ones((h, w)) * img_fill_val[0], np.ones((h, w)) * img_fill_val[1], np.ones((h, w)) * img_fill_val[2] ], axis=-1).astype(np.uint8) img_r[0, 0, :] = 1 img_r[0, 1, :] = 5 results_gt['img'] = img_r results_gt['gt_bboxes'] = np.empty((0, 4), dtype=np.float32) results_gt['gt_bboxes_ignore'] = np.empty((0, 4), dtype=np.float32) results_gt['gt_labels'] = np.empty((0, ), dtype=np.int64) gt_masks = np.empty((0, h, w), dtype=np.uint8) results_gt['gt_masks'] = BitmapMasks(gt_masks, h, w) gt_seg = (np.ones((h, w)) * 255).astype(results['gt_semantic_seg'].dtype) gt_seg[0, 0], gt_seg[0, 1] = 1, 5 results_gt['gt_semantic_seg'] = gt_seg check_result_same(results_gt, results_rotated) transform = dict(type='Rotate', level=10, max_rotate_angle=90, center=(0), img_fill_val=img_fill_val, random_negative_prob=1., prob=1.) rotate_module = build_from_cfg(transform, PIPELINES) results_rotated = rotate_module(copy.deepcopy(results)) check_result_same(results_gt, results_rotated) # test counter-clockwise roatation with angle 90, # and specify the ratation center, PolygonMasks results = construct_toy_data(poly2mask=False) results_rotated = rotate_module(copy.deepcopy(results)) gt_masks = [[np.array([0, 0, 0, 0, 1, 0, 1, 0], dtype=np.float)]] results_gt['gt_masks'] = PolygonMasks(gt_masks, 2, 4) check_result_same(results_gt, results_rotated) # test AutoAugment equipped with Rotate policies = [[dict(type='Rotate', level=10, prob=1.)]] autoaug = dict(type='AutoAugment', policies=policies) autoaug_module = build_from_cfg(autoaug, PIPELINES) autoaug_module(copy.deepcopy(results)) policies = [[ dict(type='Rotate', level=10, prob=1.), dict(type='Rotate', level=8, max_rotate_angle=90, center=(0), img_fill_val=img_fill_val) ]] autoaug = dict(type='AutoAugment', policies=policies) autoaug_module = build_from_cfg(autoaug, PIPELINES) autoaug_module(copy.deepcopy(results))