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__ a/var/www/html/stable-diffusion-webui/repositories/CodeFormer/facelib/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   )rcondzcp2tform:twoUniquePointsReq   r   r   r   )r   reshaper   r   r   zerosvstackrankr   squeeze	Exceptionarrayr   )r   r   optionsr!   Mxytmp1tmp2XuvUr_scsstxtyr   Tr   r   r   findNonreflectiveSimilarity<   s.    
&($r>   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%   )r>   r   r,   r   r   r   r   )r   r   r-   Ztrans1Z
trans1_invZxyRZtrans2rZtrans2r_invZ	TreflectYZtrans2xy1norm1xy2norm2Z
trans2_invr   r   r   findSimilarity^   s     

rC   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
    )rC   r>   )src_ptsdst_pts
reflectiver   	trans_invr   r   r   get_similarity_transform   s     rH   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"   )r=   )r   	cv2_transr   r   r   cvt_tform_mat_for_cv2   s    rJ   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()
    )rH   rJ   )rD   rE   rF   r   rG   rI   r   r   r    get_similarity_transform_for_cv2   s    rK   __main__)r      )r   r$      )r   r      )r   irP   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   numpy.linalgr   r   r   r)   r   r+   r   r   r    r>   rC   rH   rJ   rK   r   r4   r5   r/   r0   r,   r=   r   r   printr   rG   r   r   r   Zuv_augr   Zxy_mZxy_augZuv_mr   r   r   r   <module>   s\   
"
$
(
%
'


