def compute_tp_and_fp_on_single_image(predicts, ground_truths, iou_threshold=0.5): """ :param predicts: numpy array, two dimension numpy array, each row has format [score, x1, y1, x2, y2], shape is m x 5 where m corresponds to predict rectangle number :param ground_truths: numpy array, two dimension numpy array, each row has format [x1, y1, x2, y2], shape is n x 4 where n corresponds to ground truth rectangle number :param iou_threshold: :return: True Positive, False Positive and corresponding scores """ m, n = predicts.shape[0], ground_truths.shape[0] if m == 0: return [], [], [] if n == 0: return [0] * m, [1] * m, predicts[:, 0].tolist() predict_scores = predicts[:, 0] predict_boxes = predicts[:, 1:] # match from highest score to lowest score predict_boxes = predict_boxes[np.argsort(predict_scores)[::-1]] predict_scores = predict_scores[np.argsort(predict_scores)[::-1]] ground_truth_matched_flag = [ 0 ] * n # record if the ground truth has been matched true_positive, false_positive = [0] * m, [0] * m for i in range(m): predict_box = predict_boxes[i] overlaps = np.array( [iou(predict_box, ground_truth) for ground_truth in ground_truths]) if len(overlaps) == 0: false_positive[i] = 1 continue max_overlap = np.max(overlaps) max_overlap_index = np.argmax(overlaps).item() if max_overlap > iou_threshold and ground_truth_matched_flag[ max_overlap_index] is 0: ground_truth_matched_flag[max_overlap_index] = 1 true_positive[i] = 1 else: false_positive[i] = 1 return true_positive, false_positive, predict_scores
def single_frame_match(predicts, ground_truths, predict_score_threshold, iou_threshold): """ :param predicts: numpy array, two dimension numpy array, each row has format [score, x1, y1, x2, y2], shape is m x 5 where m corresponds to predict rectangle number :param ground_truths: numpy array, two dimension numpy array, each row has format [person_id, x1, y1, x2, y2], shape is n x 4 where n corresponds to ground truth rectangle number :param predict_score_threshold: any predict whose score is less than \predict_score_threshold will be ignored :param iou_threshold: :return: return a list, whose length is equal to \ground_truths, each element in the list is the matched predict position(exclude score) if there is not matched predict for some ground truths, the corresponding element is a empty list. for example, something like: [[x1, y1, x2, y2], [], [x1, y1, x2, y2]] where the second element is an empty list, meaning the second ground truth has no matched predict """ n = ground_truths.shape[0] assert n > 0, "there must be at least one ground truth" if len(predicts) == 0: return [[]] * n predict_scores = predicts[:, 0] predict_boxes = predicts[:, 1:] predict_boxes = predict_boxes[np.where( predict_scores >= predict_score_threshold)] m = predict_boxes.shape[0] if m == 0: # there are no predict boxes to be matched return [[]] * n predict_box_used_flag = [0] * m ground_truth_matched_predict = [[]] * n for i in range(n): ground_truth = ground_truths[i][1:] # exclude person id overlaps = np.array( [iou(predict_box, ground_truth) for predict_box in predict_boxes]) max_overlap = np.max(overlaps) max_overlap_index = np.argmax(overlaps).item() if max_overlap > iou_threshold and predict_box_used_flag[ max_overlap_index] is 0: predict_box_used_flag[max_overlap_index] = 1 ground_truth_matched_predict[i] = predict_boxes[max_overlap_index] return ground_truth_matched_predict
if (pred_path != gt_path): #print('pred_path', pred_path, 'gt_path', gt_path) exit(1) dst_json.insert_path(scene_id, cam_id, pred_path) extrinsics = gt_json.get_extrinsics(scene_id, cam_id) dst_json.insert_extrinsics(scene_id, cam_id, extrinsics) edges = [] for pred_inst in pred_insts: for gt_inst in gt_insts: #pred_inst_pos = [p/resize_ratio for p in pred_inst['pos']] #wgt = utility.iou(pred_inst_pos, gt_inst['pos']) wgt = utility.iou(pred_inst['pos'], gt_inst['pos']) pred_id_in_G = 'pred_' + pred_inst['inst_id'] gt_id_in_G = 'gt_' + gt_inst['inst_id'] if wgt: edges.append((pred_id_in_G, gt_id_in_G, wgt)) G.add_weighted_edges(edges) matching = G.match() matching = [ sorted([k, v], reverse=True) for (k, v) in matching.items() ] matching = {l[0]: l[1] for l in matching} for pred_inst in pred_insts: pred_id = pred_inst['inst_id'] pred_id_in_G = 'pred_' + pred_id subcls = pred_inst['subcls'] x1, y1, x2, y2 = pred_inst['pos']
def calc_rpn_pos_neg(self, gt_boxes): gt_boxes = np.array(gt_boxes) num_gt_boxes = len(gt_boxes) #if(num_gt_boxes) : gt_boxes[:,[2,1]] = gt_boxes[:,[1,2]] #x1, y1, x2, y2 pos_anchor_idx, neg_anchor_idx = np.zeros( (0, 3), dtype='int32'), np.zeros((0, 3), dtype='int32') pos_anchor_box, pos_gt_box = np.zeros((0, 4)), np.zeros((0, 4)) best_iou_for_gt_box = np.zeros((num_gt_boxes, )).astype(np.float32) best_anchor_box_for_gt_box = np.zeros((num_gt_boxes, 4)) best_anchor_idx_for_gt_box = np.zeros((num_gt_boxes, 3)) num_anchors_for_gt_box = np.zeros((num_gt_boxes, )) neg_anchor_idx_for_gt_box = np.zeros((num_gt_boxes, ), dtype='int32') x1_anc_list = [] y1_anc_list = [] for ka, (anchor_w, anchor_h) in enumerate(self.anchor_wh): for ix in range(self.output_width): x1_anc = self.downscale * (ix + 0.5) - anchor_w / 2 x1_anc_list.append(x1_anc) x2_anc = x1_anc + anchor_w if x1_anc < 0 or x2_anc > self.resized_width: continue for jy in range(self.output_height): y1_anc = self.downscale * (jy + 0.5) - anchor_h / 2 y1_anc_list.append(y1_anc) y2_anc = y1_anc + anchor_h # ignore boxes that go across image boundaries if y1_anc < 0 or y2_anc > self.resized_height: continue anchor_box = [x1_anc, y1_anc, x2_anc, y2_anc] #if jy == 9 and ix == 40 and ka == 0 : # print('check') best_iou = 0.0 best_gt_box_idx = -1 best_gt_box = None for gt_box_idx, gt_box in enumerate(gt_boxes): cur_iou = iou(gt_box, anchor_box) if cur_iou > best_iou: best_iou = cur_iou best_gt_box_idx = gt_box_idx best_gt_box = gt_box if cur_iou > best_iou_for_gt_box[gt_box_idx]: best_iou_for_gt_box[gt_box_idx] = cur_iou best_anchor_idx_for_gt_box[gt_box_idx] = [ jy, ix, ka ] best_anchor_box_for_gt_box[gt_box_idx] = anchor_box if best_iou > self.rpn_max_overlap: pos_anchor_idx = np.append(pos_anchor_idx, [[jy, ix, ka]], 0) pos_anchor_box = np.append(pos_anchor_box, [anchor_box], 0) pos_gt_box = np.append(pos_gt_box, [best_gt_box], 0) num_anchors_for_gt_box[best_gt_box_idx] += 1 elif best_iou < self.rpn_min_overlap: if np.array_equal( best_anchor_idx_for_gt_box[best_gt_box_idx], [jy, ix, ka]): neg_anchor_idx_for_gt_box[best_gt_box_idx] = len( neg_anchor_idx) neg_anchor_idx = np.append(neg_anchor_idx, [[jy, ix, ka]], 0) not_covered_gt_box_idx = np.where(num_anchors_for_gt_box == 0) additional_pos_anchor_idx, additional_pos_anchor_box, additional_pos_gt_box, neg_anchor_idx_to_remove = map( lambda a: a[not_covered_gt_box_idx], [ best_anchor_idx_for_gt_box, best_anchor_box_for_gt_box, gt_boxes, neg_anchor_idx_for_gt_box ]) pos_anchor_idx = np.append(pos_anchor_idx, additional_pos_anchor_idx.reshape(-1, 3), 0) pos_anchor_box = np.append(pos_anchor_box, additional_pos_anchor_box.reshape(-1, 4), 0) pos_gt_box = np.append(pos_gt_box, additional_pos_gt_box.reshape(-1, 4), 0) neg_anchor_idx = np.delete(neg_anchor_idx, neg_anchor_idx_for_gt_box, 0) return pos_anchor_idx, neg_anchor_idx, pos_anchor_box, pos_gt_box