def _compute_is_aclass_correctly_detected_in_image(self, detected_boxes, detected_scores, groundtruth_boxes): """Compute CorLoc score for a single class. Args: detected_boxes: A numpy array of shape [N, 4] representing detected box coordinates detected_scores: A 1-d numpy array of length N representing classification score groundtruth_boxes: A numpy array of shape [M, 4] representing ground truth box coordinates Returns: is_class_correctly_detected_in_image: An integer 1 or 0 denoting whether a class is correctly detected in the image or not """ if detected_boxes.size > 0: if groundtruth_boxes.size > 0: max_score_id = np.argmax(detected_scores) detected_boxlist = np_box_list.BoxList( np.expand_dims(detected_boxes[max_score_id, :], axis=0)) gt_boxlist = np_box_list.BoxList(groundtruth_boxes) iou = np_box_list_ops.iou(detected_boxlist, gt_boxlist) if np.max(iou) >= self.matching_iou_threshold: return 1 return 0
def _get_overlaps_and_scores_relation_tuples(self, detected_box_tuples, groundtruth_box_tuples): """Computes overlaps and scores between detected and groundtruth tuples. Both detections and groundtruth boxes have the same class tuples. Args: detected_box_tuples: A numpy array of structures with shape [N,], representing N tuples, each tuple containing the same number of named bounding boxes. Each box is of the format [y_min, x_min, y_max, x_max] groundtruth_box_tuples: A float numpy array of structures with the shape [M,], representing M tuples, each tuple containing the same number of named bounding boxes. Each box is of the format [y_min, x_min, y_max, x_max] Returns: result_iou: A float numpy array of size [num_detected_tuples, num_gt_box_tuples]. """ result_iou = np.ones( (detected_box_tuples.shape[0], groundtruth_box_tuples.shape[0]), dtype=float) for field in detected_box_tuples.dtype.fields: detected_boxlist_field = np_box_list.BoxList( detected_box_tuples[field]) gt_boxlist_field = np_box_list.BoxList( groundtruth_box_tuples[field]) iou_field = np_box_list_ops.iou(detected_boxlist_field, gt_boxlist_field) result_iou = np.minimum(iou_field, result_iou) return result_iou
def _compute_tp_fp_for_single_class(self, detected_boxes, detected_scores, groundtruth_boxes, groundtruth_is_difficult_list): """Labels boxes detected with the same class from the same image as tp/fp. Args: detected_boxes: A numpy array of shape [N, 4] representing detected box coordinates detected_scores: A 1-d numpy array of length N representing classification score groundtruth_boxes: A numpy array of shape [M, 4] representing ground truth box coordinates groundtruth_is_difficult_list: A boolean numpy array of length M denoting whether a ground truth box is a difficult instance or not Returns: scores: A numpy array representing the detection scores tp_fp_labels: a boolean numpy array indicating whether a detection is a true positive. """ if groundtruth_boxes.size == 0: is_gt_box_detected = np.array([], dtype=bool) else: is_gt_box_detected = np.zeros(groundtruth_boxes.shape[0], dtype=bool) if detected_boxes.size == 0: return np.array([], dtype=float), np.array( [], dtype=bool), is_gt_box_detected detected_boxlist = np_box_list.BoxList(detected_boxes) detected_boxlist.add_field('scores', detected_scores) detected_boxlist = np_box_list_ops.non_max_suppression( detected_boxlist, self.nms_max_output_boxes, self.nms_iou_threshold) scores = detected_boxlist.get_field('scores') if groundtruth_boxes.size == 0: return scores, np.zeros(detected_boxlist.num_boxes(), dtype=bool), is_gt_box_detected gt_boxlist = np_box_list.BoxList(groundtruth_boxes) iou = np_box_list_ops.iou(detected_boxlist, gt_boxlist) max_overlap_gt_ids = np.argmax(iou, axis=1) tp_fp_labels = np.zeros(detected_boxlist.num_boxes(), dtype=bool) is_matched_to_difficult_box = np.zeros(detected_boxlist.num_boxes(), dtype=bool) for i in range(detected_boxlist.num_boxes()): gt_id = max_overlap_gt_ids[i] if iou[i, gt_id] >= self.matching_iou_threshold: if not groundtruth_is_difficult_list[gt_id]: if not is_gt_box_detected[gt_id]: tp_fp_labels[i] = True is_gt_box_detected[gt_id] = True else: is_matched_to_difficult_box[i] = True return scores[~is_matched_to_difficult_box], tp_fp_labels[ ~is_matched_to_difficult_box], is_gt_box_detected
def _compute_is_class_correctly_detected_in_image(self, detected_boxes, detected_scores, groundtruth_boxes, detected_masks=None, groundtruth_masks=None): """Compute CorLoc score for a single class. Args: detected_boxes: A numpy array of shape [N, 4] representing detected box coordinates detected_scores: A 1-d numpy array of length N representing classification score groundtruth_boxes: A numpy array of shape [M, 4] representing ground truth box coordinates detected_masks: (optional) A np.uint8 numpy array of shape [N, height, width]. If not None, the scores will be computed based on masks. groundtruth_masks: (optional) A np.uint8 numpy array of shape [M, height, width]. Returns: is_class_correctly_detected_in_image: An integer 1 or 0 denoting whether a class is correctly detected in the image or not """ if detected_boxes.size > 0: if groundtruth_boxes.size > 0: max_score_id = np.argmax(detected_scores) mask_mode = False if detected_masks is not None and groundtruth_masks is not None: mask_mode = True if mask_mode: detected_boxlist = np_box_mask_list.BoxMaskList( box_data=np.expand_dims(detected_boxes[max_score_id], axis=0), mask_data=np.expand_dims(detected_masks[max_score_id], axis=0)) gt_boxlist = np_box_mask_list.BoxMaskList( box_data=groundtruth_boxes, mask_data=groundtruth_masks) iou = np_box_mask_list_ops.iou(detected_boxlist, gt_boxlist) else: detected_boxlist = np_box_list.BoxList( np.expand_dims(detected_boxes[max_score_id, :], axis=0)) gt_boxlist = np_box_list.BoxList(groundtruth_boxes) iou = np_box_list_ops.iou(detected_boxlist, gt_boxlist) if np.max(iou) >= self.matching_iou_threshold: return 1 return 0
def _get_overlaps_and_scores_box_mode(self, detected_boxes, detected_scores, groundtruth_boxes, groundtruth_is_group_of_list): """Computes overlaps and scores between detected and groudntruth boxes. Args: detected_boxes: A numpy array of shape [N, 4] representing detected box coordinates detected_scores: A 1-d numpy array of length N representing classification score groundtruth_boxes: A numpy array of shape [M, 4] representing ground truth box coordinates groundtruth_is_group_of_list: A boolean numpy array of length M denoting whether a ground truth box has group-of tag. If a groundtruth box is group-of box, every detection matching this box is ignored. Returns: iou: A float numpy array of size [num_detected_boxes, num_gt_boxes]. If gt_non_group_of_boxlist.num_boxes() == 0 it will be None. ioa: A float numpy array of size [num_detected_boxes, num_gt_boxes]. If gt_group_of_boxlist.num_boxes() == 0 it will be None. scores: The score of the detected boxlist. num_boxes: Number of non-maximum suppressed detected boxes. """ detected_boxlist = np_box_list.BoxList(detected_boxes) detected_boxlist.add_field('scores', detected_scores) detected_boxlist = np_box_list_ops.non_max_suppression( detected_boxlist, self.nms_max_output_boxes, self.nms_iou_threshold) gt_non_group_of_boxlist = np_box_list.BoxList( groundtruth_boxes[~groundtruth_is_group_of_list]) gt_group_of_boxlist = np_box_list.BoxList( groundtruth_boxes[groundtruth_is_group_of_list]) iou = np_box_list_ops.iou(detected_boxlist, gt_non_group_of_boxlist) ioa = np.transpose( np_box_list_ops.ioa(gt_group_of_boxlist, detected_boxlist)) scores = detected_boxlist.get_field('scores') num_boxes = detected_boxlist.num_boxes() return iou, ioa, scores, num_boxes
def test_iou(self): iou = np_box_list_ops.iou(self.boxlist1, self.boxlist2) expected_iou = np.array( [[2.0 / 16.0, 0.0, 6.0 / 400.0], [1.0 / 16.0, 0.0, 5.0 / 400.0]], dtype=float) self.assertAllClose(iou, expected_iou)