OverlapFilter: Add and validate docs, rename

This commit is contained in:
Linas Kondrackis 2024-05-30 13:45:12 +03:00
parent 34353aac54
commit f7bd7011fe
9 changed files with 57 additions and 55 deletions

View File

@ -0,0 +1,30 @@
---
comments: true
status: new
---
# Double Detection Filter
<div class="md-typeset">
<h2><a href="#supervision.detection.overlap_filter.OverlapFilter">OverlapFilter</a></h2>
</div>
:::supervision.detection.overlap_filter.OverlapFilter
<div class="md-typeset">
<h2><a href="#supervision.detection.overlap_filter.box_non_max_suppression">box_non_max_suppression</a></h2>
</div>
:::supervision.detection.overlap_filter.box_non_max_suppression
<div class="md-typeset">
<h2><a href="#supervision.detection.overlap_filter.mask_non_max_suppression">mask_non_max_suppression</a></h2>
</div>
:::supervision.detection.overlap_filter.mask_non_max_suppression
<div class="md-typeset">
<h2><a href="#supervision.detection.overlap_filter.box_non_max_merge">box_non_max_merge</a></h2>
</div>
:::supervision.detection.overlap_filter.box_non_max_merge

View File

@ -5,7 +5,3 @@ comments: true
# InferenceSlicer
:::supervision.detection.tools.inference_slicer.InferenceSlicer
# Overlap Handling Strategy
:::supervision.detection.overlap_handling.OverlapHandlingStrategy

View File

@ -17,24 +17,6 @@ status: new
:::supervision.detection.utils.mask_iou_batch
<div class="md-typeset">
<h2><a href="#supervision.detection.overlap_handling.box_non_max_suppression">box_non_max_suppression</a></h2>
</div>
:::supervision.detection.overlap_handling.box_non_max_suppression
<div class="md-typeset">
<h2><a href="#supervision.detection.overlap_handling.mask_non_max_suppression">mask_non_max_suppression</a></h2>
</div>
:::supervision.detection.overlap_handling.mask_non_max_suppression
<div class="md-typeset">
<h2><a href="#supervision.detection.overlap_handling.box_non_max_merge">box_non_max_merge</a></h2>
</div>
:::supervision.detection.overlap_handling.box_non_max_merge
<div class="md-typeset">
<h2><a href="#supervision.detection.utils.polygon_to_mask">polygon_to_mask</a></h2>
</div>

View File

@ -48,6 +48,7 @@ nav:
- Core: detection/core.md
- Annotators: detection/annotators.md
- Metrics: detection/metrics.md
- Double Detection Filter: detection/double_detection_filter.md
- Utils: detection/utils.md
- Keypoint Detection:
- Core: keypoint/core.md

View File

@ -40,8 +40,8 @@ from supervision.detection.annotate import BoxAnnotator
from supervision.detection.core import Detections
from supervision.detection.line_zone import LineZone, LineZoneAnnotator
from supervision.detection.lmm import LMM
from supervision.detection.overlap_handling import (
OverlapHandlingStrategy,
from supervision.detection.overlap_filter import (
OverlapFilter,
box_non_max_merge,
box_non_max_suppression,
mask_non_max_suppression,

View File

@ -8,7 +8,7 @@ import numpy as np
from supervision.config import CLASS_NAME_DATA_FIELD, ORIENTED_BOX_COORDINATES
from supervision.detection.lmm import LMM, from_paligemma, validate_lmm_and_kwargs
from supervision.detection.overlap_handling import (
from supervision.detection.overlap_filter import (
box_non_max_merge,
box_non_max_suppression,
mask_non_max_suppression,

View File

@ -230,7 +230,7 @@ def box_non_max_merge(
return merge_groups
class OverlapHandlingStrategy(Enum):
class OverlapFilter(Enum):
"""
Enum specifying the strategy for filtering overlapping detections.
@ -239,11 +239,9 @@ class OverlapHandlingStrategy(Enum):
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,
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.
![overlap-handling-strategies-example](https://media.roboflow.com/supervision-docs/overlap-handling-strategies-example.png)
"""
NONE = "none"
@ -251,15 +249,15 @@ class OverlapHandlingStrategy(Enum):
NON_MAX_MERGE = "non_max_merge"
def validate_overlapping_handling_strategy(
strategy: Union[OverlapHandlingStrategy, str],
) -> OverlapHandlingStrategy:
def validate_overlap_filter(
strategy: Union[OverlapFilter, str],
) -> OverlapFilter:
if isinstance(strategy, str):
try:
strategy = OverlapHandlingStrategy(strategy.lower())
strategy = OverlapFilter(strategy.lower())
except ValueError:
raise ValueError(
f"Invalid strategy value: {strategy}. Must be one of "
f"{[e.value for e in OverlapHandlingStrategy]}"
f"{[e.value for e in OverlapFilter]}"
)
return strategy

View File

@ -5,10 +5,7 @@ from typing import Callable, Optional, Tuple, Union
import numpy as np
from supervision.detection.core import Detections
from supervision.detection.overlap_handling import (
OverlapHandlingStrategy,
validate_overlapping_handling_strategy,
)
from supervision.detection.overlap_filter import OverlapFilter, validate_overlap_filter
from supervision.detection.utils import move_boxes, move_masks
from supervision.utils.image import crop_image
from supervision.utils.internal import SupervisionWarnings
@ -56,7 +53,7 @@ class InferenceSlicer:
`(width, height)`.
overlap_ratio_wh (Tuple[float, float]): Overlap ratio between consecutive
slices in the format `(width_ratio, height_ratio)`.
overlap_handling_strategy (Union[OverlapHandlingStrategy, str]): Strategy for
overlap_filter_strategy (Union[OverlapFilter, str]): Strategy for
filtering or merging overlapping detections in slices.
iou_threshold (float): Intersection over Union (IoU) threshold
used when filtering by overlap.
@ -76,20 +73,18 @@ 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_handling_strategy: Union[
OverlapHandlingStrategy, str
] = OverlapHandlingStrategy.NON_MAX_SUPPRESSION,
overlap_filter_strategy: Union[
OverlapFilter, str
] = OverlapFilter.NON_MAX_SUPPRESSION,
iou_threshold: float = 0.5,
thread_workers: int = 1,
):
overlap_handling_strategy = validate_overlapping_handling_strategy(
overlap_handling_strategy
)
overlap_filter_strategy = validate_overlap_filter(overlap_filter_strategy)
self.slice_wh = slice_wh
self.overlap_ratio_wh = overlap_ratio_wh
self.iou_threshold = iou_threshold
self.overlap_handling_strategy = overlap_handling_strategy
self.overlap_filter_strategy = overlap_filter_strategy
self.callback = callback
self.thread_workers = thread_workers
@ -120,7 +115,10 @@ class InferenceSlicer:
result = model(image_slice)[0]
return sv.Detections.from_ultralytics(result)
slicer = sv.InferenceSlicer(callback = callback)
slicer = sv.InferenceSlicer(
callback=callback,
overlap_filter_strategy=sv.OverlapFilter.NON_MAX_SUPPRESSION,
)
detections = slicer(image)
```
@ -141,18 +139,15 @@ class InferenceSlicer:
detections_list.append(future.result())
merged = Detections.merge(detections_list=detections_list)
if self.overlap_handling_strategy == OverlapHandlingStrategy.NONE:
if self.overlap_filter_strategy == OverlapFilter.NONE:
return merged
elif (
self.overlap_handling_strategy
== OverlapHandlingStrategy.NON_MAX_SUPPRESSION
):
elif self.overlap_filter_strategy == OverlapFilter.NON_MAX_SUPPRESSION:
return merged.with_nms(threshold=self.iou_threshold)
elif self.overlap_handling_strategy == OverlapHandlingStrategy.NON_MAX_MERGE:
elif self.overlap_filter_strategy == OverlapFilter.NON_MAX_MERGE:
return merged.with_nmm(threshold=self.iou_threshold)
else:
warnings.warn(
f"Invalid overlap filter strategy: {self.overlap_handling_strategy}",
f"Invalid overlap filter strategy: {self.overlap_filter_strategy}",
category=SupervisionWarnings,
)
return merged

View File

@ -4,7 +4,7 @@ from typing import List, Optional
import numpy as np
import pytest
from supervision.detection.overlap_handling import (
from supervision.detection.overlap_filter import (
box_non_max_suppression,
group_overlapping_boxes,
mask_non_max_suppression,