a
    yf8                     @   s6   d dl Z d dlZd dlZd dlmZ G dd dZdS )    N)LOGGERc                       s   e Zd ZdZdeedd fddZdeje	ejdd	d
Z
ejejdddZdeje	ejdddZejejdddZddddZ  ZS )GMCa  
    Generalized Motion Compensation (GMC) class for tracking and object detection in video frames.

    This class provides methods for tracking and detecting objects based on several tracking algorithms including ORB,
    SIFT, ECC, and Sparse Optical Flow. It also supports downscaling of frames for computational efficiency.

    Attributes:
        method (str): The method used for tracking. Options include 'orb', 'sift', 'ecc', 'sparseOptFlow', 'none'.
        downscale (int): Factor by which to downscale the frames for processing.
        prevFrame (np.ndarray): Stores the previous frame for tracking.
        prevKeyPoints (List): Stores the keypoints from the previous frame.
        prevDescriptors (np.ndarray): Stores the descriptors from the previous frame.
        initializedFirstFrame (bool): Flag to indicate if the first frame has been processed.

    Methods:
        __init__: Initializes a GMC object with the specified method and downscale factor.
        apply: Applies the chosen method to a raw frame and optionally uses provided detections.
        applyEcc: Applies the ECC algorithm to a raw frame.
        applyFeatures: Applies feature-based methods like ORB or SIFT to a raw frame.
        applySparseOptFlow: Applies the Sparse Optical Flow method to a raw frame.
        reset_params: Resets the internal parameters of the GMC object.

    Examples:
        Create a GMC object and apply it to a frame
        >>> gmc = GMC(method="sparseOptFlow", downscale=2)
        >>> frame = np.array([[1, 2, 3], [4, 5, 6]])
        >>> processed_frame = gmc.apply(frame)
        >>> print(processed_frame)
        array([[1, 2, 3],
               [4, 5, 6]])
    sparseOptFlow   N)method	downscalereturnc                    s  t    || _td|| _| jdkrLtd| _t | _	t
tj| _n| jdkrtjdddd| _tjdddd| _	t
tj| _nr| jdkrd	}d
}tj| _tjtjB ||f| _nB| jdkrtddddddd| _n | jdv rd| _ntd| d| _d| _d| _d| _dS )a  
        Initialize a Generalized Motion Compensation (GMC) object with tracking method and downscale factor.

        Args:
            method (str): The method used for tracking. Options include 'orb', 'sift', 'ecc', 'sparseOptFlow', 'none'.
            downscale (int): Downscale factor for processing frames.

        Examples:
            Initialize a GMC object with the 'sparseOptFlow' method and a downscale factor of 2
            >>> gmc = GMC(method="sparseOptFlow", downscale=2)
           orb   sift   {Gz?)ZnOctaveLayersZcontrastThresholdZedgeThresholdecci  gư>r   i  g{Gz?Fg{Gz?)Z
maxCornersZqualityLevelZminDistanceZ	blockSizeZuseHarrisDetectork>   NonenoneNNzError: Unknown GMC method:)super__init__r   maxr   cv2ZFastFeatureDetector_createdetectorZ
ORB_create	extractorZ	BFMatcherZNORM_HAMMINGmatcherZSIFT_createZNORM_L2ZMOTION_EUCLIDEAN	warp_modeZTERM_CRITERIA_EPSZTERM_CRITERIA_COUNTcriteriadictfeature_params
ValueError	prevFrameprevKeyPointsprevDescriptorsinitializedFirstFrame)selfr   r   Znumber_of_iterationsZtermination_eps	__class__ Z/var/www/html/django/DPS/env/lib/python3.9/site-packages/ultralytics/trackers/utils/gmc.pyr   ,   s6    







zGMC.__init__)	raw_frame
detectionsr   c                 C   sN   | j dv r| ||S | j dkr*| |S | j dkr>| |S tddS dS )ah  
        Apply object detection on a raw frame using the specified method.

        Args:
            raw_frame (np.ndarray): The raw frame to be processed, with shape (H, W, C).
            detections (List | None): List of detections to be used in the processing.

        Returns:
            (np.ndarray): Processed frame with applied object detection.

        Examples:
            >>> gmc = GMC(method="sparseOptFlow")
            >>> raw_frame = np.random.rand(480, 640, 3)
            >>> processed_frame = gmc.apply(raw_frame)
            >>> print(processed_frame.shape)
            (480, 640, 3)
        >   r
   r   r   r   r   r   N)r   applyFeaturesapplyEccapplySparseOptFlownpeye)r#   r(   r)   r&   r&   r'   apply\   s    




z	GMC.apply)r(   r   c              
   C   s   |j \}}}t|tj}tjddtjd}| jdkr`t|dd}t	||| j || j f}| j
sz| | _d| _
|S z$t| j||| j| jdd	\}}W n4 ty } ztd
|  W Y d}~n
d}~0 0 |S )aB  
        Apply the ECC (Enhanced Correlation Coefficient) algorithm to a raw frame for motion compensation.

        Args:
            raw_frame (np.ndarray): The raw frame to be processed, with shape (H, W, C).

        Returns:
            (np.ndarray): The processed frame with the applied ECC transformation.

        Examples:
            >>> gmc = GMC(method="ecc")
            >>> processed_frame = gmc.applyEcc(np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]))
            >>> print(processed_frame)
            [[1. 0. 0.]
             [0. 1. 0.]]
        r   r   )Zdtype      ?)r   r   g      ?TNr	   z5WARNING: find transform failed. Set warp as identity )shaper   cvtColorCOLOR_BGR2GRAYr-   r.   Zfloat32r   ZGaussianBlurresizer"   copyr   ZfindTransformECCr   r   	Exceptionr   warning)r#   r(   heightwidth_frameHer&   r&   r'   r+   w   s    

$&zGMC.applyEccc                 C   s|  |j \}}}t|tj}tdd}| jdkr`t||| j || j f}|| j }|| j }t|}d|t	d| t	d| t	d| t	d| f< |dur|D ]B}	|	dd | j 
tj}
d	||
d
 |
d |
d	 |
d f< q| j||}| j||\}}| jsB| | _t|| _t|| _d| _|S | j| j|d}g }g }dt||g }t|d	kr| | _t|| _t|| _|S |D ]\}}|jd|j k r| j|j j}||j j}|d	 |d	  |d
 |d
  f}t|d	 |d	 k rt|d
 |d
 k r|| || qt|d	}t |d	}|| d| k }g }g }g }t!t|D ]^}||d	f r||d
f r|||  || j|| j j |||| j j qt|}t|}|j d	 dkrLt"||tj#\}}| jdkrV|d  | j9  < |d  | j9  < n
t$%d | | _t|| _t|| _|S )aY  
        Apply feature-based methods like ORB or SIFT to a raw frame.

        Args:
            raw_frame (np.ndarray): The raw frame to be processed, with shape (H, W, C).
            detections (List | None): List of detections to be used in the processing.

        Returns:
            (np.ndarray): Processed frame.

        Examples:
            >>> gmc = GMC(method="orb")
            >>> raw_frame = np.random.randint(0, 255, (480, 640, 3), dtype=np.uint8)
            >>> processed_frame = gmc.applyFeatures(raw_frame)
            >>> print(processed_frame.shape)
            (2, 3)
        r   r   r0      r   g\(\?N   r   r	   Tg      ?g?g      @r   r   r	   r   #WARNING: not enough matching points)&r1   r   r2   r3   r-   r.   r   r4   Z
zeros_likeintZastypeint_r   detectr   Zcomputer"   r5   r   r    r!   r   ZknnMatcharraylenZdistanceZqueryIdxptZtrainIdxabsappendmeanZstdrangeestimateAffinePartial2DRANSACr   r7   )r#   r(   r)   r8   r9   r:   r;   r<   maskZdetZtlbr	keypointsZdescriptorsZ
knnMatchesmatchesZspatialDistancesZmaxSpatialDistancemnZprevKeyPointLocationZcurrKeyPointLocationZspatialDistanceZmeanSpatialDistancesZstdSpatialDistancesZinliersZgoodMatches
prevPoints
currPointsir&   r&   r'   r*      s    



4&






zGMC.applyFeaturesc                 C   s  |j \}}}t|tj}tdd}| jdkrLt||| j || j f}tj|fddi| j	}| j
rt| jdu r| | _t|| _d| _
|S t| j|| jd\}}	}g }
g }tt|	D ]*}|	| r|
| j|  |||  qt|
}
t|}|
j d dkrn|
j d |
j d krnt|
|tj\}}| jdkrx|d	  | j9  < |d
  | j9  < n
td | | _t|| _|S )a  
        Apply Sparse Optical Flow method to a raw frame.

        Args:
            raw_frame (np.ndarray): The raw frame to be processed, with shape (H, W, C).

        Returns:
            (np.ndarray): Processed frame with shape (2, 3).

        Examples:
            >>> gmc = GMC()
            >>> result = gmc.applySparseOptFlow(np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]))
            >>> print(result)
            [[1. 0. 0.]
             [0. 1. 0.]]
        r   r   r0   rO   NTr   r?   r@   rA   rB   )r1   r   r2   r3   r-   r.   r   r4   ZgoodFeaturesToTrackr   r"   r    r5   r   ZcalcOpticalFlowPyrLKrL   rG   rJ   rF   rM   rN   r   r7   )r#   r(   r8   r9   r:   r;   r<   rP   ZmatchedKeypointsstatusrT   rU   rV   r&   r&   r'   r,   3  s:    



&

zGMC.applySparseOptFlow)r   c                 C   s   d| _ d| _d| _d| _dS )zSReset the internal parameters including previous frame, keypoints, and descriptors.NF)r   r    r!   r"   )r#   r&   r&   r'   reset_paramst  s    zGMC.reset_params)r   r   )N)N)__name__
__module____qualname____doc__strrC   r   r-   rF   listr/   r+   r*   r,   rX   __classcell__r&   r&   r$   r'   r      s    0- Ar   )r5   r   numpyr-   Zultralytics.utilsr   r   r&   r&   r&   r'   <module>   s   