o
    0j6                  
   @   s&  d dl Z d dlmZmZmZmZmZ d dlZd dlm	Z	 ddl
mZmZ ddlmZ dd	lmZ ed
r8d dlZeeef Zee Zdede	de	de	de	f
ddZejed
G dd dZde	de	fddZde	deeef deeef deeef de	f
ddZejed
G dd dZdS )     N)ListOptionalSequenceTupleUnion)ndarray   )class_requires_depsis_dep_available   )	benchmark   )get_affine_transformzopencv-contrib-pythontheta
size_inputsize_dstsize_targetreturnc                 C   s  t | } t jdt jd}|d |d  }|d |d  }t | | |d< t |  | |d< |d|d  t |  d|d  t |   d|d    |d	< t | | |d
< t | | |d< |d|d  t |  d|d  t |   d|d    |d< |S )a  This code is based on
        https://github.com/open-mmlab/mmpose/blob/master/mmpose/core/post_processing/post_transforms.py
        Calculate the transformation matrix under the constraint of unbiased.
    Paper ref: Huang et al. The Devil is in the Details: Delving into Unbiased
    Data Processing for Human Pose Estimation (CVPR 2020).
    Args:
        theta (float): Rotation angle in degrees.
        size_input (np.ndarray): Size of input image [w, h].
        size_dst (np.ndarray): Size of output image [w, h].
        size_target (np.ndarray): Size of ROI in input plane [w, h].
    Returns:
        matrix (np.ndarray): A matrix for transformation.
    )r   r   )Zdtyper      )r   r   )r   r   g            ?)r   r   )r   r   )r   r   )r   r   )npZdeg2radzerosfloat32cossin)r   r   r   r   matrixZscale_xZscale_y r   w/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddlex/inference/models/keypoint_detection/processors.pyget_warp_matrix    s.   


r   c                   @   s   e Zd ZdZddeeef defddZ		dded	e	e
eeef ef  d
e	e
eeef ef  deeeef fddZdee dee fddZdS )TopDownAffinea:  refer to https://github.com/open-mmlab/mmpose/blob/71ec36ebd63c475ab589afc817868e749a61491f/mmpose/datasets/transforms/topdown_transforms.py#L13
    Get the bbox image as the model input by affine transform.

    Args:
        input_size (Tuple[int, int]): The input image size of the model in
            [w, h]. The bbox region will be cropped and resize to `input_size`
        use_udp (bool): Whether use unbiased data processing. See
            `UDP (CVPR 2020)`_ for details. Defaults to ``False``

    .. _`UDP (CVPR 2020)`: https://arxiv.org/abs/1911.07524
    F
input_sizeuse_udpc                 C   s<   t dd |D rt|dksJ d| || _|| _d S )Nc                 S   s   g | ]}t |tqS r   )
isinstanceint).0ir   r   r   
<listcomp>Y   s    z*TopDownAffine.__init__.<locals>.<listcomp>r   zInvalid input_size )alllenr    r!   )selfr    r!   r   r   r   __init__W   s   
zTopDownAffine.__init__Nimgcenterscaler   c                 C   s  d}t |jdd ddd }t|trt |}t|tr%t |}|dur+|n|d }|dur5|n|}| jrft||d | jd d | jd d g|}tj	||t
| jd t
| jd ftjd}nt|||| j}tj	||t
| jd t
| jd ftjd}|||fS )	aV  Applies a wrapaffine to the input image based on the specified center, scale.

        Args:
            img (ndarray): The input image as a NumPy ndarray.
            center (Optional[Union[Tuple[Number, Number], ndarray]], optional): Center of the bounding box (x, y)
            scale (Optional[Union[Tuple[Number, Number], ndarray]], optional): Scale of the bounding box
            wrt [width, height].

        Returns:
            Tuple[ndarray, ndarray, ndarray]: The transformed image,
            the center used for the transformation, and the scale used for the transformation.
        r   Nr   g       @      ?r   )flags)r   arrayshaper"   r   r!   r   r    cv2Z
warpAffiner#   ZINTER_LINEARr   )r)   r+   r,   r-   ZrotZimshapetransr   r   r   apply^   s:   




zTopDownAffine.applydatasc              	   C   s   |D ]J}|d }d|vr||d< d|vr |j d |j d g|d< | ||dd |dd \}}}||d< ||d< ||d< |j d |j d g}||d< q|S )	Nr+   ori_imgZori_img_sizer   r   r,   r-   img_size)r2   r5   get)r)   r6   datar7   r+   r,   r-   r8   r   r   r   __call__   s   

zTopDownAffine.__call__)F)NN)__name__
__module____qualname____doc__r   r#   boolr*   r   r   r   Numberr5   r   dictr;   r   r   r   r   r   H   s    

3r   pttc                 C   s2   t | d | d dgj}t ||}|dd S )a  Apply an affine transformation to a 2D point.

    Args:
        pt (numpy.ndarray): A 2D point represented as a 2-element array.
        t (numpy.ndarray): A 3x3 affine transformation matrix.

    Returns:
        numpy.ndarray: The transformed 2D point.
    r   r   r/   Nr   )r   r1   Tdot)rC   rD   Znew_ptr   r   r   affine_transform   s   
rG   coordsr,   r-   output_sizec                 C   sX   t | j}t||d|dd}t| jd D ]}t| |ddf |||ddf< q|S )a  Transform coordinates to the target space using an affine transformation.

    Args:
        coords (numpy.ndarray): Original coordinates, shape (N, 2).
        center (tuple): Center point for the transformation.
        scale (tuple): Scale factor for the transformation.
        output_size (tuple): Size of the output space.

    Returns:
        numpy.ndarray: Transformed coordinates, shape (N, 2).
    r   r   )invr   )r   r   r2   r   rangerG   )rH   r,   r-   rI   Ztarget_coordsr4   pr   r   r   transform_preds   s
   $rM   c                	   @   s   e Zd ZdZd!ddZdedededefd	d
Zdee	 dee	 dee fddZ
	d"dedededefddZdedeeef fddZdededefddZdedefddZdedededefddZd S )#KptPostProcesszSave Result TransformTc                 C   s
   || _ d S )N)use_dark)r)   rO   r   r   r   r*      s   
zKptPostProcess.__init__heatmapr,   r-   r   c                 C   sj   |d |d |d }}}|  |||\}}tj||fddtj|ddd}}dd t||D S )r5   )N.r.   Zaxisr   c                 S   s   g | ]	\}}||d qS ))	keypointsZ	kpt_scorer   )r$   ZkptZscorer   r   r   r&      s    z(KptPostProcess.apply.<locals>.<listcomp>)get_final_predsr   Zconcatenatemeansqueezezip)r)   rP   r,   r-   predsmaxvalsrR   Zscoresr   r   r   r5      s   

zKptPostProcess.applybatch_outputsr6   c                    s    fddt ||D S )a  Apply the post-processing to a batch of outputs.

        Args:
            batch_outputs (List[dict]): The list of detection outputs.
            datas (List[dict]): The list of input data.

        Returns:
            List[dict]: The list of post-processed keypoints.
        c                    s*   g | ]\}}  |d  |d |d qS )rP   r,   r-   )r5   )r$   r:   outputr)   r   r   r&      s    z+KptPostProcess.__call__.<locals>.<listcomp>)rV   )r)   rY   r6   r   r[   r   r;      s   

zKptPostProcess.__call__r   heatmaps
kernelsizec              	   C   s  |  |\}}|jd }|jd }| jr| |||}nt|jd D ]~}	t|jd D ]t}
||	 |
 }tt||	 |
 d d }tt||	 |
 d d }d|  k r^|d k rn q,d|  k rl|d k rn q,t	|| |d  || |d   ||d  | ||d  |  g}||	 |
  t
|d 7  < q,q#| }t|jd D ]}t|| || || ||g||< q||fS )a  the highest heatvalue location with a quarter offset in the
        direction from the highest response to the second highest response.
        Args:
            heatmaps (numpy.ndarray): The predicted heatmaps
            center (numpy.ndarray): The boxes center
            scale (numpy.ndarray): The scale factor
        Returns:
            preds: numpy.ndarray([batch_size, num_joints, 2]), keypoints coords
            maxvals: numpy.ndarray([batch_size, num_joints, 1]), the maximum confidence of the keypoints
        r   r   r   r   r         ?)get_max_predsr2   rO   dark_postprocessrK   r#   mathfloorr   r1   signcopyrM   )r)   r\   r,   r-   r]   rH   rX   heatmap_heightheatmap_widthnrL   hmpxpydiffrW   r%   r   r   r   rS      s2   

8
zKptPostProcess.get_final_predsc           
      C   s.  t |tjs
J d|jdksJ d|jd }|jd }|jd }|||df}t|d}t|d}|||df}|||df}t|d		tj
}|d
d
d
d
df | |d
d
d
d
df< t|d
d
d
d
df | |d
d
d
d
df< tt|dd	}	|		tj
}	||	9 }||fS )aM  get predictions from score maps
        Args:
            heatmaps: numpy.ndarray([batch_size, num_joints, height, width])
        Returns:
            preds: numpy.ndarray([batch_size, num_joints, 2]), keypoints coords
            maxvals: numpy.ndarray([batch_size, num_joints, 2]), the maximum confidence of the keypoints
        z heatmaps should be numpy.ndarrayr   zbatch_images should be 4-ndimr   r   r   r.   r   )r   r   r   Ng        )r"   r   r   ndimr2   ZreshapeZargmaxZamaxZtileZastyper   rb   Zgreater)
r)   r\   
batch_size
num_jointswidthZheatmaps_reshapedidxrX   rW   Z	pred_maskr   r   r   r_     s"   


,2zKptPostProcess.get_max_predskernelc                 C   s  |d d }|j d }|j d }|j d }|j d }t|D ]a}t|D ]Z}	t|||	f }
t|d|  |d|  f}|||	f  ||| || f< t|||fd}||| || f  |||	f< |||	f  |
t|||	f  9  < q$q|S )Nr   r   r   r   )r2   rK   r   maxr   rd   r3   ZGaussianBlur)r)   rP   rq   borderrm   rn   heightro   r%   jZ
origin_maxZdrr   r   r   gaussian_blur7  s   



$$(zKptPostProcess.gaussian_blurrh   coordc                 C   s  |j d }|j d }t|d }t|d }d|  k r"|d k rn |S d|  k r1|d k rn |S d|| |d  || |d    }d||d  | ||d  |   }d|| |d  d|| |   || |d    }	d||d  |d  ||d  |d   ||d  |d   ||d  |d    }
d||d  | d|| |   ||d  |   }t|g|gg}t|	|
g|
|gg}|	| |
d  dkr|j}| | }tjt|jdd}||7 }|S )Nr   r   r   r   r^   rQ   )r2   r#   r   r   IrU   r1   rE   )r)   rh   rw   re   rf   ri   rj   ZdxZdyZdxxZdxyZdyyZ
derivativeZhessianZ
hessianinvoffsetr   r   r   
dark_parseH  s:   

$$44
zKptPostProcess.dark_parserH   c                 C   sr   |  ||}t|d}t|}t|jd D ]}t|jd D ]}| || | || | |||f< q!q|S )zV
        refer to https://github.com/ilovepose/DarkPose/lib/core/inference.py
        g|=r   r   )rv   r   maximumlogrK   r2   rz   )r)   rh   rH   r]   rg   rL   r   r   r   r`   b  s   
&zKptPostProcess.dark_postprocessN)T)r   )r<   r=   r>   r?   r*   r   Kptsr5   r   rB   r;   r#   rS   r   r_   rv   rz   r`   r   r   r   r   rN      s6    
"
*rN   )ra   typingr   r   r   r   r   numpyr   r   Z
utils.depsr	   r
   Zutils.benchmarkr   Zobject_detection.processorsr   r3   r#   floatrA   rB   r}   r   Ztimeitr   rG   rM   rN   r   r   r   r   <module>   sP   
(\



