Repository: roboflow/supervision
File: supervision/detection/line_counter.py (Python)

Code before:
import numpy as np

from supervision.detection.core import Detections
from supervision.draw.color import Color
from supervision.geometry.core import Point, Rect, Vector


class LineZone:
    """
    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, count_condition="whole_crossed"):
        """
        Args:
            start (Point): The starting point of the line.
            end (Point): The ending point of the line.
            count_condition (str): The condition which determines
                how detections are counted as having crossed the line
                counter. Can either be "whole_crossed" or "center_point_crossed".

                If condition is set to "whole_crossed", trigger() determines
                whether if the whole bounding box of the detection has crossed
                the line or not. This is the default behaviour.

                If condition is set to "center_point_crossed", trigger() determines
                whether if the center point of the detection's bounding box has
                crossed the line or not.
        """
        self.vector = Vector(start=start, end=end)
        self.tracker_state: Dict[str, bool] = {}
        self.in_count: int = 0
        self.out_count: int = 0
        self.count_condition = count_condition
        if count_condition not in ["whole_crossed", "center_point_crossed"]:
            raise ValueError(
                "Argument count_condition must be 'whole_crossed' or 'center_point_crossed'"
            )

Review comment (suggestion):
Here's an idea. Let's replace `count_condition` with `triggering_anchors: List[sv.Position]`. In this way, we can provide our users with full flexibility. 

Let me know if you need more explanation. :) 

Code after:
import numpy as np

from supervision.detection.core import Detections
from supervision.draw.color import Color
from supervision.geometry.core import Point, Position, Rect, Vector


class LineZone:
    """
    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,
        triggering_anchors: Iterable[Position] = (
            Position.TOP_LEFT,
            Position.TOP_RIGHT,
            Position.BOTTOM_LEFT,
            Position.BOTTOM_RIGHT,
        ),
    ):
        """
        Args:
            start (Point): The starting point of the line.
            end (Point): The ending point of the line.
            triggering_anchors (List[sv.Position]): A list of positions
                specifying which anchors of the detections bounding box
                to consider when deciding on whether the detection
                has passed the line counter or not. By default, this
                contains the four corners of the detection's bounding box
        """
        self.vector = Vector(start=start, end=end)
        self.limits = self.calculate_region_of_interest_limits(vector=self.vector)
        self.tracker_state: Dict[str, bool] = {}
        self.in_count: int = 0
        self.out_count: int = 0