o
    Whw                     @   sD   d dl Z d dlZd dlmZmZmZ d dlmZ G dd deZdS )    N)BaseSolutionSolutionAnnotatorSolutionResults)colorsc                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )DistanceCalculationa  
    A class to calculate distance between two objects in a real-time video stream based on their tracks.

    This class extends BaseSolution to provide functionality for selecting objects and calculating the distance
    between them in a video stream using YOLO object detection and tracking.

    Attributes:
        left_mouse_count (int): Counter for left mouse button clicks.
        selected_boxes (Dict[int, List[float]]): Dictionary to store selected bounding boxes and their track IDs.
        centroids (List[List[int]]): List to store centroids of selected bounding boxes.

    Methods:
        mouse_event_for_distance: Handles mouse events for selecting objects in the video stream.
        process: Processes video frames and calculates the distance between selected objects.

    Examples:
        >>> distance_calc = DistanceCalculation()
        >>> frame = cv2.imread("frame.jpg")
        >>> results = distance_calc.process(frame)
        >>> cv2.imshow("Distance Calculation", results.plot_im)
        >>> cv2.waitKey(0)
    c                    s(   t  jdi | d| _i | _g | _dS )zZInitializes the DistanceCalculation class for measuring object distances in video streams.r   N )super__init__left_mouse_countselected_boxes	centroids)selfkwargs	__class__r   ^/var/www/vscode/kcb/lib/python3.10/site-packages/ultralytics/solutions/distance_calculation.pyr	   #   s   
zDistanceCalculation.__init__c                 C   s   |t jkrK|  jd7  _| jdkrGt| j| jD ]0\}}|d |  k r*|d k rFn q|d |  k r:|d k rFn q|| jvrF|| j|< qdS dS |t jkrXi | _d| _dS dS )a  
        Handles mouse events to select regions in a real-time video stream for distance calculation.

        Args:
            event (int): Type of mouse event (e.g., cv2.EVENT_MOUSEMOVE, cv2.EVENT_LBUTTONDOWN).
            x (int): X-coordinate of the mouse pointer.
            y (int): Y-coordinate of the mouse pointer.
            flags (int): Flags associated with the event (e.g., cv2.EVENT_FLAG_CTRLKEY, cv2.EVENT_FLAG_SHIFTKEY).
            param (Any): Additional parameters passed to the function.

        Examples:
            >>> # Assuming 'dc' is an instance of DistanceCalculation
            >>> cv2.setMouseCallback("window_name", dc.mouse_event_for_distance)
              r      N)cv2EVENT_LBUTTONDOWNr
   zipboxes	track_idsr   EVENT_RBUTTONDOWN)r   eventxyflagsparamboxtrack_idr   r   r   mouse_event_for_distance,   s   

J


z,DistanceCalculation.mouse_event_for_distancec           
   	   C   sL  |  | t|| jd}d}t| j| j| j| jD ]0\}}}}|j|t	t
|d| |||d t| jdkrI| j D ]}||krH|| j|< q=qt| jdkr| jdd | j D  t| jd d | jd d  d | jd d | jd d  d  }||| j g | _| }	| |	 td	| j t|	|t| jd
S )a  
        Processes a video frame and calculates the distance between two selected bounding boxes.

        This method extracts tracks from the input frame, annotates bounding boxes, and calculates the distance
        between two user-selected objects if they have been chosen.

        Args:
            im0 (numpy.ndarray): The input image frame to process.

        Returns:
            (SolutionResults): Contains processed image `plot_im`, `total_tracks` (int) representing the total number
                of tracked objects, and `pixels_distance` (float) representing the distance between selected objects
                in pixels.

        Examples:
            >>> import numpy as np
            >>> from ultralytics.solutions import DistanceCalculation
            >>> dc = DistanceCalculation()
            >>> frame = np.random.randint(0, 255, (480, 640, 3), dtype=np.uint8)
            >>> results = dc.process(frame)
            >>> print(f"Distance: {results.pixels_distance:.2f} pixels")
        )
line_widthr   T)colorlabelr   c                 S   s<   g | ]}t |d  |d  d t |d |d  d gqS )r   r   r   r   )int).0r    r   r   r   
<listcomp>n   s   < z/DistanceCalculation.process.<locals>.<listcomp>r   zUltralytics Solutions)plot_impixels_distancetotal_tracks)extract_tracksr   r#   r   r   r   clssconfs	box_labelr   r&   adjust_box_labellenr   keysr   extendvaluesmathsqrtplot_distance_and_lineresultdisplay_outputr   setMouseCallbackr"   r   )
r   im0	annotatorr*   r    r!   clsconftrk_idr)   r   r   r   processF   s.   
"$
>
zDistanceCalculation.process)__name__
__module____qualname____doc__r	   r"   r@   __classcell__r   r   r   r   r      s
    	r   )	r5   r   ultralytics.solutions.solutionsr   r   r   ultralytics.utils.plottingr   r   r   r   r   r   <module>   s
   