def _find_all_pair_overlaps(self, bounding_box_array: BoundingBoxArray): evaluated_pairs = set() overlapping_pairs = set() for i, bid1 in enumerate(bounding_box_array.bounding_box_ids): for j, bid2 in enumerate(bounding_box_array.bounding_box_ids): if i == j: continue sorted_bid_pair = [bid1, bid2] sorted_bid_pair.sort() sorted_bid_pair = tuple(sorted_bid_pair) if sorted_bid_pair in evaluated_pairs: continue # Calculate whether two bounding boxes have an # overlap metric greater than the threshold # (e.g. if box is 0.95 and threshold is 0.90, # then the boxes overlap and store True). overlap = self.metric.overlap( bounding_box_array.lookup_box(int(bid1)), bounding_box_array.lookup_box(int(bid2)), ) if overlap: overlapping_pairs.add(sorted_bid_pair) evaluated_pairs.add(sorted_bid_pair) return overlapping_pairs
def _evaluate_overlap( self, bounding_box_array: BoundingBoxArray, bounding_box_ids: Iterator[Tuple[ Any, Any]], # TODO: Replace with nested loop instead of CP symmetric: bool = False, ) -> Tuple[List[int], Set[int]]: """For a given set of bounding boxes, this method applies cartesian product non-maximum suppression to them. Args: bounding_box_array: The payload of all bounding_boxes, confidences, and labels. bounding_box_ids: A list of bounding box pairs to evaluate. symmetric: True if bounding_box_ids is a True cartesian product (i.e. comparing each box against every other box), otherwise False. Returns: selected_bids: A list of bounding_box_ids that were selected by our non-maximum suppression selector and metric. evaluated_bids: A list of bounding_box_ids that were evaluated in selection. """ bounding_box_ids = [x for x in bounding_box_ids ] # TODO: Replace with optimized version. boundary_boudning_box_idsx = set([ b[0] for b in bounding_box_ids ]) # TODO: Replace with optimized version. all_bounding_box_idxs = set([ b[1] for b in bounding_box_ids ]) # TODO: Replace with optimized version. non_boundary_bounding_box_ids = all_bounding_box_idxs.difference( boundary_boudning_box_idsx) selected_bids = [] complementary_bids = [] evaluated_bids = set() no_overlap = np.full(bounding_box_array.bounding_boxes.shape[0], True, dtype=np.bool) last_bid = -1 empty = True for bids in bounding_box_ids: empty = False if bids[0] != last_bid and len(complementary_bids) > 0: selected_bids.append(self.selector.select(complementary_bids)) complementary_bids = [] if ((bids[1] not in evaluated_bids) and (bids[0] != bids[1]) and self.metric.overlap( bounding_box_array.lookup_box(int(bids[0])), bounding_box_array.lookup_box(int(bids[1])), )): complementary_bids.append(bids[1]) evaluated_bids.add(bids[0]) evaluated_bids.add(bids[1]) no_overlap[bounding_box_array.bounding_box_id_to_ix( bids[0])] = False no_overlap[bounding_box_array.bounding_box_id_to_ix( bids[1])] = False last_bid = bids[0] if not symmetric and len(non_boundary_bounding_box_ids) > 0: no_overlap_ixs = [ int(bounding_box_array.bounding_box_id_to_ix(x)) for x in list(non_boundary_bounding_box_ids) ] print("IXS:") print(no_overlap_ixs) no_overlap[no_overlap_ixs] = False all_bounding_box_idxs_list = list(all_bounding_box_idxs) if not empty: no_overlap_boxes = np.add( np.argwhere(no_overlap).ravel(), np.min(all_bounding_box_idxs_list)).tolist() selected_bids.extend(no_overlap_boxes) evaluated_bids.update(selected_bids) return (selected_bids, set(list(evaluated_bids)))