
    ^jz                    ,   d dl mZ d dlZd dlZd dlmZmZmZ d dlm	Z	 d dl
mZ d dlmZmZmZ d dlZd dlZd dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZmZ d dl m!Z!m"Z"m#Z#m$Z$ d dl%m&Z& d dl'm(Z( dZ) G d d      Z* G d d      Z+ G d d      Z,y)    )annotationsN)Counterdefaultdictdeque)Iterable)	lru_cache)AnyLiteralcast)CLASS_NAME_DATA_FIELD)
Detections)cross_product)Color)draw_rectangle	draw_text)PointPositionRectVector)overlay_image)SupervisionWarnings
   c                     e Zd ZdZej
                  ej                  ej                  ej                  fdf	 	 	 	 	 	 	 ddZ	e
dd       Ze
dd       Ze
dd       Ze
dd       Z	 	 	 	 ddZedd	       Z	 	 	 	 dd
ZddZy)LineZonea  
    This class is responsible for counting the number of objects that cross a
    predefined line.

    <video controls>
        <source
            src="https://media.roboflow.com/supervision/cookbooks/count-objects-crossing-the-line-result-1280x720.mp4"
            type="video/mp4">
    </video>

    !!! warning

        LineZone uses the `tracker_id`. Read
        [here](/latest/trackers/) to learn how to plug
        tracking into your inference pipeline.

    Attributes:
        in_count: The number of objects that have crossed the line from outside
            to inside.
        out_count: The number of objects that have crossed the line from inside
            to outside.
        in_count_per_class: Number of objects of each class that have
            crossed the line from outside to inside, keyed by `class_id`
            (`int` for classified detections, `None` for unclassified ones).
        out_count_per_class: Number of objects of each class that have
            crossed the line from inside to outside, keyed by `class_id`
            (`int` for classified detections, `None` for unclassified ones).

    Example:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> def frames_generator():
        ...     yield np.zeros((1080, 1920, 3), dtype=np.uint8)
        ...
        >>> start = sv.Point(x=0, y=100)
        >>> end = sv.Point(x=200, y=100)
        >>> line_zone = sv.LineZone(start=start, end=end)
        >>> for frame in frames_generator():
        ...     detections = sv.Detections(
        ...         xyxy=np.array([[10, 110, 20, 150]]),
        ...         tracker_id=np.array([1])
        ...     )
        ...     crossed_in, crossed_out = line_zone.trigger(
        ...         detections
        ...     )
        ...
        >>> line_zone.in_count, line_zone.out_count
        (0, 0)
        >>> for frame in frames_generator():
        ...     detections = sv.Detections(
        ...         xyxy=np.array([[10, 50, 20, 90]]),
        ...         tracker_id=np.array([1])
        ...     )
        ...     crossed_in, crossed_out = line_zone.trigger(
        ...         detections
        ...     )
        ...
        >>> line_zone.in_count, line_zone.out_count
        (1, 0)

        ```
       c                R    t        ||       _         j                   j                         _        t	        d|dz          _        t         fd       _        t                _	        t                _
        | _        t         j                        st        d      i  _        y)a  
        Args:
            start: The starting point of the line.
            end: The ending point of the line.
            triggering_anchors: 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.
            minimum_crossing_threshold: Detection needs to be seen on the other
                side of the line for this many frames to be considered as having
                crossed the line. This is useful when dealing with unstable
                bounding boxes or when detections may linger on the line.
        startend)vector   r   c                 0    t         j                        S )N)maxlen)r   crossing_history_lengthselfs   j/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/supervision/detection/line_zone.py<lambda>z#LineZone.__init__.<locals>.<lambda>x   s    T-I-I J     z#Triggering anchors cannot be empty.N)r   r    $_calculate_region_of_interest_limitslimitsmaxr$   r   crossing_state_historyr   _in_count_per_class_out_count_per_classtriggering_anchorslist
ValueErrorclass_id_to_name)r&   r   r   r0   minimum_crossing_thresholds   `    r'   __init__zLineZone.__init__[   s    2 5c2??t{{?S'*1.H1.L'M$JK 	# 9@	 9@!"4D++,BCC02r)   c                H    t        | j                  j                               S N)sumr.   valuesr%   s    r'   in_countzLineZone.in_count   s    4++22455r)   c                H    t        | j                  j                               S r7   )r8   r/   r9   r%   s    r'   	out_countzLineZone.out_count   s    4,,33566r)   c                ,    t        | j                        S r7   )dictr.   r%   s    r'   in_count_per_classzLineZone.in_count_per_class   s    D,,--r)   c                ,    t        | j                        S r7   )r>   r/   r%   s    r'   out_count_per_classzLineZone.out_count_per_class   s    D--..r)   c                L   t        j                  t        |      d      }t        j                  t        |      d      }t        |      dk(  r||fS |j                  t	        j
                  dt               ||fS | j                  |       | j                  |      \  }}}|j                  t        |j                        ndgt        |      z  }t        t        ||j                              D ]  \  }\  }	}
||   s||   r||   r||   }| j                  |
|	f   }|j                  |       t        |      | j                  k  rZ|d   }|j!                  |      dkD  rt|r| j"                  |	xx   dz  cc<   d||<   | j$                  |	xx   dz  cc<   d||<    ||fS )a  
        Update the `in_count` and `out_count` based on the objects that cross the line.

        Args:
            detections: A Detections object for which to update the counts.

        Returns:
            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.
        Fr   NzLine zone counting skipped. LineZone requires tracker_id. Refer to https://supervision.roboflow.com/latest/trackers for more information.)categoryr   T)npfulllen
tracker_idwarningswarnr   _update_class_id_to_name_compute_anchor_sidesclass_idr1   	enumeratezipr-   appendr$   countr.   r/   )r&   
detections
crossed_incrossed_out	in_limitshas_any_left_triggerhas_any_right_trigger	class_idsirL   rG   tracker_statecrossing_historyoldest_states                 r'   triggerzLineZone.trigger   s    WWS_e4
ggc*ou5z?a{**  (MM -	 {**%%j1 &&z2 	?	')> "". $$%#j/) 	 *3	:001*
 	&%A%* Q<#A&+@+C"6q"9M#::J;QR##M2#$t'C'CC+A.L%%l3a7((2a72 $
1))(3q83!%A3	&6 ;&&r)   c                T   | j                   }|dk(  rt        d      | j                  j                  | j                  j                  z
  }| j                  j
                  | j                  j
                  z
  }||z  }||z  }| }|}t        | j                  t        | j                  j                  |z   | j                  j
                  |z               }t        | j                  t        | j                  j                  |z
  | j                  j
                  |z
              }	||	fS )Nr   z+The magnitude of the vector cannot be zero.)xyr   )	magnituder2   r   r^   r   r_   r   r   )
r    r`   delta_xdelta_yunit_vector_xunit_vector_yperpendicular_vector_xperpendicular_vector_ystart_region_limitend_region_limits
             r'   r*   z-LineZone._calculate_region_of_interest_limits   s    $$	>JKK**,,/**,,/)+)+"/!.#,,,,..#99,,..#99
 "****,,!77**,,!77
 "#333r)   c                   t        |      dkD  sJ |j                  J t        j                  | j                  D cg c]  }|j                  |       c}      }t        || j                  d         }t        || j                  d         }|dkD  |dkD  k(  }t        j                  |d      }t        || j                        dk  }t        j                  |d      }t        j                  | d      }	|||	fS c c}w )u  
        Find if detections' anchors are within the limit of the line
        zone and which anchors are on its left and right side.

        Assumes:
            * At least 1 detection is provided
            * Detections have `tracker_id`

        The limit is defined as the region between the two lines,
        perpendicular to the line zone, and passing through its start
        and end points, as shown below:

        Limits:
        ```
                |    IN    ↑
                |          |
          OUT   o---LINE---o   OUT
                |          |
                ↓    IN    |
        ```

        Args:
            detections: The detections to check.

        Returns:
            All 3 arrays are boolean arrays of shape (N, ) where N is the
                number of detections. The first array, `in_limits`, indicates
                if the detection's anchor is within the line zone limits.
                The second array, `has_any_left_trigger`, indicates if the
                detection's anchor is on the left side of the line zone.
                The third array, `has_any_right_trigger`, indicates if the
                detection's anchor is on the right side of the line zone.
        r   r   )axis)rF   rG   rD   arrayr0   get_anchors_coordinatesr   r+   allr    any)
r&   rQ   anchorall_anchorscross_products_1cross_products_2rT   triggersrU   rV   s
             r'   rK   zLineZone._compute_anchor_sides   s    H :"""$$000hh #55 226:
 )dkk!nE(dkk!nE &)/?!/CD	FF91-	 dkk:Q>!vvhQ7 "yq 9.0EEE#s   C<c                f   |j                   j                  t              }||j                  J |j                  y|$|j                  D ci c]  }|t	        |       }}n)t        |j                  |      D ci c]  \  }}||
 }}}| j                  j                  |       yc c}w c c}}w )z
        Update the attribute keeping track of which class
        IDs correspond to which class names.

        Assumes that class_names are only provided when class_ids are.
        N)datagetr   rL   strrN   r3   update)r&   rQ   class_namesrL   	new_names
class_names         r'   rJ   z!LineZone._update_class_id_to_name3  s     !oo))*?@"j&9&9&EEE&AKATATUX3x=0UIU -0
0C0C[,Q(Hj *$I  	$$Y/ Vs   B(<B-N)r   r   r   r   r0   zIterable[Position]r4   int)returnr|   )r}   zdict[int | None, int])rQ   r   r}   z3tuple[npt.NDArray[np.bool_], npt.NDArray[np.bool_]])r    r   r}   ztuple[Vector, Vector])rQ   r   r}   zJtuple[npt.NDArray[np.bool_], npt.NDArray[np.bool_], npt.NDArray[np.bool_]])rQ   r   r}   None)__name__
__module____qualname____doc__r   TOP_LEFT	TOP_RIGHTBOTTOM_LEFTBOTTOM_RIGHTr5   propertyr:   r<   r?   rA   r\   staticmethodr*   rK   rJ    r)   r'   r   r      s    >J   !!	2
 +,$3$3 $3 /	$3 %($3L 6 6 7 7 . . / /E'$E'	<E'N 4 4>9F$9F	S9Fv0r)   r   c                  R   e Zd Zdej                  dej
                  ddddddddddf	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 dd	Zdd
Z	 	 	 	 	 	 	 	 	 	 	 	 ddZ		 	 	 	 	 	 	 	 	 	 ddZ
	 	 	 	 	 	 	 	 	 	 ddZe ed      	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd              Zy)LineZoneAnnotatorr!   g      ?      ?r   NTFc                    || _         || _        || _        || _        || _        || _        || _        |r|nd| _        |	r|	nd| _        |
| _	        || _
        || _        || _        || _        y)a  
        A class for drawing the `LineZone` and its detected object count
        on an image.

        Args:
            thickness: Line thickness.
            color: Line color.
            text_thickness: Text thickness.
            text_color: Text color.
            text_scale: Text scale.
            text_offset: How far the text will be from the line.
            text_padding: The empty space in the text box, surrounding the text.
            custom_in_text: Write something else instead of "in".
            custom_out_text: Write something else instead of "out".
            display_in_count: Pass `False` to hide the "in" count.
            display_out_count: Pass `False` to hide the "out" count.
            display_text_box: Pass `False` to hide the text background box.
            text_orient_to_line: Match text orientation to the line.
                Recommended to set to `True`.
            text_centered: Pass `False` to disable text centering. Useful
                when the label overlaps something important.

        inoutN)	thicknesscolortext_thickness
text_color
text_scaletext_offsettext_paddingin_textout_textdisplay_in_countdisplay_out_countdisplay_text_boxtext_orient_to_linetext_centered)r&   r   r   r   r   r   r   r   custom_in_textcustom_out_textr   r   r   r   r   s                  r'   r5   zLineZoneAnnotator.__init__K  sw    P (!
#1!+!+"-!-.<N$0?_U&6'8&6)< #0r)   c           	        |j                   j                  j                         }|j                   j                  j                         }t	        j
                  |||| j                  j                         | j                  t        j                  d       t	        j                  ||d| j                  j                         dt        j                         t	        j                  ||d| j                  j                         dt        j                         | j                   d|j                   }| j                   d|j                   }| j!                  |      }|| j"                  df|| j$                  dffD ]Y  \  }}	}
|	s
|dk(  s| j&                  s*| j)                  ||j                   j*                  ||
	       E| j-                  ||||

       [ |S )a(  
        Draws the line on the frame using the line zone provided.

        Args:
            frame: The image on which the line will be drawn.
            line_counter: The line zone that will be used to draw the line.

        Returns:
            The image with the line drawn on it.

        r   )lineTypeshift   )radiusr   r   r   : TF)frameline_centertextis_in_count)r   	line_zoner   r   )r    r   as_xy_int_tupler   cv2liner   as_bgrr   LINE_AAcircler   r   r:   r   r<   _get_line_angler   r   r   _draw_basic_labelcenter_draw_oriented_label)r&   r   line_counter
line_startline_endr   r   line_angle_degreesr   is_shownr   s              r'   annotatezLineZoneAnnotator.annotate  s    "((..>>@
&&**::<JJNN[[	
 	

//((*[[	
 	

//((*[[	
 \\N"\%:%:$;<mm_B|'='=&>?!11,? d++T2t--u5,
 	'D(K !Q&d.F.F&& , 3 3 : : +	 '  ))* +	 * 	, r)   c                b   |j                   j                  j                         }|j                   j                  j                         }|d   |d   z
  }|d   |d   z
  }|dk(  rd}||dk  rdz  }|S dz  }|S t	        j
                  t	        j                  ||z              }||dk  rdndz  }|S )z
        Calculate the line counter angle (in degrees).

        Args:
            line_zone: The line zone object.

        Returns:
            Line counter angle, in degrees.
        r   r   g     V@   )r    r   r   r   mathdegreesatan)r&   r   start_point	end_pointra   rb   
line_angles          r'   r   z!LineZoneAnnotator._get_line_angle  s      &&,,<<>$$((88:	A,Q/A,Q/a<J1#3J
  343J
  dii'0A&BCJ1#!3Jr)   c                ^   | j                  |      }| j                  rYt        |j                  j                  |j                  j
                        j                  j                         }t        |      }n|j                  j
                  j                         }	t        |	      }t        t        j                  t        j                  |            |dz  | j                  z   z        }
t        t        j                  t        j                  |            |dz  | j                  z   z        }|dxx   |
z  cc<   |dxx   |z  cc<   t        t        j                  t        j                  |            | j                  |z  z        }t        t        j                  t        j                  |            | j                  |z  z        }|r|dxx   |z  cc<   |dxx   |z  cc<   n|dxx   |z  cc<   |dxx   |z  cc<   t!        |d   |dz  z
  d      }t!        |d   |dz  z
  d      }||fS )a  
        Calculate insertion anchor in frame to position the center of the count image.

        Args:
            line_zone: The line counter object used for counting.
            text_width: Text width.
            text_height: Text height.
            is_in_count: Whether the count should be placed over or below line.
            label_dimension: Size of the label image. Assumes the
                label is rectangular.

        Returns:
            xy, point in an image where the label will be placed.
        r   r!   r   r   )r   r   r   r    r   r   r   r   r1   r|   r   cosradiansr   sinr   r,   )r&   r   
text_widthtext_heightr   label_dimensionr   	mid_pointro   r   move_along_xmove_along_ymove_perpendicular_xmove_perpendicular_yx1y1s                   r'   _calculate_anchor_in_framez,LineZoneAnnotator._calculate_anchor_in_frame  s   , )))4
&&,,)2B2B2F2Ff__&  )_F!((,,<<>I)_Fj12>D$5$557L j12>D$5$557L
 1I%I1I%I"HHT\\*-.$2B2B[2PQ 
  #HHT\\*-.$2B2B[2PQ 
 1I--I1I--I1I--I1I--I_1115_11152vr)   c           
        t        j                  |t         j                  | j                  | j                        d   \  }}|r,|xj
                  t        | j                  |z        z  c_        n+|xj
                  t        | j                  |z        z  c_        t        |||| j                  | j                  | j                  | j                  | j                  r| j                  nd       |S )a  
        Draw the count label on the frame. For example: "out: 7".
        The label contains horizontal text and is not rotated.

        Args:
            frame: The entire scene, on which the label will be placed.
            line_center: The center of the line zone.
            text: The text that will be drawn.
            is_in_count: Whether to display the in count (above line)
                or out count (below line).

        Returns:
            The scene with the label drawn on it.
        r   N)scener   text_anchorr   r   r   r   background_color)r   getTextSizeFONT_HERSHEY_SIMPLEXr   r   r_   r|   r   r   r   r   r   r   )r&   r   r   r   r   _r   s          r'   r   z#LineZoneAnnotator._draw_basic_label!  s    * #**DOOT=P=P

; MMS!1!1K!?@@MMMS!1!1K!?@@M#..**+/+@+@TZZd		
 r)   c           
        | j                  |      }| j                  || j                  | j                  | j                  | j
                  | j                  | j                  |      }|j                  d   |j                  d   k(  sJ t        j                  |t        j                  | j                  | j                        d   \  }}| j                  |||||j                  d         }	t        |||	      }|S )a  
        Draw the count label on the frame. For example: "out: 7".
        The label is oriented to match the line angle.

        Args:
            frame: The entire scene, on which the label will be placed.
            line_zone: The line zone responsible for counting objects crossing it.
            text: The text that will be drawn.
            is_in_count: Whether to display the in count (above line)
                or out count (below line).

        Returns:
            The scene with the label drawn on it.
        )r   r   r   r   text_box_showtext_box_colorr   r   r   )r   r   r   r   r   )r   _make_label_imager   r   r   r   r   r   shaper   r   r   r   r   )
r&   r   r   r   r   r   label_imager   r   label_anchors
             r'   r   z&LineZoneAnnotator._draw_oriented_labelL  s    , "11)<,,..**//::1 - 	
   #{'8'8';;;;"%//#**DOOT=P=P#

#
K 66!##'--a0 7 
 e[,?r)       )maxsizec                  t        j                  | t         j                  ||      d   \  }}	t        t	        ||	      |dz  z   dz        }
|
|
f}t        |
dz  |
dz        }t        j                  g |dt        j                        }t        j                  g |dt        j                        }t        | ||||      }t        d|||r|ndd	| t        d|t        j                  |rt        j                  ndd	| t        j                  ||f      }d
|dz  cxk  rdk  r7n n4t        j                  |d      j                  t        j                        }| }t        j                   |j#                         |d      }t        j$                  |||      }t'        t(        j*                  t        j                     |      S )aY  
        Create the small text box displaying line zone count. E.g. "out: 7".

        Args:
            text: The text to display.
            text_scale: The scale of the text.
            text_thickness: The thickness of the text.
            text_padding: The padding around the text.
            text_color: The color of the text.
            text_box_show: Whether to display the text box.
            text_box_color: The color of the text box.
            line_angle_degrees: The angle of the line in degrees.

        Returns:
            The label of shape (H, W, 4), in BGRA format.
        r   r!   r      )dtyper   )r   r   r   r   r   N)r   r   r   Z   ih  i  r   )flipCode)scaler   )r   r   r   r|   r,   r   rD   zerosuint8r>   r   r   WHITEdstackflipastypegetRotationMatrix2Das_xy_float_tuple
warpAffiner   nptNDArray)r   r   r   r   r   r   r   r   r   r   annotation_dimannotation_shapeannotation_center
annotationannotation_alpha	text_argsrotation_anglerotation_matrixs                     r'   r   z#LineZoneAnnotator._make_label_image  s   : #&//#**J#

#
K c*k:\A=MMQTTU*N;!.A"5~7JKXX4 04!4BHHE
88$:&6$:$:"((K$()!)%%
	 	 	
!/<^$	
 		
 	 	
"{{,9U[[t	
 		
 YY
,<=>
 "S(.3.*r:AA"((KJ,,11//1>
 ^^JAQR
CKK):66r)   )r   r|   r   r   r   r|   r   r   r   floatr   r   r   r|   r   
str | Noner   r   r   boolr   r   r   r   r   r   r   r   )r   npt.NDArray[np.uint8]r   r   r}   r   )r   r   r}   r   )r   r   r   r|   r   r|   r   r   r   r|   r}   ztuple[int, int])
r   r   r   r   r   rw   r   r   r}   r   )
r   r   r   r   r   rw   r   r   r}   r   )r   rw   r   r   r   r|   r   r|   r   r   r   r   r   r   r   r   r}   r   )r   r   r   r   r   BLACKr5   r   r   r   r   r   r   r   r   r   r)   r'   r   r   J  s    {{!KK %)&*!%"&!%$)"5151 51 	51
 51 51 51 51 #51 $51 51  51 51 "51 51nD*D:BD	DL2>> > 	>
 > > 
>@)$) ) 	)
 ) 
)V1$1 1 	1
 1 
1f rE7E7 E7 	E7
 E7 E7 E7 E7 "E7 
E7  E7r)   r   c            
          e Zd Zej                  ej                  dddej                  dddd		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d
dZ	 d	 	 	 	 	 	 	 dd	Z	y)LineZoneAnnotatorMulticlassr   i  g      ?r   F)	table_positiontable_colortable_margintable_paddingtable_max_widthr   r   r   force_draw_class_idsc       	           |t         j                  t         j                  t         j                  t         j                  hvrt        d      || _        || _        || _        || _	        || _
        || _        || _        || _        |	| _        y)a  
        Draw a table showing how many items of each class crossed each line.

        Args:
            table_position: The position of the table.
            table_color: The color of the table.
            table_margin: The margin of the table from the image border.
            table_padding: The padding of the table.
            table_max_width: The maximum width of the table.
            text_color: The color of the text.
            text_scale: The scale of the text.
            text_thickness: The thickness of the text.
            force_draw_class_ids: Instead of writing the class names,
                on the table, write the class IDs. E.g. instead of `person: 6`,
                write `0: 6`.
        z]Invalid table position. Supported values are: TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT.N)r   r   r   r   r   r2   r  r  r  r  r  r   r   r   r  )
r&   r  r  r  r  r  r   r   r   r  s
             r'   r5   z$LineZoneAnnotatorMulticlass.__init__  s    D   !!	"
 
 C 
 -&(*.$$,$8!r)   Nc                    |(t        t        |            D cg c]  }d|dz    d }}t        |      t        |      k7  rt        d      dg}t        ||      D ]  \  }}|j	                  |       |j
                  }d|j                  fd|j                  ffD ]  \  }	}
|
s	|j	                  d|	 d       |
j                         D ]T  \  }}| j                  rt        |      }n |d	}n|j                  |t        |            }|j	                  d
| d|        V   d\  }}|D ]\  }t        j                  |t        j                  | j                  | j                         d   \  }}|t"        z  }t%        ||      }||z  }^ |d| j&                  z  z  }|d| j&                  z  z  }|j(                  d   d| j*                  z  z
  }t-        ||      }t-        || j.                        }t0        j2                  | j*                  | j*                  ft0        j4                  |j(                  d   |z
  | j*                  z
  | j*                  ft0        j6                  | j*                  |j(                  d   |z
  | j*                  z
  ft0        j8                  |j(                  d   |z
  | j*                  z
  |j(                  d   |z
  | j*                  z
  fi}|| j:                     \  }}t=        ||||      }t?        ||| j@                  d      }tC        |      D ]  \  }}t        j                  |t        j                  | j                  | j                         d   \  }}|t"        z  }|| j&                  z   }|| j&                  z   |dz   |z  z   }t        jD                  ||||ft        j                  | j                  | jF                  jI                         | j                   t        jJ                          |S c c}w )a  
        Draws a table with the number of objects of each class that crossed each line.

        Args:
            frame: The image on which the table will be drawn.
            line_zones: The line zones to be annotated.
            line_zone_labels: The labels, one for each line zone. If not
                provided, the default labels will be used.

        Returns:
            The image with the table drawn on it.

        zLine r   :z5The number of line zones and their labels must match.zLine Crossings:InOut r~   z  r   )r   r   r   r!   )r^   r_   widthheightr   )r   rectr   r   )imgr   orgfontFace	fontScaler   r   r   )&rangerF   r2   rN   rO   r3   r?   rA   itemsr  rw   rv   r   r   r   r   r   TEXT_MARGINr,   r  r   r  minr  r   r   r   r   r   r  r   r   r  rM   putTextr   r   r   )r&   r   
line_zonesline_zone_labelsrX   
text_linesr   line_zone_labelr3   	directioncount_per_classrL   rP   r{   table_widthtable_heightr   r   r   table_max_heightposition_maptable_x1table_y1
table_rectr   anchor_xanchor_ys                              r'   r   z$LineZoneAnnotatorMulticlass.annotate  s"   & #:?J:PQQ%Awa 0QQz?c"233TUU'(
*-j:J*K 	B&Io.(99 y334	556/ B*	? '!!Ai["23'6'<'<'> BOHe00%(]
!)%+
%5%9%9(CM%R
%%:,b&@ABB		B* %)!\ 	(D&)ooc..ATAT''#J ;&Kk:6KK'L	( 	q4----D.... ;;q>A0A0A,AA<)9:+t';';<  1 143D3DEA,t/@/@@!!!   !!A-0A0AA# !!A,t/@/@@A-0A0AA$
 *$*=*=>((+l

 j0@0@B
 !, 	GAt __c..ATATNA{ ;&K$"4"44H$"4"44A7LLHKKx(11//oo,,.--		& i  Rs   O;)r  z[Literal[Position.TOP_LEFT, Position.TOP_RIGHT, Position.BOTTOM_LEFT, Position.BOTTOM_RIGHT]r  r   r  r|   r  r|   r  r|   r   r   r   r   r   r|   r  r   r7   )r   r   r  zlist[LineZone]r  zlist[str] | Noner}   r   )
r   r   r   r   r   r   r   r   r5   r   r   r)   r'   r  r    s     "[["!KK %*!59
59 59 59 59 59 59 59 59  #!59v .2	h$h #h +	h
 
hr)   r  )-
__future__r   r   rH   collectionsr   r   r   collections.abcr   	functoolsr   typingr	   r
   r   r   numpyrD   numpy.typingr   supervision.configr   supervision.detection.corer   $supervision.detection.utils.internalr   supervision.draw.colorr   supervision.draw.utilsr   r   supervision.geometry.corer   r   r   r   supervision.utils.imager   supervision.utils.internalr   r  r   r   r  r   r)   r'   <module>r9     so    "   3 3 $  % % 
   4 1 > ( < C C 1 :m0 m0`	|7 |7~` `r)   