def calc_detection(labels, preds, th=0.5, iou_th=0.5): false_negatives = 0 false_positives = 0 for pred, label in zip(preds, labels): # args = pred[:, 5].argsort()[::-1] # opred = pred[args, :] opred = pred[pred[:, 5] > th, :] for i in range(label.shape[0]): for j in range(opred.shape[0]): iou = bbox_iou(label[i, :4].reshape(1, -1), opred[j, :4].reshape(1, -1)).item() if (opred[j, 4] == label[i, 4]) and (iou > iou_th): break else: false_negatives += 1 for i in range(opred.shape[0]): for j in range(label.shape[0]): iou = bbox_iou(label[j, :4].reshape(1, -1), opred[i, :4].reshape(1, -1)).item() if (opred[i, 4] == label[j, 4]) and (iou > iou_th): break else: false_positives += 1 return false_negatives, false_positives
def forward(self, cls_preds, box_preds, cls_targets, box_targets, loss=None): RepLoss = [] all_box_gt = box_targets[0].asnumpy() all_box_pred = box_preds[0].asnumpy() for i in range(all_box_pred.shape[0]): #filter out all zero rows(mainly gt) nonzero_boxgt_index = np.where( all_box_gt[i][:, 0] != all_box_gt[i][:, 2]) nonzero_boxpred_index = np.where( all_box_pred[i][:, 0] != all_box_pred[i][:, 2]) nonzero_box_gt = all_box_gt[i][nonzero_boxgt_index][:, 0:4] nonzero_box_pred = all_box_pred[i][nonzero_boxpred_index][:, 0:4] #calculate iou _iou = bbox_iou(nonzero_box_pred, nonzero_box_gt) # select positive proposals pos_index = np.where(np.max(_iou, axis=1) >= self.iou_thresh) _iou = _iou[pos_index] #for each positive proposals keep its top two iou with targets sort_index = _iou.argsort(axis=1)[:, -2:] iog = [] for _i in range(len(sort_index)): tmp = _iou[_i, sort_index[_i]] iog.append(tmp) iog = np.array(iog) if iog.shape[0] == 0: RepGT = 0 RepBo = 0 else: #RepulsionGT RepGT = self.Smooth_Ln(iog[:, 0], self.sigma) / iog.shape[0] #for each ground truth keep only the proposal with highest iou pos_gt_prop_index = np.argmax(_iou, axis=0) pos_gt_prop = np.array([ nonzero_box_pred[pos_gt_prop_index], nonzero_box_pred[pos_gt_prop_index] ]) # RepulsionBox box_l = np.array([]) total_iou = np.array([]) for row in range(len(pos_gt_prop[0]) - 1): curr = pos_gt_prop[0][row].reshape(1, -1) rest = pos_gt_prop[1][row + 1:] _bbox_iou = bbox_iou(curr, rest) box_l = np.hstack((box_l, [self.Smooth_Ln(_bbox_iou, self.sigma)])) total_iou = np.hstack((total_iou, [np.sum(_bbox_iou)])) RepBo = np.sum(box_l) / (np.sum(total_iou) + self.epo) RepLoss.append(RepGT + RepBo)
def get_class_preds(labels, preds, th=0.5, iou_th=0.5): n_classes = len(cfg.classes) ground_truth = [] predictions = [] for pred, label in zip(preds, labels): for i in range(label.shape[0]): ground_truth.append(label[i, 4]) # Make sure that preidiction are ordered from highest to lowest score args = pred[:, 5].argsort()[::-1] opred = pred[args, :] for j in range(opred.shape[0]): iou = bbox_iou(label[i, :4].reshape(1, -1), opred[j, :4].reshape(1, -1)).item() if (opred[j, 5] > th) and (iou > iou_th): predictions.append(opred[j, 4]) break else: predictions.append(n_classes) return predictions, ground_truth
def _set_labels_and_scores(self, log_folder): self._set_test_dataset() transf = gcv.data.transforms.presets.rcnn.FasterRCNNDefaultValTransform(512) test_true = self.test_dataset.transform(transf) y_true= np.zeros((len(self.test_dataset))) y_scores = np.zeros((len(self.test_dataset))) iou_list = np.zeros((len(self.test_dataset))) x_list_test, _ = gcv.data.transforms.presets.ssd.load_test(self.tests_set, 512) for i, (x, data) in enumerate(zip(x_list_test, test_true)): _, label, _ = data _, _, true_bboxes= ModelBasedDetector.filter_eaf( nd.array([label[:, :4]]),nd.array([label[:, 4:5]]), nd.array(np.ones(shape=(1,2,1)))) box_ids, scores, bboxes = self.net(x) _, n_scores, n_bboxes = ModelBasedDetector.filter_eaf(bboxes,box_ids,scores) iou = utils.bbox_iou(true_bboxes[0].asnumpy(), n_bboxes[0].asnumpy()) iou_list[i] = iou if 1 in label[:, 4:5]: y_true[i] = 1 y_scores[i] = n_scores.asnumpy()[0][0][0] mean_iou = np.mean(iou_list[iou_list > 0]) Path(log_folder).mkdir(parents=True, exist_ok=True) with open(log_folder + 'eval.log', "a") as f: f.write(f"L'intersection over union moyen est : {mean_iou:.3f}\n") self.y_true, self.y_scores, self.mean_iou = y_true, y_scores, mean_iou
def random_crop_with_constraints(bbox, size, height, width, min_scale=0.3, max_scale=1, max_aspect_ratio=2, constraints=None, max_trial=1000): """Crop an image randomly with bounding box constraints. This data augmentation is used in training of Single Shot Multibox Detector [#]_. More details can be found in data augmentation section of the original paper. .. [#] Wei Liu, Dragomir Anguelov, Dumitru Erhan, Christian Szegedy, Scott Reed, Cheng-Yang Fu, Alexander C. Berg. SSD: Single Shot MultiBox Detector. ECCV 2016. Parameters ---------- bbox : numpy.ndarray Numpy.ndarray with shape (N, 4+) where N is the number of bounding boxes. The second axis represents attributes of the bounding box. Specifically, these are :math:`(x_{min}, y_{min}, x_{max}, y_{max})`, we allow additional attributes other than coordinates, which stay intact during bounding box transformations. size : tuple Tuple of length 2 of image shape as (width, height). min_scale : float The minimum ratio between a cropped region and the original image. The default value is :obj:`0.3`. max_scale : float The maximum ratio between a cropped region and the original image. The default value is :obj:`1`. max_aspect_ratio : float The maximum aspect ratio of cropped region. The default value is :obj:`2`. constraints : iterable of tuples An iterable of constraints. Each constraint should be :obj:`(min_iou, max_iou)` format. If means no constraint if set :obj:`min_iou` or :obj:`max_iou` to :obj:`None`. If this argument defaults to :obj:`None`, :obj:`((0.1, None), (0.3, None), (0.5, None), (0.7, None), (0.9, None), (None, 1))` will be used. max_trial : int Maximum number of trials for each constraint before exit no matter what. Returns ------- numpy.ndarray Cropped bounding boxes with shape :obj:`(M, 4+)` where M <= N. tuple Tuple of length 4 as (x_offset, y_offset, new_width, new_height). """ # default params in paper if constraints is None: constraints = ( (0.1, None), (0.3, None), (0.5, None), (0.7, None), (0.9, None), (None, 1), ) if len(bbox) == 0: constraints = [] w, h = size candidates = [] for min_iou, max_iou in constraints: min_iou = -np.inf if min_iou is None else min_iou max_iou = np.inf if max_iou is None else max_iou for _ in range(max_trial): scale = random.uniform(min_scale, max_scale) aspect_ratio = random.uniform( max(1 / max_aspect_ratio, scale * scale), min(max_aspect_ratio, 1 / (scale * scale))) crop_h = int(height * scale / np.sqrt(aspect_ratio)) crop_w = int(width * scale * np.sqrt(aspect_ratio)) crop_t = random.randrange(h - crop_h) crop_l = random.randrange(w - crop_w) crop_bb = np.array( (crop_l, crop_t, crop_l + crop_w, crop_t + crop_h)) iou = bbox_iou(bbox, crop_bb[np.newaxis]) if min_iou <= iou.min() and iou.max() <= max_iou: top, bottom = crop_t, crop_t + crop_h left, right = crop_l, crop_l + crop_w candidates.append((left, top, right - left, bottom - top)) break # random select one while candidates: crop = candidates.pop(np.random.randint(0, len(candidates))) new_bbox = bbox_crop(bbox, crop, allow_outside_center=False) if new_bbox.size < 1: continue new_crop = (crop[0], crop[1], crop[2], crop[3]) return new_bbox, new_crop return random_crop_with_constraints(bbox, (w, h), height, width, min_scale=0.9, max_scale=1, max_trial=50)