refactor(inference_slicer): Update class and method docstrings

This commit is contained in:
SkalskiP 2023-08-30 15:56:15 +02:00
parent 07c4472eac
commit bddd32dbb5
8 changed files with 80 additions and 16 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,3 @@
## InferenceSlicer
:::supervision.detection.tools.inference_slicer.InferenceSlicer

View File

@ -1,3 +0,0 @@
## InferenceSlicer
:::supervision.detection.tools.slicer.InferenceSlicer

View File

@ -4,4 +4,4 @@
## crop
:::supervision.utils.image.crop
:::supervision.utils.image.crop_image

View File

@ -37,6 +37,7 @@ nav:
- Utils: detection/utils.md
- Tools:
- Polygon Zone: detection/tools/polygon_zone.md
- Inference Slicer: detection/tools/inference_slicer.md
- Trackers:
- Core: tracker/core.md
- Dataset:

View File

@ -16,8 +16,8 @@ from supervision.dataset.core import (
from supervision.detection.annotate import BoxAnnotator, MaskAnnotator
from supervision.detection.core import Detections
from supervision.detection.line_counter import LineZone, LineZoneAnnotator
from supervision.detection.tools.inference_slicer import InferenceSlicer
from supervision.detection.tools.polygon_zone import PolygonZone, PolygonZoneAnnotator
from supervision.detection.tools.slicer import InferenceSlicer
from supervision.detection.utils import (
box_iou_batch,
filter_polygons_by_area,

View File

@ -11,7 +11,8 @@ def move_detections(detections: Detections, offset: np.array) -> Detections:
"""
Args:
detections (sv.Detections): Detections object to be moved.
offset (np.array): An array of shape `(2,)` containing offset values in format is `[dx, dy]`.
offset (np.array): An array of shape `(2,)` containing offset values in format
is `[dx, dy]`.
Returns:
(sv.Detections) repositioned Detections object.
"""
@ -21,7 +22,26 @@ def move_detections(detections: Detections, offset: np.array) -> Detections:
class InferenceSlicer:
"""
Slicing inference(SAHI) method for small target detection.
InferenceSlicer performs slicing-based inference for small target detection. This
method, often referred to as Slicing Adaptive Inference (SAHI), involves dividing a
larger image into smaller slices, performing inference on each slice, and then
merging the detections.
Attributes:
slice_wh (Tuple[int, int]): Dimensions of each slice in the format
`(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.
callback (Callable): A function that performs inference on a given image slice
and returns detections.
Note:
The class ensures that slices do not exceed the boundaries of the original
image. As a result, the final slices in the row and column dimensions might be
smaller than the specified slice dimensions if the image's width or height is
not a multiple of the slice's width or height minus the overlap.
"""
def __init__(
@ -38,6 +58,37 @@ class InferenceSlicer:
validate_inference_callback(callback=callback)
def __call__(self, image: np.ndarray) -> Detections:
"""
Performs slicing-based inference on the provided image using the specified
callback.
Args:
image (np.ndarray): The input image on which inference needs to be
performed. The image should be in the format
`(height, width, channels)`.
Returns:
Detections: A collection of detections for the entire image after merging
results from all slices and applying NMS.
Example:
```python
>>> import cv2
>>> import supervision as sv
>>> from ultralytics import YOLO
>>> image = cv2.imread(SOURCE_IMAGE_PATH)
>>> model = YOLO(...)
>>> def callback(image_slice: np.ndarray) -> sv.Detections:
... result = model(image_slice)[0]
... return sv.Detections.from_ultralytics(result)
>>> slicer = sv.InferenceSlicer(callback = callback)
>>> detections = slicer(image)
```
"""
detections_list = []
resolution_wh = (image.shape[1], image.shape[0])
offsets = self._generate_offset(
@ -62,18 +113,29 @@ class InferenceSlicer:
overlap_ratio_wh: Tuple[float, float],
) -> np.ndarray:
"""
Generate offset coordinates for slicing an image based on the given resolution, slice dimensions, and overlap ratios.
Generate offset coordinates for slicing an image based on the given resolution,
slice dimensions, and overlap ratios.
Args:
resolution_wh (Tuple[int, int]): A tuple representing the width and height of the image to be sliced.
slice_wh (Tuple[int, int]): A tuple representing the desired width and height of each slice.
overlap_ratio_wh (Tuple[float, float]): A tuple representing the desired overlap ratio for width and height between consecutive slices. Each value should be in the range [0, 1), where 0 means no overlap and a value close to 1 means high overlap.
resolution_wh (Tuple[int, int]): A tuple representing the width and height
of the image to be sliced.
slice_wh (Tuple[int, int]): A tuple representing the desired width and
height of each slice.
overlap_ratio_wh (Tuple[float, float]): A tuple representing the desired
overlap ratio for width and height between consecutive slices. Each
value should be in the range [0, 1), where 0 means no overlap and a
value close to 1 means high overlap.
Returns:
np.ndarray: An array of shape `(n, 4)` containing coordinates for each slice in the format `[xmin, ymin, xmax, ymax]`.
np.ndarray: An array of shape `(n, 4)` containing coordinates for each
slice in the format `[xmin, ymin, xmax, ymax]`.
Note:
The function ensures that slices do not exceed the boundaries of the original image. As a result, the final slices in the row and column dimensions might be smaller than the specified slice dimensions if the image's width or height is not a multiple of the slice's width or height minus the overlap.
The function ensures that slices do not exceed the boundaries of the
original image. As a result, the final slices in the row and column
dimensions might be smaller than the specified slice dimensions if the
image's width or height is not a multiple of the slice's width or
height minus the overlap.
"""
slice_width, slice_height = slice_wh
image_width, image_height = resolution_wh

View File

@ -380,9 +380,10 @@ def process_roboflow_result(
def move_boxes(xyxy: np.ndarray, offset: np.ndarray) -> np.ndarray:
"""
Args:
xyxy (np.ndarray): An array of shape `(n, 4)` containing the bounding boxes coordinates in format
`[x1, y1, x2, y2]`
offset (np.array): An array of shape `(2,)` containing offset values in format is `[dx, dy]`.
xyxy (np.ndarray): An array of shape `(n, 4)` containing the bounding boxes
coordinates in format `[x1, y1, x2, y2]`
offset (np.array): An array of shape `(2,)` containing offset values in format
is `[dx, dy]`.
Returns:
(np.ndarray) repositioned bounding boxes