def test_calc_heatmap_mixed_args(self): det = data_holders.BBoxDetInst([0.1], [15, 20.8, 45, 60.6], pos_prob=1) expected_map = np.zeros((100, 100)) expected_map[21:61, 15:46] = 1 expected_map[20, 15:46] = 0.2 expected_map[61, 15:46] = 0.6 heatmap = det.calc_heatmap((100, 100)) self.assertNPClose(expected_map, heatmap)
def test_calc_heatmap_outsize_bounds(self): det = data_holders.BBoxDetInst([0.1], [-15.5, 80.8, 45.3, 160.6], pos_prob=1) expected_map = np.zeros((100, 100)) expected_map[81:100, 0:46] = 1 expected_map[81:100, 46] = 0.3 expected_map[80, 0:46] = 0.2 expected_map[80, 46] = 0.3 * 0.2 heatmap = det.calc_heatmap((100, 100)) self.assertNPClose(expected_map, heatmap)
def test_calc_heatmap_float_args(self): det = data_holders.BBoxDetInst([0.1], [15.5, 20.8, 45.3, 60.6], pos_prob=1) expected_map = np.zeros((100, 100)) expected_map[21:61, 16:46] = 1 expected_map[21:61, 15] = 0.5 expected_map[21:61, 46] = 0.3 expected_map[20, 16:46] = 0.2 expected_map[61, 16:46] = 0.6 expected_map[20, 15] = 0.5 * 0.2 expected_map[61, 15] = 0.5 * 0.6 expected_map[20, 46] = 0.3 * 0.2 expected_map[61, 46] = 0.3 * 0.6 heatmap = det.calc_heatmap((100, 100)) self.assertNPClose(expected_map, heatmap)
def __iter__(self): """ Generate DetectionInstances for a given image. DetectionInstances will be of sub-class BBoxDetInst or PBoxDetInst. BBoxDetInst is DetectionInstance for standard bounding box detection. PBoxDetInst is DetectionInstance for probabilistic bounding box detection. :param img_dets: list of detections given as dictionaries. Individual detection dictionaries have the keys: 'img_size': (height x width) 'img_num': int identifying which image the detection is a part of 'label_probs': full list of probabilities that the detection is describing each of the classes 'bbox': coordinates of the bounding box corners [left, top, right, bottom] 'covars': covariances for the top-left and bottom-right corners respectively. Each with format [[xx, xy], [yx, yy]]. Covariances must be positive semi-definite or all zeros (regular BBox). :param class_mapping: A pair of lists of indexes, the first to our class list, and the second to theirs :param num_classes: The number of classes to expect :param img_idx: The current image index, for error reporting :param sequence_name: The current image name, for error reporting :return: generator of DetectionInstances """ # Handle no detections for the image for det_idx, det in enumerate(self._img_dets): if 'label_probs' not in det: raise KeyError(make_error_msg("missing key \'label_probs\'", self._sequence_name, self._img_idx, det_idx)) if 'bbox' not in det: raise KeyError(make_error_msg("missing key \'bbox\'", self._sequence_name, self._img_idx, det_idx)) if len(det['label_probs']) != self._num_classes: raise KeyError(make_error_msg("The number of class probabilities doesn't match the number of classes", self._sequence_name, self._img_idx, det_idx)) if len(det['bbox']) != 4: raise ValueError(make_error_msg("The bounding box must contain exactly 4 entries", self._sequence_name, self._img_idx, det_idx)) if det['bbox'][2] < det['bbox'][0]: raise ValueError(make_error_msg("The x1 coordinate must be less than the x2 coordinate", self._sequence_name, self._img_idx, det_idx)) if det['bbox'][3] < det['bbox'][1]: raise ValueError(make_error_msg("The y1 coordinate must be less than the y2 coordinate", self._sequence_name, self._img_idx, det_idx)) # Use numpy list indexing to move specific indexes from the submission label_probs = np.zeros(len(rvc1_class_list.CLASSES), dtype=np.float32) label_probs[self._class_mapping[0]] = np.array(det['label_probs'])[self._class_mapping[1]] total_prob = np.sum(label_probs) if total_prob > 0.5: # Arbitrary theshold for classes we care about. # Normalize the label probability if total_prob > 1: label_probs /= total_prob if 'covars' not in det or det['covars'] == [[[0, 0], [0, 0]], [[0, 0], [0, 0]]] or self._override_cov == 0: yield data_holders.BBoxDetInst( class_list=label_probs, box=det['bbox'] ) else: if self._override_cov is not None: covars = np.array([[[self._override_cov, 0], [0, self._override_cov]], [[self._override_cov, 0], [0, self._override_cov]]]) else: covars = np.array(det['covars']) if covars.shape != (2, 2, 2): raise ValueError(make_error_msg("Key 'covars' must contain 2 2x2 matrices", self._sequence_name, self._img_idx, det_idx)) if not np.allclose(covars.transpose((0, 2, 1)), covars): raise ValueError(make_error_msg("Given covariances are not symmetric", self._sequence_name, self._img_idx, det_idx)) if not is_positive_semi_definite(covars[0]): raise ValueError(make_error_msg("The upper-left covariance is not positive semi-definite", self._sequence_name, self._img_idx, det_idx)) if not is_positive_semi_definite(covars[1]): raise ValueError(make_error_msg("The lower-right covariance is not positive semi-definite", self._sequence_name, self._img_idx, det_idx)) yield data_holders.PBoxDetInst( class_list=label_probs, box=det['bbox'], covs=det['covars'] )
def test_calc_heatmap_int_args(self): det = data_holders.BBoxDetInst([0.1], [15, 20, 45, 60], pos_prob=1) expected_map = np.zeros((100, 100)) expected_map[20:61, 15:46] = 1 heatmap = det.calc_heatmap((100, 100)) self.assertNPEqual(expected_map, heatmap)