Select overlap filtering strategy

This commit is contained in:
Linas Kondrackis committed 2024-05-28 09:52:46 +03:00
1 parent 9bc2907c49
commit f0e88b1982
3 files changed
+37 -7

No files matched your search

+1
View File
@@ -46,6 +46,7 @@ from supervision.detection.tools.json_sink import JSONSink
from supervision.detection.tools.polygon_zone import PolygonZone, PolygonZoneAnnotator
from supervision.detection.tools.smoother import DetectionsSmoother
from supervision.detection.utils import (
OverlapFilter,
box_iou_batch,
box_non_max_merge,
box_non_max_suppression,
@@ -1,10 +1,11 @@
import warnings
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import Callable, Optional, Tuple
import numpy as np
from supervision.detection.core import Detections
from supervision.detection.utils import move_boxes, move_masks
from supervision.detection.utils import OverlapFilter, move_boxes, move_masks
from supervision.utils.image import crop_image
@@ -50,8 +51,10 @@ class InferenceSlicer:
`(width, height)`.
overlap_ratio_wh (Tuple[float, float]): Overlap ratio between consecutive
slices in the format `(width_ratio, height_ratio)`.
iou_threshold (Optional[float]): Intersection over Union (IoU) threshold
used for non-max suppression.
overlap_filter (OverlapFilter): Strategy for
filtering or merging overlapping detections in slices.
iou_threshold (float): Intersection over Union (IoU) threshold
used when filtering by overlap.
callback (Callable): A function that performs inference on a given image
slice and returns detections.
thread_workers (int): Number of threads for parallel execution.
@@ -68,12 +71,14 @@ class InferenceSlicer:
callback: Callable[[np.ndarray], Detections],
slice_wh: Tuple[int, int] = (320, 320),
overlap_ratio_wh: Tuple[float, float] = (0.2, 0.2),
iou_threshold: Optional[float] = 0.5,
overlap_filter: OverlapFilter = OverlapFilter.NON_MAX_SUPPRESSION,
iou_threshold: float = 0.5,
thread_workers: int = 1,
):
self.slice_wh = slice_wh
self.overlap_ratio_wh = overlap_ratio_wh
self.iou_threshold = iou_threshold
self.overlap_filter = overlap_filter
self.callback = callback
self.thread_workers = thread_workers
@@ -124,9 +129,16 @@ class InferenceSlicer:
for future in as_completed(futures):
detections_list.append(future.result())
return Detections.merge(detections_list=detections_list).with_nms(
threshold=self.iou_threshold
)
merged = Detections.merge(detections_list=detections_list)
if self.overlap_filter == OverlapFilter.NONE:
return merged
elif self.overlap_filter == OverlapFilter.NON_MAX_SUPPRESSION:
return merged.with_nms(threshold=self.iou_threshold)
elif self.overlap_filter == OverlapFilter.NON_MAX_MERGE:
return merged.with_nmm(threshold=self.iou_threshold)
else:
warnings.warn(f"Invalid overlap filter strategy: {self.overlap_filter}")
return merged
def _run_callback(self, image, offset) -> Detections:
"""
+17
View File
@@ -1,3 +1,4 @@
from enum import Enum
from itertools import chain
from typing import Dict, List, Optional, Tuple, Union
@@ -1056,3 +1057,19 @@ def contains_multiple_segments(
mask_uint8, labels, connectivity=connectivity
)
return number_of_labels > 2
class OverlapFilter(Enum):
"""
Enum specifying the strategy for filtering overlapping detections.
Attributes:
NONE: Do not filter detections based on overlap.
NON_MAX_SUPPRESSION: Filter detections using non-max suppression.
NON_MAX_MERGE: Merge detections with non-max-merging instead of
discarding them.
"""
NONE = "none"
NON_MAX_SUPPRESSION = "non_max_suppression"
NON_MAX_MERGE = "non_max_merge"