
    h                    Z    S SK Jr  S SKJr  S SKrS SKJrJrJ	r	  S SK
Jr   " S S\5      rg)    )annotations)AnyN)BaseSolutionSolutionAnnotatorSolutionResults)colorsc                  ^   ^  \ rS rSrSrSU 4S jjr          S	S jrS rS
S jrSr	U =r
$ )RegionCounter   a  
A class for real-time counting of objects within user-defined regions in a video stream.

This class inherits from `BaseSolution` and provides functionality to define polygonal regions in a video frame,
track objects, and count those objects that pass through each defined region. Useful for applications requiring
counting in specified areas, such as monitoring zones or segmented sections.

Attributes:
    region_template (dict): Template for creating new counting regions with default attributes including name,
        polygon coordinates, and display colors.
    counting_regions (list): List storing all defined regions, where each entry is based on `region_template`
        and includes specific region settings like name, coordinates, and color.
    region_counts (dict): Dictionary storing the count of objects for each named region.

Methods:
    add_region: Add a new counting region with specified attributes.
    process: Process video frames to count objects in each region.
    initialize_regions: Initialize zones to count the objects in each one. Zones could be multiple as well.

Examples:
    Initialize a RegionCounter and add a counting region
    >>> counter = RegionCounter()
    >>> counter.add_region("Zone1", [(100, 100), (200, 100), (200, 200), (100, 200)], (255, 0, 0), (255, 255, 255))
    >>> results = counter.process(frame)
    >>> print(f"Total tracks: {results.total_tracks}")
c                |   > [         TU ]  " S0 UD6  SSSSSS.U l        0 U l        / U l        U R                  5         g)zSInitialize the RegionCounter for real-time object counting in user-defined regions.zDefault RegionNr      r   r   )r   r   r   )namepolygoncountsregion_color
text_color )super__init__region_templateregion_countscounting_regionsinitialize_regions)selfkwargs	__class__s     ^/home/james-whalen/.local/lib/python3.13/site-packages/ultralytics/solutions/region_counter.pyr   RegionCounter.__init__)   sJ    "6"$+# 
   "!    c                    U R                   R                  5       nUR                  UU R                  U5      UUS.5        U R                  R                  U5        U$ )a  
Add a new region to the counting list based on the provided template with specific attributes.

Args:
    name (str): Name assigned to the new region.
    polygon_points (list[tuple]): List of (x, y) coordinates defining the region's polygon.
    region_color (tuple[int, int, int]): BGR color for region visualization.
    text_color (tuple[int, int, int]): BGR color for the text within the region.

Returns:
    (dict[str, any]): Returns a dictionary including the region information i.e. name, region_color etc.
)r   r   r   r   )r   copyupdatePolygonr   append)r   r   polygon_pointsr   r   regions         r   
add_regionRegionCounter.add_region7   sY    & %%**,<<7 ,(		
 	$$V,r    c           	     h   U R                   c  U R                  5         [        U R                   [        5      (       d  SU R                   0U l         [	        U R                   R                  5       5       H<  u  nu  p#U R                  X#[        US5      S5      nU R                  US   5      US'   M>     g)zInitialize regions only once.Nz	Region#01Tr   r   prepared_polygon)	r'   initialize_region
isinstancedict	enumerateitemsr(   r   prep)r   ir   ptsr'   s        r   r    RegionCounter.initialize_regionsV   s    ;;""$$++t,,&4DK'(9(9(;<NA{__Tq$QF)-6)3D)EF%& =r    c                   U R                  U5        [        XR                  S9n[        U R                  U R
                  U R                  U R                  5       H  u  p4pVUR                  X0R                  XFU5      [        US5      S9  U R                  US   US   -   S-  US   US   -   S-  45      nU R                   H@  nUS   R                  U5      (       d  M  US	==   S-  ss'   US	   U R                  US
   '   MB     M     U R                   H  nUS   n	[        [!        ["        [$        R&                  " U	R(                  R*                  [$        R,                  S95      5      n
[/        U	R0                  R2                  5      [/        U	R0                  R4                  5      4/S-  u  u  pu  pUR7                  XS   U R                  S-  5        UR9                  XX/[;        US	   5      US   US   U R                  S-  SS9  SUS	'   M     UR=                  5       nU R?                  U5        [A        U[C        U R                  5      U R                  S9$ )ag  
Process the input frame to detect and count objects within each defined region.

Args:
    im0 (np.ndarray): Input image frame where objects and regions are annotated.

Returns:
    (SolutionResults): Contains processed image `plot_im`, 'total_tracks' (int, total number of tracked objects),
        and 'region_counts' (dict, counts of objects per region).
)
line_widthT)labelcolorr            r+   r   r   r   )dtyper   r      rect)r7   r8   	txt_colormarginshape)plot_imtotal_tracksr   )"extract_tracksr   r6   zipboxesclss	track_idsconfs	box_labeladjust_box_labelr   Pointr   containsr   listmaptuplenparrayexteriorcoordsint32intcentroidxydraw_regionadaptive_labelstrresultdisplay_outputr   len)r   im0	annotatorboxclstrack_idconfcenterr'   polyr3   x1y1x2y2rB   s                   r   processRegionCounter.process`   s(    	C %cooF	(+DJJ		4>>SWS]S](^$Ch+@+@H+U]cdlnr]stZZ#a&3q6/Q!6Q#a&A8M NOF//,-66v>>8$)$9?9ID&&vf~6 0 )_ ++F)$Ds5"((4==+?+?rxx"PQRC#&t}}#7T]]__9M"N!ORS!SHRhr!!#n'=tQR?RS$$ &*+^, .* %   !F8 , ""$G$wS=P`d`r`rssr    )r   r'   r   r   )r   r   returnNone)
r   r\   r&   zlist[tuple]r   tuple[int, int, int]r   rp   rn   zdict[str, Any])r`   z
np.ndarrayrn   r   )__name__
__module____qualname____firstlineno____doc__r   r(   r   rl   __static_attributes____classcell__)r   s   @r   r
   r
      sT    6" $ +	
 ) 
>F(t (tr    r
   )
__future__r   typingr   numpyrQ   ultralytics.solutions.solutionsr   r   r   ultralytics.utils.plottingr   r
   r   r    r   <module>r}      s)    #   \ \ -{tL {tr    