From 00e209744fc89e0f9a235da333bd578dd5c47d5c Mon Sep 17 00:00:00 2001 From: SkalskiP Date: Wed, 18 Oct 2023 14:42:59 +0200 Subject: [PATCH 1/2] Add documentation and improvements to "LineZone" functionality Descriptions for various attributes and functionalities have been added into LineZone class to aid developers in understanding their behaviour. Also, the trigger function was modified to return two separate boolean arrays - 'crossed_in' and 'crossed_out' to denote objects crossing the line in specific directions. Moreover, Line Zone documentation is added to the side navigation in mkdocs.yml. --- docs/detection/tools/line_zone.md | 3 ++ mkdocs.yml | 1 + supervision/detection/line_counter.py | 53 ++++++++++++++++----------- 3 files changed, 35 insertions(+), 22 deletions(-) create mode 100644 docs/detection/tools/line_zone.md diff --git a/docs/detection/tools/line_zone.md b/docs/detection/tools/line_zone.md new file mode 100644 index 00000000..3e15a00e --- /dev/null +++ b/docs/detection/tools/line_zone.md @@ -0,0 +1,3 @@ +## LineZone + +:::supervision.detection.line_counter.LineZone \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 276c85dc..f511cb2f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -39,6 +39,7 @@ nav: - Core: detection/core.md - Utils: detection/utils.md - Tools: + - Line Zone: detection/tools/line_zone.md - Polygon Zone: detection/tools/polygon_zone.md - Inference Slicer: detection/tools/inference_slicer.md - Annotators: annotators.md diff --git a/supervision/detection/line_counter.py b/supervision/detection/line_counter.py index c668354e..851d1d4a 100644 --- a/supervision/detection/line_counter.py +++ b/supervision/detection/line_counter.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional +from typing import Dict, Optional, Tuple import cv2 import numpy as np @@ -10,42 +10,54 @@ from supervision.geometry.core import Point, Rect, Vector class LineZone: """ - Count the number of objects that cross a line. + This class is responsible for counting the number of objects that cross a + predefined line. + + !!! warning + + LineZone utilizes the `tracker_id`. Read + [here](https://supervision.roboflow.com/trackers/) to learn how to plug + tracking into your inference pipeline. + + Attributes: + in_count (int): The number of objects that have crossed the line from outside + to inside. + out_count (int): The number of objects that have crossed the line from inside + to outside. """ def __init__(self, start: Point, end: Point): """ - Initialize a LineCounter object. - - Attributes: + Args: start (Point): The starting point of the line. end (Point): The ending point of the line. - """ self.vector = Vector(start=start, end=end) self.tracker_state: Dict[str, bool] = {} self.in_count: int = 0 self.out_count: int = 0 - def trigger(self, detections: Detections) -> np.ndarray: + def trigger(self, detections: Detections) -> Tuple[np.ndarray, np.ndarray]: """ - Update the in_count and out_count for the detections that cross the line. + Update the `in_count` and `out_count` based on the objects that cross the line. - Attributes: - detections (Detections): The detections for which to update the counts. + Args: + detections (Detections): A list of detections for which to update the + counts. Returns: - np.ndarray: A boolean array indicating - which detection has crossed the line on the either sides + A tuple of two boolean NumPy arrays. The first array indicates which + detections have crossed the line from outside to inside. The second + array indicates which detections have crossed the line from inside to + outside. """ - crossed = np.full(len(detections), False) + crossed_in = np.full(len(detections), False) + crossed_out = np.full(len(detections), False) for i, (xyxy, _, confidence, class_id, tracker_id) in enumerate(detections): - # handle detections with no tracker_id if tracker_id is None: continue - # we check if all four anchors of bbox are on the same side of vector x1, y1, x2, y2 = xyxy anchors = [ Point(x=x1, y=y1), @@ -55,30 +67,27 @@ class LineZone: ] triggers = [self.vector.is_in(point=anchor) for anchor in anchors] - # detection is partially in and partially out if len(set(triggers)) == 2: continue tracker_state = triggers[0] - # handle new detection + if tracker_id not in self.tracker_state: self.tracker_state[tracker_id] = tracker_state continue - # handle detection on the same side of the line if self.tracker_state.get(tracker_id) == tracker_state: continue self.tracker_state[tracker_id] = tracker_state if tracker_state: self.in_count += 1 - crossed[i] = True - + crossed_in[i] = True else: self.out_count += 1 - crossed[i] = True + crossed_out[i] = True - return crossed + return crossed_in, crossed_out class LineZoneAnnotator: From 62c45548a63bdf47165fa017fd59b36f620f5e6b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 12:44:19 +0000 Subject: [PATCH 2/2] =?UTF-8?q?fix(pre=5Fcommit):=20=F0=9F=8E=A8=20auto=20?= =?UTF-8?q?format=20pre-commit=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/detection/tools/line_zone.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/detection/tools/line_zone.md b/docs/detection/tools/line_zone.md index 3e15a00e..cbecdaa9 100644 --- a/docs/detection/tools/line_zone.md +++ b/docs/detection/tools/line_zone.md @@ -1,3 +1,3 @@ ## LineZone -:::supervision.detection.line_counter.LineZone \ No newline at end of file +:::supervision.detection.line_counter.LineZone