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
Exemple #2
0
    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)))