Renamed overlap strategy, added into InferenceSlicer docs page
This commit is contained in:
parent
f0e88b1982
commit
4dc001d9bf
|
|
@ -5,3 +5,7 @@ comments: true
|
|||
# InferenceSlicer
|
||||
|
||||
:::supervision.detection.tools.inference_slicer.InferenceSlicer
|
||||
|
||||
# Overlap Handling Strategy
|
||||
|
||||
:::supervision.detection.utils.OverlapHandlingStrategy
|
||||
|
|
|
|||
|
|
@ -46,7 +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,
|
||||
OverlapHandlingStrategy,
|
||||
box_iou_batch,
|
||||
box_non_max_merge,
|
||||
box_non_max_suppression,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
import warnings
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from typing import Callable, Optional, Tuple
|
||||
from typing import Callable, Optional, Tuple, Union
|
||||
|
||||
import numpy as np
|
||||
|
||||
from supervision.detection.core import Detections
|
||||
from supervision.detection.utils import OverlapFilter, move_boxes, move_masks
|
||||
from supervision.detection.utils import (
|
||||
OverlapHandlingStrategy,
|
||||
move_boxes,
|
||||
move_masks,
|
||||
validate_overlapping_handling_strategy,
|
||||
)
|
||||
from supervision.utils.image import crop_image
|
||||
from supervision.utils.internal import SupervisionWarnings
|
||||
|
||||
|
||||
def move_detections(
|
||||
|
|
@ -51,7 +57,7 @@ class InferenceSlicer:
|
|||
`(width, height)`.
|
||||
overlap_ratio_wh (Tuple[float, float]): Overlap ratio between consecutive
|
||||
slices in the format `(width_ratio, height_ratio)`.
|
||||
overlap_filter (OverlapFilter): Strategy for
|
||||
overlap_handling_strategy (Union[OverlapHandlingStrategy, str]): Strategy for
|
||||
filtering or merging overlapping detections in slices.
|
||||
iou_threshold (float): Intersection over Union (IoU) threshold
|
||||
used when filtering by overlap.
|
||||
|
|
@ -71,14 +77,20 @@ class InferenceSlicer:
|
|||
callback: Callable[[np.ndarray], Detections],
|
||||
slice_wh: Tuple[int, int] = (320, 320),
|
||||
overlap_ratio_wh: Tuple[float, float] = (0.2, 0.2),
|
||||
overlap_filter: OverlapFilter = OverlapFilter.NON_MAX_SUPPRESSION,
|
||||
overlap_handling_strategy: Union[
|
||||
OverlapHandlingStrategy, str
|
||||
] = OverlapHandlingStrategy.NON_MAX_SUPPRESSION,
|
||||
iou_threshold: float = 0.5,
|
||||
thread_workers: int = 1,
|
||||
):
|
||||
overlap_handling_strategy = validate_overlapping_handling_strategy(
|
||||
overlap_handling_strategy
|
||||
)
|
||||
|
||||
self.slice_wh = slice_wh
|
||||
self.overlap_ratio_wh = overlap_ratio_wh
|
||||
self.iou_threshold = iou_threshold
|
||||
self.overlap_filter = overlap_filter
|
||||
self.overlap_handling_strategy = overlap_handling_strategy
|
||||
self.callback = callback
|
||||
self.thread_workers = thread_workers
|
||||
|
||||
|
|
@ -130,14 +142,20 @@ class InferenceSlicer:
|
|||
detections_list.append(future.result())
|
||||
|
||||
merged = Detections.merge(detections_list=detections_list)
|
||||
if self.overlap_filter == OverlapFilter.NONE:
|
||||
if self.overlap_handling_strategy == OverlapHandlingStrategy.NONE:
|
||||
return merged
|
||||
elif self.overlap_filter == OverlapFilter.NON_MAX_SUPPRESSION:
|
||||
elif (
|
||||
self.overlap_handling_strategy
|
||||
== OverlapHandlingStrategy.NON_MAX_SUPPRESSION
|
||||
):
|
||||
return merged.with_nms(threshold=self.iou_threshold)
|
||||
elif self.overlap_filter == OverlapFilter.NON_MAX_MERGE:
|
||||
elif self.overlap_handling_strategy == OverlapHandlingStrategy.NON_MAX_MERGE:
|
||||
return merged.with_nmm(threshold=self.iou_threshold)
|
||||
else:
|
||||
warnings.warn(f"Invalid overlap filter strategy: {self.overlap_filter}")
|
||||
warnings.warn(
|
||||
f"Invalid overlap filter strategy: {self.overlap_handling_strategy}",
|
||||
category=SupervisionWarnings,
|
||||
)
|
||||
return merged
|
||||
|
||||
def _run_callback(self, image, offset) -> Detections:
|
||||
|
|
|
|||
|
|
@ -1059,17 +1059,34 @@ def contains_multiple_segments(
|
|||
return number_of_labels > 2
|
||||
|
||||
|
||||
class OverlapFilter(Enum):
|
||||
class OverlapHandlingStrategy(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.
|
||||
NON_MAX_SUPPRESSION: Filter detections using non-max suppression. This means,
|
||||
detections that overlap by more than a set threshold will be discarded,
|
||||
except for the one with the highest confidence.
|
||||
NON_MAX_MERGE: Merge detections with non-max-merging. This means,
|
||||
detections that overlap by more than a set threshold will be merged
|
||||
into a single detection.
|
||||
"""
|
||||
|
||||
NONE = "none"
|
||||
NON_MAX_SUPPRESSION = "non_max_suppression"
|
||||
NON_MAX_MERGE = "non_max_merge"
|
||||
|
||||
|
||||
def validate_overlapping_handling_strategy(
|
||||
strategy: Union[OverlapHandlingStrategy, str],
|
||||
) -> OverlapHandlingStrategy:
|
||||
if isinstance(strategy, str):
|
||||
try:
|
||||
strategy = OverlapHandlingStrategy(strategy.lower())
|
||||
except ValueError:
|
||||
raise ValueError(
|
||||
f"Invalid strategy value: {strategy}. Must be one of "
|
||||
f"{[e.value for e in OverlapHandlingStrategy]}"
|
||||
)
|
||||
return strategy
|
||||
|
|
|
|||
Loading…
Reference in New Issue