def random(cls, rng=None, **kwargs): """ Args: rng (None | int | numpy.random.RandomState): seed or state Kwargs: num_preds: number of predicted boxes num_gts: number of true boxes p_ignore (float): probability of a predicted box assinged to an ignored truth p_assigned (float): probability of a predicted box not being assigned p_use_label (float | bool): with labels or not Returns: AssignResult : Example: >>> from mmdet.core.bbox.samplers.sampling_result import * # NOQA >>> self = SamplingResult.random() >>> print(self.__dict__) """ from mmdet.core.bbox.samplers.random_sampler import RandomSampler from mmdet.core.bbox.assigners.assign_result import AssignResult from mmdet.core.bbox import demodata rng = demodata.ensure_rng(rng) # make probabalistic? num = 32 pos_fraction = 0.5 neg_pos_ub = -1 assign_result = AssignResult.random(rng=rng, **kwargs) # Note we could just compute an assignment bboxes = demodata.random_boxes(assign_result.num_preds, rng=rng) gt_bboxes = demodata.random_boxes(assign_result.num_gts, rng=rng) if rng.rand() > 0.2: # sometimes algorithms squeeze their data, be robust to that gt_bboxes = gt_bboxes.squeeze() bboxes = bboxes.squeeze() if assign_result.labels is None: gt_labels = None else: gt_labels = None # todo if gt_labels is None: add_gt_as_proposals = False else: add_gt_as_proposals = True # make probabalistic? sampler = RandomSampler(num, pos_fraction, neg_pos_ubo=neg_pos_ub, add_gt_as_proposals=add_gt_as_proposals, rng=rng) self = sampler.sample(assign_result, bboxes, gt_bboxes, gt_labels) return self
def test_seq_random_crop(self): # test assertion for invalid random crop with pytest.raises(AssertionError): transform = dict( type='SeqRandomCrop', crop_size=(-1, 0), share_params=False) build_from_cfg(transform, PIPELINES) crop_size = (256, 384) transform = dict( type='SeqRandomCrop', crop_size=crop_size, share_params=False) crop_module = build_from_cfg(transform, PIPELINES) results = copy.deepcopy(self.results) for res in results: res['gt_bboxes'] = random_boxes(8, 256) res['gt_labels'] = np.random.randint(8) res['gt_instance_ids'] = np.random.randint(8) res['gt_bboxes_ignore'] = random_boxes(2, 256) outs = crop_module(results) assert len(outs) == len(results) for res in results: assert res['img'].shape[:2] == crop_size # All bboxes should be reserved after crop assert res['img_shape'][:2] == crop_size assert res['gt_bboxes'].shape[0] == 8 assert res['gt_bboxes_ignore'].shape[0] == 2 assert outs[0]['img_info']['crop_offsets'] != outs[1]['img_info'][ 'crop_offsets'] crop_module.share_params = True outs = crop_module(results) assert outs[0]['img_info']['crop_offsets'] == outs[1]['img_info'][ 'crop_offsets']
def test_track(self): self.tracker.reset() img_size, feats_channel = 64, 256 img_metas = [dict(scale_factor=1.0)] model = MagicMock() model.track_head.extract_roi_feats = MagicMock( return_value=(torch.rand(self.num_objs, feats_channel, 7, 7), [self.num_objs])) model.track_head.simple_test = MagicMock( return_value=torch.rand((self.num_objs, self.num_objs + 1))) feats = torch.rand((1, feats_channel, img_size, img_size)) bboxes = random_boxes(self.num_objs, 64) scores = torch.rand((self.num_objs, 1)) bboxes = torch.cat((bboxes, scores), dim=1) labels = torch.arange(self.num_objs) for frame_id in range(3): bboxes, labels, ids = self.tracker.track(img_metas, feats, model, bboxes, labels, frame_id) assert bboxes.shape[0] == labels.shape[0] assert labels.shape[0] == labels.shape[0] assert ids.shape[0] == labels.shape[0]
def _demodata_refine_boxes(n_roi, n_img, rng=0): """ Create random test data for the ``mmdet.models.bbox_heads.bbox_head.BBoxHead.refine_boxes`` method """ import numpy as np from mmdet.core.bbox.demodata import random_boxes from mmdet.core.bbox.demodata import ensure_rng try: import kwarray except ImportError: import pytest pytest.skip("kwarray is required for this test") scale = 512 rng = ensure_rng(rng) img_metas = [{"img_shape": (scale, scale)} for _ in range(n_img)] # Create rois in the expected format roi_boxes = random_boxes(n_roi, scale=scale, rng=rng) if n_img == 0: assert n_roi == 0, "cannot have any rois if there are no images" img_ids = torch.empty((0, ), dtype=torch.long) roi_boxes = torch.empty((0, 4), dtype=torch.float32) else: img_ids = rng.randint(0, n_img, (n_roi, )) img_ids = torch.from_numpy(img_ids) rois = torch.cat([img_ids[:, None].float(), roi_boxes], dim=1) # Create other args labels = rng.randint(0, 2, (n_roi, )) labels = torch.from_numpy(labels).long() bbox_preds = random_boxes(n_roi, scale=scale, rng=rng) # For each image, pretend random positive boxes are gts is_label_pos = (labels.numpy() > 0).astype(np.int) lbl_per_img = kwarray.group_items(is_label_pos, img_ids.numpy()) pos_per_img = [sum(lbl_per_img.get(gid, [])) for gid in range(n_img)] # randomly generate with numpy then sort with torch _pos_is_gts = [ rng.randint(0, 2, (npos, )).astype(np.uint8) for npos in pos_per_img ] pos_is_gts = [ torch.from_numpy(p).sort(descending=True)[0] for p in _pos_is_gts ] return rois, labels, bbox_preds, pos_is_gts, img_metas
def test_outs2results(): from mmtrack.core import outs2results # pseudo data num_objects, num_classes, image_size = 8, 4, 100 bboxes = random_boxes(num_objects, image_size) scores = torch.FloatTensor(num_objects, 1).uniform_(0, 1) bboxes = torch.cat([bboxes, scores], dim=1) # leave the results of the last class as empty labels = torch.randint(0, num_classes - 1, (num_objects, )) ids = torch.arange(num_objects) masks = torch.randint(0, 2, (num_objects, image_size, image_size)).bool() # test track2result without ids results = outs2results( bboxes=bboxes, labels=labels, masks=masks, num_classes=num_classes) for key in ['bbox_results', 'mask_results']: assert key in results assert len(results['bbox_results']) == num_classes assert isinstance(results['bbox_results'][0], np.ndarray) assert results['bbox_results'][-1].shape == (0, 5) assert len(results['mask_results']) == num_classes assert isinstance(results['mask_results'][-1], list) assert len(results['mask_results'][-1]) == 0 for i in range(num_classes): assert results['bbox_results'][i].shape[0] == (labels == i).sum() assert results['bbox_results'][i].shape[1] == 5 assert len(results['mask_results'][i]) == (labels == i).sum() if len(results['mask_results'][i]) > 0: assert results['mask_results'][i][0].shape == (image_size, image_size) # test track2result with ids results = outs2results( bboxes=bboxes, labels=labels, masks=masks, ids=ids, num_classes=num_classes) for key in ['bbox_results', 'mask_results']: assert key in results assert len(results['bbox_results']) == num_classes assert isinstance(results['bbox_results'][0], np.ndarray) assert results['bbox_results'][-1].shape == (0, 6) assert len(results['mask_results']) == num_classes assert isinstance(results['mask_results'][-1], list) assert len(results['mask_results'][-1]) == 0 for i in range(num_classes): assert results['bbox_results'][i].shape[0] == (labels == i).sum() assert results['bbox_results'][i].shape[1] == 6 assert len(results['mask_results'][i]) == (labels == i).sum() if len(results['mask_results'][i]) > 0: assert results['mask_results'][i][0].shape == (image_size, image_size)
def test_cmc(): cmc = CameraMotionCompensation() img = np.random.randn(256, 256, 3).astype(np.float32) ref_img = img warp_matrix = cmc.get_warp_matrix(img, ref_img) assert isinstance(warp_matrix, torch.Tensor) bboxes = random_boxes(5, 256) trans_bboxes = cmc.warp_bboxes(bboxes, warp_matrix) assert (bboxes == trans_bboxes).all()
def test_seq_bbox_jitter(self): results = copy.deepcopy(self.results) for res in results: res['gt_bboxes'] = random_boxes(1, 256) res['bbox_fields'] = ['gt_bboxes'] transform = dict(type='SeqBboxJitter', center_jitter_factor=[0, 4.5], scale_jitter_factor=[0, 0.5], crop_size_factor=[2, 5]) seq_bbox_jitter = build_from_cfg(transform, PIPELINES) results = seq_bbox_jitter(results) assert results[0]['jittered_bboxes'].shape == (1, 4) assert results[1]['jittered_bboxes'].shape == (1, 4)
def test_seq_shift_scale_aug(self): results = copy.deepcopy(self.results) for res in results: res['gt_bboxes'] = random_boxes(1, 256).numpy() res['bbox_fields'] = ['gt_bboxes'] transform = dict(type='SeqShiftScaleAug', target_size=[127, 255], shift=[4, 64], scale=[0.05, 0.18]) seq_shift_scale_aug = build_from_cfg(transform, PIPELINES) results = seq_shift_scale_aug(results) assert results[0]['img'].shape == (127, 127, 3) assert results[1]['img'].shape == (255, 255, 3)
def test_seq_crop_like_siamfc(self): results = copy.deepcopy(self.results) for res in results: res['gt_bboxes'] = random_boxes(1, 256) res['bbox_fields'] = ['gt_bboxes'] transform = dict(type='SeqCropLikeSiamFC', context_amount=0.5, exemplar_size=127, crop_size=511) seq_crop_like_siamfc = build_from_cfg(transform, PIPELINES) results = seq_crop_like_siamfc(results) assert results[0]['img'].shape == (511, 511, 3) assert results[1]['img'].shape == (511, 511, 3)
def test_update(self): ids = torch.arange(self.num_objs) bboxes = random_boxes(self.num_objs, 64) labels = torch.arange(self.num_objs) embeds = torch.randn(self.num_objs, 256) self.tracker.update(ids=ids, bboxes=bboxes, embeds=embeds, labels=labels, frame_id=0) for tid in range(self.num_objs): assert self.tracker.tracks[tid]['bbox'].equal(bboxes[tid]) assert self.tracker.tracks[tid]['embed'].equal(embeds[tid]) assert self.tracker.tracks[tid]['label'].equal(labels[tid]) assert self.tracker.tracks[tid]['acc_frame'] == 0 assert self.tracker.tracks[tid]['last_frame'] == 0 assert len(self.tracker.tracks[tid]['velocity']) == len( bboxes[tid]) ids = torch.tensor([self.num_objs - 1]) bboxes = random_boxes(1, 64) labels = torch.tensor([self.num_objs]) embeds = torch.randn(1, 256) new_embeds = (1 - self.tracker.memo_momentum) * self.tracker.tracks[ ids.item()]['embed'] + self.tracker.memo_momentum * embeds self.tracker.update(ids=ids, bboxes=bboxes, labels=labels, embeds=embeds, frame_id=1) assert self.tracker.tracks[ids.item()]['embed'].equal( new_embeds[0]) == True # noqa
def test_update(self): for i in range(1, self.num_frames_retain * 2): bboxes = random_boxes(self.num_objs, 512) labels = torch.zeros(self.num_objs, dtype=torch.int) embeds = torch.randn(self.num_objs, 256) ids = torch.arange(self.num_objs) + i self.tracker.update(ids=ids, bboxes=bboxes, labels=labels, embeds=embeds, frame_ids=i) if i < self.num_frames_retain: assert 0 in self.tracker.tracks else: assert 0 not in self.tracker.tracks
def test_seq_crop_like_stark(self): results = copy.deepcopy(self.results) for res in results: res['gt_bboxes'] = random_boxes(1, 256) res['jittered_bboxes'] = np.array([[ res['gt_bboxes'][0][0] - 1, res['gt_bboxes'][0][1] + 2, res['gt_bboxes'][0][2] + 2, res['gt_bboxes'][0][3] + 3 ]]) res['bbox_fields'] = ['gt_bboxes'] transform = dict(type='SeqCropLikeStark', crop_size_factor=[2, 5], output_size=[128, 320]) seq_crop_like_stark = build_from_cfg(transform, PIPELINES) results = seq_crop_like_stark(results) assert results[0]['img'].shape == (128, 128, 3) assert results[1]['img'].shape == (320, 320, 3)
def test_track(self): img_size = 64 img = torch.rand((1, 3, img_size, img_size)) img_metas = [dict(scale_factor=1.0)] model = MagicMock() bboxes = random_boxes(self.num_objs, img_size) scores = torch.rand((self.num_objs, 1)) bboxes = torch.cat((bboxes, scores), dim=1) labels = torch.arange(self.num_objs) for frame_id in range(3): bboxes, labels, ids = self.tracker.track( img, img_metas, model, bboxes, labels, frame_id, rescale=True) assert bboxes.shape[0] == labels.shape[0] assert bboxes.shape[0] == ids.shape[0]
def test_init(self): bboxes = random_boxes(self.num_objs, 512) labels = torch.zeros(self.num_objs) embeds = torch.randn(self.num_objs, 256) ids = torch.arange(self.num_objs) self.tracker.update(ids=ids, bboxes=bboxes, labels=labels, embeds=embeds, frame_ids=0) assert self.tracker.ids == list(ids) assert self.tracker.memo_items == [ 'ids', 'bboxes', 'labels', 'embeds', 'frame_ids' ] for k, v in self.tracker.tracks[0].items(): if k in self.momentums: assert isinstance(v, torch.Tensor) else: assert isinstance(v, list)
def test_track2result(): from mmtrack.core import track2result # pseudo data num_objects, num_classes = 8, 4 bboxes = random_boxes(num_objects, 640) scores = torch.FloatTensor(num_objects, 1).uniform_(0, 1) bboxes = torch.cat([bboxes, scores], dim=1) # leave the results of the last class as empty labels = torch.randint(0, num_classes - 1, (num_objects, )) ids = torch.arange(num_objects) # run result = track2result(bboxes, labels, ids, num_classes) # test assert len(result) == num_classes assert result[-1].shape == (0, 6) assert isinstance(result[0], np.ndarray) for i in range(num_classes): assert result[i].shape[0] == (labels == i).sum() assert result[i].shape[1] == 6
def create_dummy_data(): # 2 categories: ['car', 'person'] classes = ['car', 'person'] # 1 video videos = [ dict(name='dummy_video', images=dict(num=8, shape=(256, 512, 3)), instances=[ dict(frames=[1, 2, 3, 4], category='car'), dict(frames=[4, 5, 6], category='person') ]) ] attrs = dict(occluded=False, truncated=False, iscrowd=False, ignore=False) attrs['is_vid_train_frame'] = True # ImageNet VID attrs['visibility'] = 1.0 # MOT17 # set all corner cases in img_id == 1 corner_cases = dict(ignore=0, iscrowd=3) ann = defaultdict(list) img_id, ann_id, ins_id = 1, 1, 1 for cls_id, cls in enumerate(classes, 1): ann['categories'].append(dict(id=cls_id, name=cls)) for vid_id, video in enumerate(videos, 1): ann['videos'].append(dict(id=vid_id, name=video['name'])) img_info = video['images'] frame2id = dict() for i in range(img_info['num']): img_name = f'image_{img_id}.jpg' # img = np.ones(img_info['shape']) * 125 # mmcv.imwrite(img, img_name) ann['images'].append( dict(file_name=img_name, height=img_info['shape'][0], width=img_info['shape'][1], id=img_id, video_id=vid_id, frame_id=i)) frame2id[i] = img_id img_id += 1 ins_info = video['instances'] for i, ins in enumerate(ins_info): bboxes = random_boxes(len(ins['frames']), min(img_info['shape'][:-1])).numpy() for ind, frame_id in enumerate(ins['frames']): assert frame_id < img_info['num'] x1 = float(bboxes[ind][0]) y1 = float(bboxes[ind][1]) x2 = float(bboxes[ind][2]) y2 = float(bboxes[ind][3]) bbox = [x1, y1, x2 - x1, y2 - y1] area = float((x2 - x1) * (y2 - y1)) bbox[2] = 2.0 if bbox[2] < 1 else bbox[2] bbox[3] = 2.0 if bbox[2] < 1 else bbox[3] ann['annotations'].append( dict(id=ann_id, image_id=frame2id[frame_id], video_id=vid_id, category_id=classes.index(ins['category']) + 1, instance_id=ins_id, bbox=bbox, area=area, **attrs)) ann_id += 1 ins_id += 1 for case, num in corner_cases.items(): bboxes = random_boxes(num, min(img_info['shape'][:-1]) - 1).numpy() for ind in range(bboxes.shape[0]): x1 = float(bboxes[ind][0]) y1 = float(bboxes[ind][1]) x2 = float(bboxes[ind][2]) y2 = float(bboxes[ind][3]) bbox = [x1, y1, x2 - x1, y2 - y1] bbox[2] = 2.0 if bbox[2] < 1 else bbox[2] bbox[3] = 2.0 if bbox[3] < 1 else bbox[3] area = float((x2 - x1) * (y2 - y1)) _attrs = attrs.copy() if case == 'ignore': _attrs['ignore'] = True elif case == 'iscrowd': _attrs['iscrowd'] = True elif case == 'visibility': _attrs['visibility'] = 1.0 else: raise KeyError() ann['annotations'].append( dict(id=ann_id, image_id=1, video_id=1, category_id=1, instance_id=ins_id, bbox=bbox, area=area, **_attrs)) ann_id += 1 ins_id += 1 mmcv.dump(ann, 'ann.json')