
    >|h4                     H   d dl Z d dlZd dlZd dlZd dl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mZ 	 d dlmZ da	 	 	 dd	Zd
 ZddZddZ ed      dd       ZddZ ed      dd       Zd ZddZddZddZ d Z!ddZ"y# e$ r	 d dlmZ Y \w xY w)    N)io)color)jit)urlparse)download_url_to_file
HASH_REGEX)get_dir)_get_torch_homec
                    || }|| }||}||}||z  dz   }
|	|z  dz   }t        j                  ||ft         j                        }t        |      D ]z  }t        |      D ]j  }|t	        j
                  t	        j                  |dz   |
z
  ||z  z  d      dz  t	        j                  |dz   |z
  ||z  z  d      dz  z          z  ||   |<   l | |r|t        j                  |      z  }|S )N      ?dtype      g       @)npemptyfloat32rangemathexppowsum)sizesigma	amplitude	normalizewidthheight
sigma_horz
sigma_vert	mean_horz	mean_vertcenter_xcenter_ygaussijs                  S/var/www/html/test/engine/venv/lib/python3.12/site-packages/face_alignment/utils.py	_gaussianr)      s,   
 }~

5 3&H6!C'HHHfe_BJJ7E6] pu 	pA#dhh1q58;KU";$%&2(*-2.04!a%(:Jz\bOb9cef0gjm0m2n 0o 'p pE!HQK	pp u%L    c           	      J   t        j                  |d   d|z  z
        t        j                  |d   d|z  z
        g}t        j                  |d   d|z  z         t        j                  |d   d|z  z         g}|d   | j                  d   kD  s%|d   | j                  d   kD  s|d   dk  s|d   dk  r| S d|z  dz   }t        t	        |      }|ant        }t        t        d|d                t        t        |d   | j                  d               t        t        d|d               z
  t        t        d|d                z   g}t        t        d|d                t        t        |d   | j                  d               t        t        d|d               z
  t        t        d|d                z   g}t        t        d|d               t        t        |d   | j                  d               g}	t        t        d|d               t        t        |d   | j                  d               g}
|d   dkD  r|d   dkD  sJ | |
d   dz
  |
d   |	d   dz
  |	d   f   ||d   dz
  |d   |d   dz
  |d   f   z   | |
d   dz
  |
d   |	d   dz
  |	d   f<   d| | dkD  <   | S )Nr      r      )r   floorshapegauss_kernelr)   intmaxmin)imagepointr   ulbrr   gg_xg_yimg_ximg_ys              r(   draw_gaussianr=   0   s    **U1XE	)
*DJJuQx!e)7K,L	MB
**U1XE	)
*DJJuQx!e)7K,L	MB
1A"Q%%++a."8BqEAIAQRu9q=DdOs1r!uf~C1u{{1~$> ?#c!RPQUmBT TWZ[^_`cefgchbh[iWj j
kCs1r!uf~C1u{{1~$> ?#c!RPQUmBT TWZ[^_`cefgchbh[iWj j
kCQ1SAA%?!@AEQ1SAA%?!@AEFQJ3q6A:&%E!HqLq)58a<a+@@AAc!fqjQTUVQWFWY\]^Y_bcYcdghidjYjFjDkk 
%(Q,uQx
qAeAh!6
6 E%!)Lr*   c                 h   t        j                  d      }| d   |d<   | d   |d<   d|z  }t        j                  d      }||z  |d<   ||z  |d<   ||d    |z  dz   z  |d<   ||d    |z  dz   z  |d	<   |rt        j                  |      }t        j                  ||      dd
 }|j                         S )a  Generate and affine transformation matrix.

    Given a set of points, a center, a scale and a targer resolution, the
    function generates and affine transformation matrix. If invert is ``True``
    it will produce the inverse transformation.

    Arguments:
        point {torch.tensor} -- the input 2D point
        center {torch.tensor or numpy.array} -- the center around which to perform the transformations
        scale {float} -- the scale of the face/object
        resolution {float} -- the output resolution

    Keyword Arguments:
        invert {bool} -- define wherever the function should produce the direct or the
        inverse transformation matrix (default: {False})
    r,   r   r         i@r   r   r   r   r   r   r   r   r   r   )torchoneseyeinversematmulr1   	r5   centerscale
resolutioninvert_ptht	new_points	            r(   	transformrR   H   s    " **Q-C1XCF1XCFA		!A1nAdG1nAdGVAYJNS01AdGVAYJNS01AdGMM!a%q+I==?r*   c                 b   	 t        ddg|||d      }t        ||g|||d      }| j                  dkD  rmt        j                  |d   |d   z
  |d   |d   z
  | j                  d   gt        j
                        }t        j                  |t        j                        }n^t        j                  |d   |d   z
  |d   |d   z
  gt        j                        }t        j                  |t        j                        }| j                  d   }| j                  d   }	t        j                  t        d|d    dz         t        |d   |	      |d   z
  gt        j
                        }
t        j                  t        d|d    dz         t        |d   |      |d   z
  gt        j
                        }t        j                  t        d|d   dz         t        |d   |	      gt        j
                        }t        j                  t        d|d   dz         t        |d   |      gt        j
                        }| |d   dz
  |d   |d   dz
  |d   ddf   ||d   dz
  |d   |
d   dz
  |
d   f<   t        j                  |t        |      t        |      ft        j                        }|S )a  Center crops an image or set of heatmaps

    Arguments:
        image {numpy.array} -- an rgb image
        center {numpy.array} -- the center of the object, usually the same as of the bounding box
        scale {float} -- scale of the face

    Keyword Arguments:
        resolution {float} -- the size of the output cropped image (default: {256.0})

    Returns:
        [type] -- [description]
    r   Tr   r   r   N)dsizeinterpolation)rR   ndimr   arrayr/   int32zerosuint8r1   r2   r3   cv2resizeINTER_LINEAR)r4   rJ   rK   rL   r6   r7   newDimnewImghtwdnewXnewYoldXoldYs                 r(   croprf   l   sk    U	Aq665*d	;B	J
+VUJ	MBzzA~2a52a5="Q%"Q%- ;;q>+24((<&12a52a5="Q%"Q%-8G&1	QB	QB88	QA
	SA^be34BHHFD88	QA
	SA^be34BHHFD88SBqEAI&BqE27rxxHD88SBqEAI&BqE27rxxHDT!Wq[a($q'A+d1g*=q@A 47Q;tAwQ!DG 33 ZZs:J&H&)&6&68FMr*   T)nopythonc                    t        j                  d      }| d   |d<   | d   |d<   d|z  }t        j                  d      }||z  |d<   ||z  |d<   ||d    |z  dz   z  |d<   ||d    |z  dz   z  |d	<   |r2t        j                  t         j                  j                  |            }t        j                  ||      dd
 }|j                  t         j                        S )a  Generate and affine transformation matrix.

    Given a set of points, a center, a scale and a targer resolution, the
    function generates and affine transformation matrix. If invert is ``True``
    it will produce the inverse transformation.

    Arguments:
        point {numpy.array} -- the input 2D point
        center {numpy.array} -- the center around which to perform the transformations
        scale {float} -- the scale of the face/object
        resolution {float} -- the output resolution

    Keyword Arguments:
        invert {bool} -- define wherever the function should produce the direct or the
        inverse transformation matrix (default: {False})
    r,   r   r   r?   r@   rA   r   rB   rC   r   )	r   rE   rF   ascontiguousarraylinalgpinvdotastyperX   rI   s	            r(   transform_nprn      s    $ ''!*C1XCF1XCFA
q	A1nAdG1nAdGVAYJNS01AdGVAYJNS01AdG  !23q#q#IBHH%%r*   c                 "   | j                   \  }}}}| j                  ||||z        }t        j                  |d      }t        j                  |t        j
                  |d      d      j                  d      }	t        | |||      \  }
}|
||	fS )a  Obtain (x,y) coordinates given a set of N heatmaps. If the center
    and the scale is provided the function will return the points also in
    the original coordinate frame.

    Arguments:
        hm {torch.tensor} -- the predicted heatmaps, of shape [B, N, W, H]

    Keyword Arguments:
        center {torch.tensor} -- the center of the bounding box (default: {None})
        scale {float} -- face scale (default: {None})
    )axis)r/   reshaper   argmaxtake_along_axisexpand_dimssqueeze_get_preds_fromhm)hmrJ   rK   BCHW
hm_reshapeidxscorespreds
preds_origs               r(   get_preds_fromhmr      s     JAq!QAq!a%(J
))JR
(C
BNN3R,HrRZZ[]^F)"c65AE:*f$$r*   c           	         | j                   \  }}}}|dz  }|j                  d      j                  ||d      j                  t        j
                        }|dddddf   dz
  |z  dz   |dddddf<   t	        j                  |dddddf   dz
  |z        dz   |dddddf<   t        |      D ]  }	t        |      D ]  }
| |	|
ddf   }t        ||	|
df         dz
  t        ||	|
df         dz
  }}|dkD  s;|dk  sA|dkD  sG|dk  sMt	        j                  |||dz   f   |||dz
  f   z
  ||dz   |f   ||dz
  |f   z
  g      }||	|
fxx   t	        j                  |      dz  z  cc<     |dz  }t	        j                  |      }|;|9t        |      D ]+  }	t        |      D ]  }
t        ||	|
f   |||d      ||	|
f<    - ||fS )	a  Obtain (x,y) coordinates given a set of N heatmaps and the
    coresponding locations of the maximums. If the center
    and the scale is provided the function will return the points also in
    the original coordinate frame.

    Arguments:
        hm {torch.tensor} -- the predicted heatmaps, of shape [B, N, W, H]

    Keyword Arguments:
        center {torch.tensor} -- the center of the bounding box (default: {None})
        scale {float} -- face scale (default: {None})
    r   r   Nr   ?         ?r   T)r/   repeatrr   rm   r   r   r.   r   r1   rW   sign
zeros_likern   )rx   r~   rJ   rK   ry   rz   r{   r|   r   r&   r'   hm_pXpYdiffr   s                   r(   rw   rw      s    JAq!Q1HCJJqM!!!Q*11"**=EAq!Gnq(A-1E!Q'NXXuQ1W~1Q67!;E!Q'N1X 4q 	4AQ1W+Cq!Qw(1,c%1a..AA.EBAv"r'b1fbxxR!V_s2rAv:6a_s262:689 adrwwt}t33	44 
SLEu%Je/q 	9A1X 9#/!Q$K4$9
1a4 9	9
 *r*   c           	      b   t        j                  | j                  d   dddft         j                        }t	        |j                  d         D ]J  }t	        d      D ]:  }t        | ||f   dz   ||   ||   dd      }t        |||f   |dz   d      |||f<   < L t        j                  |      S )	Nr   D   @   r   r   F)rM   r   )	r   rY   r/   r   r   rR   r=   rD   tensor)target_landmarkscentersscalesheatmapsr&   plandmark_cropped_coors          r(   create_target_heatmapr      s    xx)//2BB?rzzRH8>>!$% Yr 	YA$-.>q!t.Dq.H'RS*V\]^V_aclq$r!*8AqD>;PST;TVWXHQTN	YY <<!!r*   c                    | j                  ddd      j                  d      \  }}| j                  ddd      j                  d      \  }}|dz  }|dddf   |dddf   z
  |z  }|dddf   |dddf   z
  |z  }|dddfxx   |z  cc<   |dddfxx   |z  cc<   |dddfxx   |z  cc<   |dddfxx   |z  cc<   t        j                  ||gd      S )a  
    gets a batch of landmarks and calculates a bounding box that includes all the landmarks per set of landmarks in
    the batch
    :param target_landmarks: batch of landmarks of dim (n x 68 x 2). Where n is the batch size
    :param expansion_factor: expands the bounding box by this factor. For example, a `expansion_factor` of 0.2 leads
    to 20% increase in width and height of the boxes
    :return: a batch of bounding boxes of dim (n x 4) where the second dim is (x1,y1,x2,y2)
    rp   r   r   r   )dimNr   )rr   r3   r2   rD   cat)r   expansion_factorx_y_min_x_y_maxbb_expansion_xbb_expansion_ys          r(   create_bounding_boxr     s     "))"b!488Q8?JGQ!))"b!488Q8?JGQadmgadm37GGNadmgadm37GGNAqDM^#MAqDM^#MAqDM^#MAqDM^#M99gw'Q//r*   c                 ^    |g d}| j                         dk(  r	| |df   } | S | dd|df   } | S )a&  Shuffle the points left-right according to the axis of symmetry
    of the object.

    Arguments:
        parts {torch.tensor} -- a 3D or 4D object containing the
        heatmaps.

    Keyword Arguments:
        pairs {list of integers} -- [order of the flipped points] (default: {None})
    N)D                  
   	         r-         r,   r   r   r                                             #   "   !          -   ,   +   *   /   .   '   &   %   $   )   (   6   5   4   3   2   1   0   ;   :   9   8   7   r   r   >   =   <   C   B   A   r,   .)
ndimension)partspairss     r(   
shuffle_lrr     sO     })
 QeSj! L am$Lr*   c                     t        j                  |       st        j                  |       } |r-t        |       j	                  | j                         dz
        } | S | j	                  | j                         dz
        } | S )a  Flip an image or a set of heatmaps left-right

    Arguments:
        tensor {numpy.array or torch.tensor} -- [the input image or heatmaps]

    Keyword Arguments:
        is_label {bool} -- [denote wherever the input is an image or a set of heatmaps ] (default: {False})
    r   )rD   	is_tensor
from_numpyr   flipr   )r   is_labels     r(   r   r   1  sp     ??6"!!&)F#(():):)<q)@A M V..0145Mr*   c                    t        | t              r	 t        j                  |       }nIt        | t        j                        r-| j                         j                         j                         }n| }|j                  dk(  rt        j                  |      }|S |j                  dk(  r	|dddf   }|S # t        $ r t        d|        Y yw xY w)zReads an image from file or array/tensor and converts it to RGB (H,W,3).

    Arguments:
        tensor {Sstring, numpy.array or torch.tensor} -- [the input image or path to it]
    zerror opening file :: Nr   r   .r,   )
isinstancestrr   imreadIOErrorprintrD   TensordetachcpunumpyrV   r   gray2rgb)image_or_pathr4   s     r(   	get_imager   E  s     -%	IIm,E 
M5<<	0$$&**,224zzQu% L 
qc2A2gL  	*M:	s   B1 1C	C	c                    |*t               }t        j                  j                  |d      }	 t        j                  |       t        |       }t        j                  j                  |j                        }||}t        j                  j                  ||      }	t        j                  j                  |	      slt        j                  j                  dj                  | |	             d }
|r*t        j                   |      }|r|j#                  d      nd }
t%        | |	|
|       |	S # t
        $ r*}|j                  t        j                  k(  rn Y d }~d }~ww xY w)NcheckpointszDownloading: "{}" to {}
r   )progress)r	   ospathjoinmakedirsOSErrorerrnoEEXISTr   basenameexistssysstderrwriteformatr   searchgroupr   )url	model_dirr   
check_hash	file_namehub_direr   filenamecached_filehash_prefixrs               r(   load_file_from_urlr  _  s   )GGLL-8	
I SMEww

+H'',,y(3K77>>+&

4;;CMN!!(+A()!''!*tKS+{XN+  77ell"  s   D( (	E1EE)
r,   r   r   FNNNNr   r   )F)g      p@)NN)g        )N)NTFN)#r   r  r   rD   r   r   r   r[   skimager   r   numbar   urllib.parser   	torch.hubr   r   r	   BaseExceptionr
   r0   r)   r=   rR   rf   rn   r   rw   r   r   r   r   r   r   r*   r(   <module>r     s    	 
     
    ! 65!  AEAD40!H%P d!& !&H%* d& &R"0.2(4_
  545s   B B! B!