o
    ॵi7                     @   s`  d dl Z d dlmZ d dlZd dlmZmZmZm	Z	 d dl
Z
d dlZd dlmZ d dlm  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  d d	l!m"Z" d d
l#m$Z$m%Z%m&Z&m'Z' d dl(m)Z) d dl*m+Z+ d dl,m-Z- e.d e- Z/dddZ0dddZ1dddZ2dddZ3e)j4e+j5ej5dG dd de&Z6dS )    N)AnyDictListUnion)	animation)writers)MultipleLocator)	Pipelines)KeypointsTypes)
OutputKeys)pipeline)InputModelPipelineTensor)	PIPELINES)Tasks)
get_loggerAgg   c           	      C   sf  ddgddgddgddgd	d
gddgddgddgddgddgddgdd	gddgddgd
dgg}| j \}}t||f}|D ]}| |d  ||d < q=|dkrtddgddgddgddgd	d	gddgddgddgddgddgddgddgdd
gddgd
dgg}td}||d d df  ||d d df < |d |d  d |d< |d |d  d |d< |}|S )Nr                                 	      
         r      )r$   r         ?)shapenpzerosarray)	joints
joints_nbrlst_mappingsnbrdimh36m_jointsmappinglst_mappings_17h36m_joints_17 r4   f/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/pipelines/cv/body_3d_keypoints_pipeline.pyconvert_2_h36m!   s,   *$
"

r6         .@c              	   C   s&  |d u r| S |d |d  \}}|dks|dkr| S t |}t | }|dks*|dkr,| S ||  }	||  }
t|D ]V}t|	t| | d || d   }t|
t| | d || d   }d| | | d  ||| d   | | d< d| | | d  ||| d   | | d< q:| S )Nr   r   g      ?)lenranger(   expabs)cur_ptspre_ptsbboxsmooth_xsmooth_ywhsize_presize_curfactor_xfactor_yiw_xw_yr4   r4   r5   
smooth_pts9   s"   

((,.rJ   c                 C   st   | j d |j d ksJ g }d }t| j d D ]}t| | ||| dd dd||}|| |}qt|S )Nr   r   )r'   r9   rJ   reshapeappendr(   r*   )lst_kps
lst_bboxesr?   r@   lst_smoothed_kpsprev_ptsrG   smoothed_cur_kpsr4   r4   r5   	smoothingQ   s   


rS   c                 C   sh   |   } |  }| jd |jd ksJ t| |} g }t| jd D ]}t| | |d}|| q"|S )Nr   r,   )squeezer'   rS   r9   r6   rM   )rN   rO   r,   	keypointsrG   h36m_joints_2dr4   r4   r5   convert_2_h36m_data`   s   
rX   )module_namec                       s   e Zd Zdef fddZdedeeef fddZdeeef deeef fdd	Z	deeef deeef fd
dZ
deeejf fddZdd Z  ZS )Body3DKeypointsPipelinemodelc                    s   t  jdd|i| | j| _| j  d| _ttj| jt	j
 r#dndd| _t| jjjjdr;| jjjjj| _dS | jjjjj| _dS )	aj  Human body 3D pose estimation.

        Args:
            model (str): model id on modelscope hub.
            kwargs (dict, `optional`): Extra kwargs passed into the preprocessor's constructor.
        Example:
            >>> from modelscope.pipelines import pipeline
            >>> body_3d_keypoints = pipeline(Tasks.body_3d_keypoints,
                model='damo/cv_hdformer_body-3d-keypoints_video')
            >>> test_video_url = 'https://modelscope.oss-cn-beijing.aliyuncs.com/test/videos/Walking.54138969.mp4'
            >>> output = body_3d_keypoints(test_video_url)
            >>> print(output)
        r[   z*damo/cv_hrnetv2w32_body-2d-keypoints_imagegpucpu)r[   device	MAX_FRAMENr4   )super__init__r[   keypoint_model_3devalhuman_body_2d_kps_det_pipeliner   r   body_2d_keypointstorchcudais_availablehuman_body_2d_kps_detectorhasattrcfgINPUTr_   	max_frame)selfr[   kwargs	__class__r4   r5   ra   s   s   
z Body3DKeypointsPipeline.__init__inputreturnc                 C   sf  || _ | | j }dt|krddd}|S g }g }t|D ]Q\}}| |}g |dkr:dd| d}|  S |d d }	|d d }
t|d d  }|	|
 |	t
t|	d	|g  |d
 | jkro nqt|t|ddf}t|t|df}t| jjjjdr| jjjjjn| jjjjj}t|||d}t|}d|d}|S )Nr   Fzget video frame failed.successmsgboxesz%fail to detect person at image frame rV   scoresrK   r   r   r   r   IN_NUM_JOINTSrT   T)ru   input_2d_pts)	video_urlread_video_framesr8   	enumerateri   getr(   r*   maxrM   listrL   rm   rj   rb   rk   r[   MODELry   n_jointsrX   )rn   rr   video_framesresall_2d_posesall_boxes_with_socrerG   framekps_2dboxposescoreall_2d_poses_npall_boxes_np	joint_numkps_2d_h36m_17r4   r4   r5   
preprocess   s`   







z"Body3DKeypointsPipeline.preprocessc                 C   sN   |d sddd}|S |d }| j |}| j |}tddifi |}|S )Nru   Fzpreprocess failed.rt   rz   T)rb   r   forwarddict)rn   rr   r   rz   outputsr4   r4   r5   r      s   
zBody3DKeypointsPipeline.forwardc                 K   s   | dd }|d u rtjddj}tjg tjg tj|i}|d s(| j|tj< |S |t	j
 }|j  d }d| jj v rI| || ||tj< ||tj< | j|tj< |S )Noutput_videoz.mp4)suffixru   r   render)r~   tempfileNamedTemporaryFilenamer   	KEYPOINTS
TIMESTAMPSOUTPUT_VIDEOr{   r
   POSES_CAMERAdatar]   numpyrb   rk   keysrender_prediction
timestamps)rn   rr   ro   output_video_pathr   posespred_3d_poser4   r4   r5   postprocess   s(   


z#Body3DKeypointsPipeline.postprocessr{   c                 C   s   dd }g }g | _ t|trt|}| std| n|}|tj| _	| j	du s1| j	dkr7td| d}	 |
 \}}|sCn| j ||| j	 d |d	7 }|| || jkr^nq:|  |S )
a  Read video from local video file or from a video stream URL.

        Args:
            video_url (str or cv2.VideoCapture): Video path or video stream.

        Raises:
            Exception: Open video fail.

        Returns:
            [nd.array]: List of video frames.
        c                 S   s.   t | d\}}t |d\}}d|||f }|S )N<   z%02d:%02d:%06.3f)divmod)secondsmsrB   timer4   r4   r5   timestamp_format   s   zCBody3DKeypointsPipeline.read_video_frames.<locals>.timestamp_formatz1modelscope error: %s cannot be decoded by OpenCV.Nr   z/modelscope error: %s cannot get video fps info.T)r   r   )r   
isinstancestrcv2VideoCaptureisOpened	Exceptionr~   CAP_PROP_FPSfpsreadrM   rm   release)rn   r{   r   framescap	frame_idxretr   r4   r4   r5   r|      sB   




z)Body3DKeypointsPipeline.read_video_framesc                    s  j d g dddgddgddgddgddgddgdd	gdd
gd
dgd
dgd
dgddgddgddgddgddggt }tj|dd |  td} j|  j	|  j
|  d  d  d  dd  dd  dd | jjjj}| jjjj} || ddddf }ddddf }ddddf }	 |||	d\}
 fdd}||||	}fdd}tj||| j|
|fd }td! }|| ji d"d#}|j||d$ dS )%zrender predict result 3d poses.

        Args:
            pose3d_cam_rr (nd.array): [frame_num, joint_num, joint_dim], 3d pose joints
            output_video_path (str): output path for video
        Returns:
        r   )r#   r   r   r   r   r!   r   r   r   r   r   r!   r   r   r    r#   r   r   r%   r   r   r"   F)auto_add_to_figurer&   XYZrK   Nzr.c           
         s   i }t D ]8\}}|d |d }}|v rd}nd} j| | | | g|| || g|| || gd|d}	|	d ||< q|S )zrender bones in skeleton

            Args:
                xs (nd.array): [joint_num, joint_channel]
                ys (nd.array): [joint_num, joint_channel]
                zs (nd.array): [joint_num, joint_channel]
            r   r   redbluer   )	linewidthcolor)r}   plot)
xsyszsbonesidxedgeindex1index2
edge_colorconnect)axedgesleft_pointsr4   r5   renderBones<  s   z>Body3DKeypointsPipeline.render_prediction.<locals>.renderBonesc                    s   | dddf }| dddf }| dddf }t  D ];\}}|d |d }}	|| ||	 f}
|| ||	 f}|| ||	 f}|| |
 || | || |d q||| ||d d| d krxtd|  d  ||fS )	aM  update animation

            Args:
                frame_idx (int): frame index
                points (mpl_toolkits.mplot3d.art3d.Line3D): skeleton points ploter
                bones (dict[int, mpl_toolkits.mplot3d.art3d.Line3D]): connection ploter

            Returns:
                tuple: points and bones ploter
            Nr   r   r   zd   z
rendering /)r}   	set_xdata	set_ydataset_3d_propertiesset_dataloggerinfo)r   pointsr   r   r   r   r   r   r   r   x1x2y1y2z1z2)r   	frame_numpose3d_cam_rrr4   r5   updateU  s    z9Body3DKeypointsPipeline.render_prediction.<locals>.update)figfuncr   intervalfargsffmpegi   )r   metadatabitrate)writer)r'   pltfigurep3Axes3Dadd_axesr   xaxisset_major_locatoryaxiszaxis
set_xlabel
set_ylabel
set_zlabelset_xlimset_ylimset_zlimrb   rk   r   azimelev	view_initr   r   FuncAnimationr   r   save)rn   r   r   r   x_major_locatorr   r   xyr   r   r   r   r   aniWriterr   r4   )r   r   r   r   r   r5   r     sT   
&$



 z)Body3DKeypointsPipeline.render_prediction)__name__
__module____qualname__r   ra   r   r   r   r   r   r   r   r   r   r|   r   __classcell__r4   r4   rp   r5   rZ   o   s    ","1rZ   )r   )r7   r7   )7datetimeos.pathpathospr   typingr   r   r   r   r   
matplotlibmatplotlib.pyplotpyplotr   mpl_toolkits.mplot3d.axes3dmplot3daxes3dr   r   r(   rf   r   matplotlib.animationr   matplotlib.tickerr   modelscope.metainfor	   Bmodelscope.models.cv.body_3d_keypoints.canonical_pose.body_3d_poser
   modelscope.outputsr   modelscope.pipelinesr   modelscope.pipelines.baser   r   r   r   modelscope.pipelines.builderr   modelscope.utils.constantr   modelscope.utils.loggerr   user   r6   rJ   rS   rX   register_modulebody_3d_keypointsrZ   r4   r4   r4   r5   <module>   s>   




