a
    d                     @   s  d dl Zd dlmZmZ d dlmZ d dlmZ G dd deZ	dd Z
d	d
 Zd'ddZd(ddZd)ddZdd Zd*ddZedkrg dZg dZg dZg dZeeefjZeeefjZed ee ed ee eee\ZZed ee ed ee ed ed  eeeejd  d!ffZ e!e eZ"ee" ed" e
eeZ"ee" ed# ed$ eeeejd  d!ffZ#e!e#eZ$ee$ ed% e
eeZ$ee$ eeeZ$ed& ee$ dS )+    N)invlstsq)matrix_rank)normc                       s   e Zd Z fddZ  ZS )MatlabCp2tormExceptionc                    s   d tt| S )NzIn File {}:{})format__file__super__str__)self	__class__ k/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/facexlib/detection/matlab_cp2tform.pyr
   	   s    zMatlabCp2tormException.__str__)__name__
__module____qualname__r
   __classcell__r   r   r   r   r      s   r   c                 C   sB   t |t |jd dff}t || }|ddddf }|S )ap  
    Function:
    ----------
        apply affine transform 'trans' to uv

    Parameters:
    ----------
        @trans: 3x3 np.array
            transform matrix
        @uv: Kx2 np.array
            each row is a pair of coordinates (x, y)

    Returns:
    ----------
        @xy: Kx2 np.array
            each row is a pair of transformed coordinates (x, y)
    r      N)nphstackonesshapedot)transuvxyr   r   r   tformfwd   s    r   c                 C   s   t | }t||}|S )a  
    Function:
    ----------
        apply the inverse of affine transform 'trans' to uv

    Parameters:
    ----------
        @trans: 3x3 np.array
            transform matrix
        @uv: Kx2 np.array
            each row is a pair of coordinates (x, y)

    Returns:
    ----------
        @xy: Kx2 np.array
            each row is a pair of inverse-transformed coordinates (x, y)
    )r   r   )r   r   Tinvr   r   r   r   tforminv%   s    
r    c              	   C   s  ddi}|d }|j d }|d d df d}|d d df d}t||t|dft|dff}t|| t|dft|dff}t||f}	| d d df d}
| d d df d}t|
|f}t|	d| krt|	|dd\}}}}t	|}nt
d|d }|d }|d }|d	 }t|| dg||dg||dgg}t|}tg d
|d d df< ||fS )NK   r   )r   r   r   r   )Zrcondzcp2tform:twoUniquePointsReq   r   r   r   )r   Zreshaper   r   r   zerosZvstackrankr   Zsqueeze	Exceptionarrayr   )r   r   optionsr!   MxyZtmp1Ztmp2XuvUr_ZscssZtxtyr   Tr   r   r   findNonreflectiveSimilarity<   s.    
&($r6   c                 C   s   ddi}t | ||\}}|}d|d d df  |d d df< t | ||\}}tg dg dg dg}t||}	t|| }
t|
| }t|	| }t|| }||kr||fS t|	}|	|fS d S )Nr!   r"   r   r   )r   r   r   )r   r   r   r$   )r6   r   r(   r   r   r   r   )r   r   r)   Ztrans1Z
trans1_invZxyRZtrans2rZtrans2r_invZ	TreflectYZtrans2Zxy1Znorm1Zxy2Znorm2Z
trans2_invr   r   r   findSimilarity^   s     

r7   Tc                 C   s*   |rt | |\}}nt| |\}}||fS )ap  
    Function:
    ----------
        Find Similarity Transform Matrix 'trans':
            u = src_pts[:, 0]
            v = src_pts[:, 1]
            x = dst_pts[:, 0]
            y = dst_pts[:, 1]
            [x, y, 1] = [u, v, 1] * trans

    Parameters:
    ----------
        @src_pts: Kx2 np.array
            source points, each row is a pair of coordinates (x, y)
        @dst_pts: Kx2 np.array
            destination points, each row is a pair of transformed
            coordinates (x, y)
        @reflective: True or False
            if True:
                use reflective similarity transform
            else:
                use non-reflective similarity transform

    Returns:
    ----------
       @trans: 3x3 np.array
            transform matrix from uv to xy
        trans_inv: 3x3 np.array
            inverse of trans, transform matrix from xy to uv
    )r7   r6   )src_ptsdst_pts
reflectiver   	trans_invr   r   r   get_similarity_transform   s     r<   c                 C   s   | ddddf j }|S )aP  
    Function:
    ----------
        Convert Transform Matrix 'trans' into 'cv2_trans' which could be
        directly used by cv2.warpAffine():
            u = src_pts[:, 0]
            v = src_pts[:, 1]
            x = dst_pts[:, 0]
            y = dst_pts[:, 1]
            [x, y].T = cv_trans * [u, v, 1].T

    Parameters:
    ----------
        @trans: 3x3 np.array
            transform matrix from uv to xy

    Returns:
    ----------
        @cv2_trans: 2x3 np.array
            transform matrix from src_pts to dst_pts, could be directly used
            for cv2.warpAffine()
    Nr   r"   )r5   )r   	cv2_transr   r   r   cvt_tform_mat_for_cv2   s    r>   c                 C   s   t | ||\}}t|}|S )a  
    Function:
    ----------
        Find Similarity Transform Matrix 'cv2_trans' which could be
        directly used by cv2.warpAffine():
            u = src_pts[:, 0]
            v = src_pts[:, 1]
            x = dst_pts[:, 0]
            y = dst_pts[:, 1]
            [x, y].T = cv_trans * [u, v, 1].T

    Parameters:
    ----------
        @src_pts: Kx2 np.array
            source points, each row is a pair of coordinates (x, y)
        @dst_pts: Kx2 np.array
            destination points, each row is a pair of transformed
            coordinates (x, y)
        reflective: True or False
            if True:
                use reflective similarity transform
            else:
                use non-reflective similarity transform

    Returns:
    ----------
        @cv2_trans: 2x3 np.array
            transform matrix from src_pts to dst_pts, could be directly used
            for cv2.warpAffine()
    )r<   r>   )r8   r9   r:   r   r;   r=   r   r   r    get_similarity_transform_for_cv2   s    r?   __main__)r      )r   r#      )r   r      )r   irD   z
--->uv:z
--->xy:z
--->trans matrix:z
--->trans_inv matrix:z
---> apply transform to uvz
xy_m = uv_augmented * transr   z
xy_m = tformfwd(trans, uv)z#
---> apply inverse transform to xyz 
uv_m = xy_augmented * trans_invz
uv_m = tformfwd(trans_inv, xy)z
uv_m = tforminv(trans, xy))N)N)T)T)%numpyr   Znumpy.linalgr   r   r   r&   r   r'   r   r   r    r6   r7   r<   r>   r?   r   r.   r/   r+   r,   r(   r5   r   r   printr   r;   r   r   r   Zuv_augr   Zxy_mZxy_augZuv_mr   r   r   r   <module>   s\   
"
$
(
%
'


