Exemple #1
0
def test_check1():
    """Test check without arguments"""
    bounding_boxes, confidences, labels, _ = setup_test_case()

    bb = BoundingBoxArray(bounding_boxes=bounding_boxes,
                          confidences=confidences,
                          labels=labels)

    bb.check()
Exemple #2
0
def smoke_test_setup():
    bounding_boxes, confidences, labels, _ = setup_test_case()
    bb = BoundingBoxArray(bounding_boxes=bounding_boxes,
                          confidences=confidences,
                          labels=labels)
    bb.check()

    metric = DefaultIntersectionOverTheUnion(threshold=0.35, direction="lt")
    selector = RandomSelector()
    return bb, metric, selector
Exemple #3
0
def test_check2():
    """Test check with arguments"""
    bounding_boxes, confidences, labels, _ = setup_test_case()
    bounding_box, confidence, label = one_additional()

    bb = BoundingBoxArray(bounding_boxes=bounding_boxes,
                          confidences=confidences,
                          labels=labels)

    bb.check(bounding_box=bounding_box, confidence=confidence, label=label)
Exemple #4
0
def test_check7():
    """Test check without arguments - fail bb range"""
    bounding_boxes, confidences, labels, _ = setup_test_case()
    bounding_boxes[0, 0, 0] = 1.01

    bb = BoundingBoxArray(bounding_boxes=bounding_boxes,
                          confidences=confidences,
                          labels=labels)

    with pytest.raises(ValueError):
        bb.check()
Exemple #5
0
def test_check5():
    """Test check without arguments - warn"""
    bounding_boxes, confidences, labels, _ = setup_test_case()
    labels = labels.astype(np.float64)

    bb = BoundingBoxArray(bounding_boxes=bounding_boxes,
                          confidences=confidences,
                          labels=labels)

    with pytest.warns(SyntaxWarning):
        bb.check()
Exemple #6
0
def test_check6():
    """Test check with arguments - warn"""
    bounding_boxes, confidences, labels, _ = setup_test_case()
    bounding_box, confidence, label = one_additional()
    bounding_box = bounding_box.astype(np.int64)

    bb = BoundingBoxArray(bounding_boxes=bounding_boxes,
                          confidences=confidences,
                          labels=labels)

    with pytest.warns(SyntaxWarning):
        bb.check(bounding_box=bounding_box, confidence=confidence, label=label)
Exemple #7
0
def test_append1():
    """Test append without arguments"""
    bounding_boxes, confidences, labels, _ = setup_test_case()
    before_length = bounding_boxes.shape[0]

    bounding_box, confidence, label = one_additional()

    bb = BoundingBoxArray(bounding_boxes=bounding_boxes,
                          confidences=confidences,
                          labels=labels)

    bb.append(bounding_box=bounding_box, confidence=confidence, label=label)
    assert bb.bounding_boxes.shape[0] == before_length + 1
    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 #9
0
def test_check9():
    """Test check without arguments - fail bb shape len"""
    bounding_boxes, confidences, labels, _ = setup_test_case()
    bounding_boxes = np.array(
        (
            ((0.04, 0.19, 0.12), (0.14, 0.29, 0.81)),
            ((0.11, 0.15, 0.02), (0.21, 0.25, 0.14)),
        ),
        dtype=np.float64,
    )

    bb = BoundingBoxArray(bounding_boxes=bounding_boxes,
                          confidences=confidences,
                          labels=labels)

    with pytest.raises(ValueError):
        bb.check()
Exemple #10
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)))
    def _handle_boundaries(
        self,
        bounding_box_array: BoundingBoxArray,
        dividing_lines: List[Tuple[int, bool]],
    ) -> Optional[BoundingBoxArray]:
        """Finds all boxes overlapping boundaries. Performs selection on those boxes and any overlapping boxes.

        Args:
            bounding_box_array: The payload of the boxes, confidences, and labels.
            dividing_lines: The dividing_lines of each sector as determined by _create_sectors().

        Returns:
            selected_bids: The bids (box ids) selected by the selection algorithm.
            bounding_boxes: The original bounding boxes less any bounding boxes that were evaluated for selection.
            confidences: The original confidences less any confidences that were evaluated for selection.
        """
        assert bounding_box_array.bounding_boxes.shape[0] == bounding_box_array.bounding_box_ids.shape[0]
        on_boundary = np.full(
            bounding_box_array.bounding_boxes.shape[0], False, np.bool
        )
        all_bids = np.arange(0, bounding_box_array.bounding_boxes.shape[0])
        for bid in all_bids:
            for line, divide_on_height in dividing_lines:
                if (
                    divide_on_height
                    and bounding_box_array.bounding_boxes[bid, 0, 0]
                    < line
                    < bounding_box_array.bounding_boxes[bid, 1, 0]
                ):
                    on_boundary[bid] = True
                    break
                elif (
                    not divide_on_height
                    and bounding_box_array.bounding_boxes[bid, 0, 1]
                    < line
                    < bounding_box_array.bounding_boxes[bid, 1, 1]
                ):
                    on_boundary[bid] = True
                    break

        boundary_bids = all_bids[on_boundary]
        if len(boundary_bids) == 0:
            return None
        assert len(bounding_box_array) > 0

        all_bids += np.min(bounding_box_array.bounding_box_ids)

        for bid1 in all_bids[on_boundary]:
            for bid2 in all_bids[on_boundary]:
                if bid1 == bid2:
                    continue

        prod = itertools.product(all_bids[on_boundary], all_bids)
        selected_bids, evaluated_bids = self._evaluate_overlap(bounding_box_array, prod)
        evaluated_bids = np.asarray(list(evaluated_bids), dtype=np.int64)
        evaluated_bids_inv = np.ones(
            bounding_box_array.bounding_boxes.shape[0], np.bool
        )

        evaluated_bids_inv_ixs = [bounding_box_array.bounding_box_id_to_ix(x) for x in evaluated_bids]
        evaluated_bids_inv[evaluated_bids_inv_ixs] = 0

        return bounding_box_array[np.asarray(selected_bids, dtype=np.int64)]