
    ^jV                     V   d Z ddlZddlZddlmZ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mZ dd	lmZmZmZmZmZmZ dd
lmZmZ ddlmZmZm Z m!Z!m"Z"  e        rddl#m$Z$ ddl%m&Z&m'Z' erddl(m)Z)  e!jT                  e+      Z, G d ded      Z-	 	 d/de.e/z  ej`                  z  de1de1de2de2f
dZ3de2dej`                  dej`                  dej`                  fdZ4d Z5d ej`                  d!e.ej`                  ej`                  f   fd"Z6d0d#ej`                  d$ej`                  d%e1d!ej`                  fd&Z7d#ej`                  d'ej`                  d(ej`                  d)ej`                  d!ej`                  f
d*Z8d+ej`                  d!ej`                  fd,Z9e G d- d.e             Z:d.gZ;y)1z"Image processor class for VitPose.    N)TYPE_CHECKINGUnion)
functional   )TorchvisionBackend)BatchFeature)group_images_by_shapereorder_images)IMAGENET_DEFAULT_MEANIMAGENET_DEFAULT_STDChannelDimension
ImageInputPILImageResamplingSizeDict)ImagesKwargsUnpack)
TensorTypeauto_docstringis_scipy_availableloggingrequires_backends)inv)affine_transformgaussian_filter   )VitPoseEstimatorOutputc                   2    e Zd ZU dZedz  ed<   edz  ed<   y)VitPoseImageProcessorKwargsaI  
    do_affine_transform (`bool`, *optional*):
        Whether to apply an affine transformation to the input images based on the bounding boxes.
    normalize_factor (`float`, *optional*, defaults to `200.0`):
        Width and height scale factor used for normalization when computing center and scale from bounding boxes.
    Ndo_affine_transformnormalize_factor)__name__
__module____qualname____doc__bool__annotations__float     /var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/transformers/models/vitpose/image_processing_vitpose.pyr   r   7   s     $dl"r)   r   F)totalboximage_widthimage_heightr    padding_factorc                 .   | dd \  }}}}||z  }	t        j                  ||dz  z   ||dz  z   gt         j                        }
||	|z  kD  r	|dz  |	z  }n||	|z  k  r||	z  }t        j                  ||z  ||z  gt         j                        }||z  }|
|fS )a  
    Encodes a bounding box in COCO format into (center, scale).

    Args:
        box (`Tuple`, `List`, or `np.ndarray`):
            Bounding box in COCO format (top_left_x, top_left_y, width, height).
        image_width (`int`):
            Image width.
        image_height (`int`):
            Image height.
        normalize_factor (`float`):
            Width and height scale factor.
        padding_factor (`float`):
            Bounding box padding factor.

    Returns:
        tuple: A tuple containing center and scale.

        - `np.ndarray` [float32](2,): Center of the bbox (x, y).
        - `np.ndarray` [float32](2,): Scale of the bbox width & height.
    N         ?dtype      ?)nparrayfloat32)r,   r-   r.   r    r/   
top_left_x
top_left_ywidthheightaspect_ratiocenterscales               r*   box_to_center_and_scaler@   D   s    : -0G)J
E6-LXXzECK/fsl1JKSUS]S]^F|f$$|+	&	&%HHe..9I0IJRTR\R\]EN"E5=r)   theta
size_inputsize_dstsize_targetc                    t        j                  |       } t        j                  dt         j                        }|d   |d   z  }|d   |d   z  }t	        j
                  |       |z  |d<   t	        j                  |        |z  |d<   |d|d   z  t	        j
                  |       z  d|d   z  t	        j                  |       z  z   d|d   z  z   z  |d	<   t	        j                  |       |z  |d
<   t	        j
                  |       |z  |d<   |d|d   z  t	        j                  |       z  d|d   z  t	        j
                  |       z  z
  d|d   z  z   z  |d<   |S )a  
    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).

    Source: https://github.com/open-mmlab/mmpose/blob/master/mmpose/core/post_processing/post_transforms.py

    Args:
        theta (`float`):
            Rotation angle in degrees.
        size_input (`np.ndarray`):
            Size of input image [width, height].
        size_dst (`np.ndarray`):
            Size of output image [width, height].
        size_target (`np.ndarray`):
            Size of ROI in input plane [w, h].

    Returns:
        `np.ndarray`: A matrix for transformation.
    )   r   r3   r   r   r   r   r   r   g      r2   r   rF   r   r   r   r   r   rF   )r6   deg2radzerosr8   mathcossin)rA   rB   rC   rD   matrixscale_xscale_ys          r*   get_warp_matrixrU   p   sX   ( JJuEXXfBJJ/FqkKN*GqkKN*G88E?W,F4LHHUO#g-F4Lz!}txx.z!}1DtxxPU1VVY\_jkl_mYmmF4L 88E?W,F4L88E?W,F4Lz!}txx.z!}1DtxxPU1VVY\_jkl_mYmmF4L Mr)   c           	         t        | j                  d         D cg c]	  }| d|f    }}t        j                  |g dg      }t	        |      }|d   |d   |d   |d   |d   |d	   f\  |d<   |d<   |d<   |d<   |d	<   |d<   |D cg c]  }t        |||d
       }}t        j                  |d      }|S c c}w c c}w )a[  
    This function implements cv2.warpAffine function using affine_transform in scipy. See https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.affine_transform.html and https://docs.opencv.org/4.x/d4/d61/tutorial_warp_affine.html for more details.

    Note: the original implementation of cv2.warpAffine uses cv2.INTER_LINEAR.
    .)r   r   r   rK   rJ   rH   rG   rL   rI   r   )output_shapeorderaxis)rangeshaper6   vstackr   r   stack)	srcMsizeichannelsM_scipyM_invchannelnew_srcs	            r*   scipy_warp_affineri      s     &+399R=%9:CF:H: iiI'GLEddddddTPE$KteDk5;dU4[ \ddPWTKdGdhhwR(GN# ; es   B7B<heatmapsreturnc                    t        | t        j                        st        d      | j                  dk7  rt        d      | j                  \  }}}}| j                  ||df      }t        j                  |d      j                  ||df      }t        j                  |d      j                  ||df      }t        j                  |d      j                  t        j                        }|ddddd	f   |z  |ddddd	f<   |dddddf   |z  |dddddf<   t        j                  t        j                  |d      d
kD  |d      }||fS )a  Get keypoint predictions from score maps.

    Args:
        heatmaps (`np.ndarray` of shape `(batch_size, num_keypoints, height, width)`):
            Model predicted heatmaps.

    Returns:
        tuple: A tuple containing aggregated results.

        - coords (`np.ndarray` of shape `(batch_size, num_keypoints, 2)`):
            Predicted keypoint location.
        - scores (`np.ndarray` of shape `(batch_size, num_keypoints, 1)`):
            Scores (confidence) of the keypoints.
    zHeatmaps should be np.ndarrayr1   z Heatmaps should be 4-dimensionalrW   rF   r   )r   r   rF   Nr   g        )
isinstancer6   ndarray	TypeErrorndim
ValueErrorr]   reshapeargmaxamaxtileastyper8   where)	rj   
batch_sizenum_keypoints_r;   heatmaps_reshapedidxscorespredss	            r*   get_keypoint_predictionsr      s-    h

+788}};<<*2..'Jq% ((*mR)HI
))%q
)
1
1:}a2P
QCWW&*22Jq3QRFGGC#**2::6E1a7^e+E!Q'N1a7^u,E!Q'NHHRWWVY/#5ubAE&=r)   coordsbatch_heatmapskernelc                    |j                   \  }}}}| j                   d   }|dk(  s||k(  st        d      t        |dz
  dz        }t        j                  |D 	
cg c]!  }	|	D 
cg c]  }
t        |
d||fd       c}
# c}
}	      }t        j                  |dd	      }t        j                  |      }t        j                  |d
d      j                         }| d   dz   | d   dz   |dz   z  z   }||dz   |dz   z  t        j                  d||z        j                  d|      z  z  }|j                  t              j                  dd      }||   }||dz      }|||z   dz      }|||z   dz      }|||z
  dz
     }||dz
     }||dz
  |z
     }d||z
  z  }d||z
  z  }t        j                  ||gd      }|j                  ||dd      }|d|z  z
  |z   }|d|z  z
  |z   }d||z
  |z
  |z   |z   |z
  |z
  |z   z  }t        j                  ||||gd      }|j                  ||dd      }t        j                  j                  |t        j                   t        j"                        j$                  t        j&                  d      z  z         }| t        j(                  d||      j+                         z  } | S c c}
w c c}
}	w )a  DARK post-processing. Implemented by unbiased_data_processing.

    Paper references:
    - Huang et al. The Devil is in the Details: Delving into Unbiased Data Processing for Human Pose Estimation (CVPR 2020).
    - Zhang et al. Distribution-Aware Coordinate Representation for Human Pose Estimation (CVPR 2020).

    Args:
        coords (`np.ndarray` of shape `(num_persons, num_keypoints, 2)`):
            Initial coordinates of human pose.
        batch_heatmaps (`np.ndarray` of shape `(batch_size, num_keypoints, height, width)`):
            Batched heatmaps as predicted by the model.
            A batch_size of 1 is used for the bottom up paradigm where all persons share the same heatmap.
            A batch_size of `num_persons` is used for the top down paradigm where each person has its own heatmaps.
        kernel (`int`, *optional*, defaults to 3):
            Gaussian kernel size (K) for modulation.

    Returns:
        `np.ndarray` of shape `(num_persons, num_keypoints, 2)` ):
            Refined coordinates.
    r   r   zQThe batch size of heatmaps should be 1 or equal to the batch size of coordinates.rF   g?rH   )sigmaradiusaxesgMbP?2   )rG   rG   rK   rK   edge)mode).r   ).r   rW   r   r2   rZ   zijmn,ijnk->ijmk)r]   rq   intr6   r7   r   cliplogpadflattenarangerr   rv   concatenatelinalgr   finfor8   epseyeeinsumsqueeze)r   r   r   rx   ry   r<   r;   
num_coordsr   rj   heatmapbatch_heatmaps_padindexi_ix1iy1ix1y1ix1_y1_ix1_iy1_dxdy
derivativedxxdyydxyhessians                              r*   "post_dark_unbiased_data_processingr      s   * 0>/C/C,JvuaJ!OzZ7lmm&1*"#FXX +	
 goo[b_WC8HvVo	
N WW^UB7NVVN+N0PW]^ffh6NQ&.1"4!CCE	eaiFQJ'"))AzM7Q*R*Z*Z[]_l*mmmELL%%b!,E	E	"B
UQY
'C
UU]Q.
/Cuu}q01E !23Geai(Deai%/0D	d
	B	d
	BRq1J##Jq!DJ
B,
C
B,
C
s"R'",t3d:WD
ECnnc3S1:Gooj-A>GiimmGbhhrzz&:&>&>&JJKG
bii)7J?GGIIFM; p	
s   	J>
$J9<J>
9J>
r>   r?   output_sizec                    | j                   d   dvrt        d      t        |      dk7  rt        d      t        |      dk7  rt        d      t        |      dk7  rt        d      |dz  }|d   |d	   d
z
  z  }|d	   |d   d
z
  z  }t        j                  |       }| ddd	f   |z  |d	   z   |d	   dz  z
  |ddd	f<   | dddf   |z  |d   z   |d   dz  z
  |dddf<   |S )ao  Get final keypoint predictions from heatmaps and apply scaling and
    translation to map them back to the image.

    Note:
        num_keypoints: K

    Args:
        coords (`np.ndarray` of shape `(num_keypoints, ndims)`):

            * If ndims=2, corrds are predicted keypoint location.
            * If ndims=4, corrds are composed of (x, y, scores, tags)
            * If ndims=5, corrds are composed of (x, y, scores, tags,
              flipped_tags)

        center (`np.ndarray` of shape `(2,)`):
            Center of the bounding box (x, y).
        scale (`np.ndarray` of shape `(2,)`):
            Scale of the bounding box wrt original image of width and height.
        output_size (`np.ndarray` of shape `(2,)`):
            Size of the destination heatmaps in (height, width) format.

    Returns:
        np.ndarray: Predicted coordinates in the images.
    r   )rF   r1      z5Coordinates need to have either 2, 4 or 5 dimensions.rF   z9Center needs to have 2 elements, one for x and one for y.z,Scale needs to consist of a width and heightz2Output size needs to consist of a height and width      i@r   r5   Nr2   )r]   rq   lenr6   	ones_like)r   r>   r?   r   rT   rS   target_coordss          r*   transform_predsr     s   2 ||Ai'PQQ
6{aTUU
5zQGHH
;1MNN EME Ah+a.3./GAh+a.3./GLL(M A,06!9<uQx#~MM!Q$ A,06!9<uQx#~MM!Q$r)   bboxesc                 z    | dddf   | dddf   z   dz
  | dddf<   | dddf   | dddf   z   dz
  | dddf<   | S )a  
    Converts bounding boxes from the COCO format to the Pascal VOC format.

    In other words, converts from (top_left_x, top_left_y, width, height) format
    to (top_left_x, top_left_y, bottom_right_x, bottom_right_y).

    Args:
        bboxes (`np.ndarray` of shape `(batch_size, 4)):
            Bounding boxes in COCO format.

    Returns:
        `np.ndarray` of shape `(batch_size, 4) in Pascal VOC format.
    NrF   r   r   r   r(   )r   s    r*   coco_to_pascal_vocr   <  sW     !Q$<&A,.2F1a4L!Q$<&A,.2F1a4LMr)   c            '           e Zd ZdZeZdgZeZe	Z
dddZdZdZdZdZdee   f fd	Zed
edeeee         ej.                  z  dee   def fd       Z	 d5d
edeeee         ej.                  z  dz  dededeedf   dz  defdZej@                  jB                  ddde"e   de"e   dede#ddfd       Z$	 	 	 d6d
ed   dede#dddede#d ed!ed"ed#eee   z  dz  d$eee   z  dz  d%edz  d&e#dz  d'edz  d(ee%z  dz  d)ed*edeej.                  z  dz  def&d+Z&	 d7d,ej.                  dej.                  dej.                  d-e'fd.Z(	 	 	 d8d/d0deeee         ej.                  z  d1e'd2edz  d3e%ee"   z  dz  f
d4Z) xZ*S )9VitPoseImageProcessorz6Torchvision backend for VitPose with affine transform.pixel_values      )r<   r;   Tr   kwargsc                 $    t        |   di | y )Nr(   )super__init__)selfr   	__class__s     r*   r   zVitPoseImageProcessor.__init___  s    "6"r)   imagesboxesrk   c                 &    t        |   ||fi |S )a  
        boxes (`list[list[list[float]]]` or `np.ndarray`):
            List or array of bounding boxes for each image. Each box should be a list of 4 floats representing the
            bounding box coordinates in COCO format (top_left_x, top_left_y, width, height).
        )r   
preprocess)r   r   r   r   r   s       r*   r   z VitPoseImageProcessor.preprocessb  s     w!&%:6::r)   Ndo_convert_rgbinput_data_formatdeviceztorch.devicec                 \    | j                  ||||      }||d<    | j                  |fi |S )z"Handle extra inputs beyond images.)r   r   r   r   r   )_prepare_image_like_inputs_preprocess)r   r   r   r   r   r   r   s          r*   _preprocess_image_like_inputsz3VitPoseImageProcessor._preprocess_image_like_inputsp  sG     00.L]fl 1 
  wt1&11r)   imageztorch.Tensorr>   r?   rotationrb   c                    t        ||dz  t        j                  |j                  |j                  f      dz
  |dz        }|j                  ddd      j                         j                         }t        |||j                  |j                  f      }t        j                  |      j                  ddd      j                  |j                        }	|	S )z7Apply an affine transformation to a torch tensor image.g       @r5   r   r   rF   r   )r`   ra   rb   )rU   r6   r7   r;   r<   permutecpunumpyri   torch
from_numpytor   )
r   r   r>   r?   r   rb   transformationimage_nptransformed_nptransformeds
             r*   r   z&VitPoseImageProcessor.affine_transform  s     )fslBHHdjj$++-F$G#$MuW\}
 ==Aq)--/557*x>QUQ\Q\^b^h^hPij&&~6>>q!QGJJ5<<Xr)   	do_resizeresamplez7PILImageResampling | tvF.InterpolationMode | int | Nonedo_center_crop	crop_size
do_rescalerescale_factordo_normalize
image_mean	image_stddo_padpad_sizedisable_groupingreturn_tensorsr   r    c           	         |n|rlg }t        ||      D ]Y  \  }}|D ]O  }t        ||j                  |j                  |      \  }}| j	                  |||d|      }|j                  |       Q [ |}t        ||      \  }}i }|j                         D ]   \  }}| j                  ||||	|
|      }|||<   " t        ||      } t        d| i|      S )z!Custom preprocessing for VitPose.)r-   r.   r    r   )r   rb   )r   r   )datatensor_type)zipr@   r;   r<   r   appendr	   itemsrescale_and_normalizer
   r   )!r   r   r   rb   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r   r   transformed_imagesr   image_boxesr,   r>   r?   transformed_imagegrouped_imagesgrouped_images_indexprocessed_images_groupedr]   stacked_imagesprocessed_imagess!                                    r*   r   z!VitPoseImageProcessor._preprocess  s   . !4!#&)&%&8 	A"{& AC$;$(JJ%)[[)9	%MFE )-(=(=eVU]^ei(=(j%&--.?@A	A (F/DV^n/o,,#% %3%9%9%; 	=!E>!77
NL*V_N /=$U+		=
 **BDXY.2B!CQ_``r)   rj   r   c                     |j                   \  }}}}t        |      \  }	}
t        |	||      }t        |      D ]  }t	        ||   ||   ||   ||g      ||<   ! ||
fS )zRGet final keypoint predictions from heatmaps and transform them back to the image.r   )r>   r?   r   )r]   r   r   r\   r   )r   rj   r>   r?   r   rx   rz   r<   r;   r   r}   r~   rc   s                r*   keypoints_from_heatmapsz-VitPoseImageProcessor.keypoints_from_heatmaps  sy     (0~~$
Avu1(;268FSz" 	pA&uQxq	q`fhm_noE!H	pf}r)   outputsr   kernel_size	thresholdtarget_sizesc                 D   t        | d       |j                  j                  \  }}}}||t        |      k7  rt	        d      t        j                  |dft
        j                        }	t        j                  |dft
        j                        }
t        t        j                  |       }t        |      D ]|  }|4||   d   ||   d   }}t        j                  ||||g      }||   |z  ||<   | j                  d   | j                  d	   }}t        ||   ||
      \  }}||	|ddf<   ||
|ddf<   ~ | j                  |j                  j!                         j#                         |	|
|      \  }}t        j                  |dft
        j                        }|	ddddf   |ddddf<   |
ddddf   |ddddf<   t%        j&                  |      }t%        j&                  |      }t%        j(                  d|      }t%        j&                  t+        |            }g }t-        |||      }|D ]k  }g }|D ]Q  }t/        |      \  }}} |j1                         }|}!|||kD  }"||"   }||"   }|!|"   }!|||!| d}#|j3                  |#       S |j3                  |       m |S )a  
        Transform the heatmaps into keypoint predictions and transform them back to the image.

        Args:
            outputs (`VitPoseEstimatorOutput`):
                VitPoseForPoseEstimation model outputs.
            boxes (`list[list[list[float]]]` or `np.ndarray`):
                List or array of bounding boxes for each image. Each box should be a list of 4 floats representing the bounding
                box coordinates in COCO format (top_left_x, top_left_y, width, height).
            kernel_size (`int`, *optional*, defaults to 11):
                Gaussian kernel size (K) for modulation.
            threshold (`float`, *optional*, defaults to None):
                Score threshold to keep object detection predictions.
            target_sizes (`torch.Tensor` or `list[tuple[int, int]]`, *optional*):
                Tensor of shape `(batch_size, 2)` or list of tuples (`tuple[int, int]`) containing the target size
                `(height, width)` of each image in the batch. If unset, predictions will be resize with the default value.
        Returns:
            `list[list[Dict]]`: A list of dictionaries, each dictionary containing the keypoints and boxes for an image
            in the batch as predicted by the model.
        r   NzTMake sure that you pass in as many target sizes as the batch dimension of the logitsrF   r3   r   r   r;   r<   )r-   r.   r   r1   )	keypointsr}   labelsbbox)r   rj   r]   r   rq   r6   rN   r8   list	itertoolschainr\   r7   rb   r@   r   r   r   r   tensorr   r   r   nextr   r   )$r   r   r   r   r   r   rx   ry   rz   centersscalesflattened_boxesrc   r-   r.   scale_factorr;   r<   r>   r?   r~   r}   	all_boxesposesr   bboxes_xyxyresultspose_bbox_pairsimage_bboxesimage_resultsposescore	bbox_xyxykeypoints_labelskeeppose_results$                                       r*   post_process_pose_estimationz2VitPoseImageProcessor.post_process_pose_estimation  s   8 	$(*1*:*:*@*@'
M1a#
c,6G(Gstt((J?"**=:q/<y67z" 	!A',8OA,>QPQ@R\!xxlKQ](^_%4Q%7,%F" IIg.		(0C6E3OA4FTYhnoMFE"GAqDM F1a4L	! 44  "((*GVK 5 
v HHj!_BJJ?	#AqsFO	!QqS&"1ac6N	!QqS&U#f%a/ll#5i#@A79eV[9! 	*L;=M! 
2)-o)>&eY#) ( 9,D:D!$KE'7'=$,0EM]gpq$$[1
2 NN=)	* r)   )N)Tr   N)   )r  NN)+r!   r"   r#   r$   r   valid_kwargsmodel_input_namesr   r   r   r   rb   r   r   r   r    r   r   r   r   r   r'   r6   rn   r   r   r%   r   r   strr   r   compilerdisabletupler   r   r   r   r   r   r  __classcell__)r   s   @r*   r   r   P  sI   @.L'(&J$IC(DJL#(C!D # ;; De%&3; 45	;
 
; ;& 5922 De%&3d:2 	2
 ,2 c>)*T12 
2" ^^ e U|	
   
 D %)"'*.'-a^$-a -a 	-a
 L-a -a -a -a -a -a DK'$.-a 4;&--a t-a T/-a +-a  j(4/!-a" "#-a$  %-a& bjj 4''-a* 
+-ah ** 

 zz	
 & "&8<F)F De%&3F 	F
 4<F !4;.5Fr)   r   )r   g      ?)r   )<r$   r   rO   typingr   r   r   r6   r   torchvision.transforms.v2r   tvFimage_processing_backendsr   image_processing_utilsr   image_transformsr	   r
   image_utilsr   r   r   r   r   r   processing_utilsr   r   utilsr   r   r   r   r   scipy.linalgr   scipy.ndimager   r   modeling_vitposer   
get_loggerr!   loggerr   r  r   rn   r   r'   r@   rU   ri   r   r   r   r   r   __all__r(   r)   r*   <module>r-     s   )   '   7 ; 2 E  5   ?8			H	%	#,e 	#" $ )	

	")) ) 	)
 )X"5 "bjj "BJJ "]_]g]g "J4rzz eBJJ

<R6S B9rzz 92:: 9_b 9kmkuku 9x-BJJ -

 -2:: -\^\f\f -kmkuku -`rzz bjj ( F. F FR #
#r)   