o
    ߥi#z                     @   s  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Zd dlZd dl	Z
d dlZd dlm  mZ d dlmZ d dlmZmZ dedefddZd[d
dZd\ddZdd Zd]ddZejddddd Zejddddd Zd^ddZd_dd Zd`d"d#Z d$d% Z!d&d' Z"d(d) Z#dad*d+Z$d,d- Z%d.d/ Z&d0d1 Z'd2d3 Z(d4d5 Z)d6d7 Z*dbd9d:Z+d;d< Z,dcd>d?Z-d@dA Z.dBdC Z/dddEdFZ0d\dGdHZ1dedJdKZ2dfdMdNZ3dOdP Z4dQdR Z5dSdT Z6dgdVdWZ7dhdYdZZ8dS )i    N)array)Image)loadmatsavemat	old_range	new_rangec                 C   sX   t |dksJ t |dksJ | |d  |d |d   |d |d   |d  } | S )N   r      )len)imgr   r    r   b/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/models/cv/face_reconstruction/utils.pyimg_value_rescale   s   r      c                 C   s   | j d }| j d }||kr'|d | }tj| t|| |ftjd}||fS |d | }tj| |t|| ftjd}||fS )Nr   r	         ?interpolation)shapecv2resizeintINTER_CUBIC)r   	long_side
src_height	src_widthscale_imgr   r   r   resize_on_long_side   s   


r   c                 C   sr   | |  | d d|  |  d|   d  }d||dk < d||dk< t ||  }d||dk < |dur7d||dk< |S )	z_
    src, gt shape: [h, w, 3] value: [0, 1]
    return: mg, shape: [h, w, 1] value: [0, 1]
    g|=r   g|=      ?r   r	   gp?N)npabs)srcgt	skin_maskmgdiff_absr   r   r   get_mg_layer,   s   (r&   c                 C   s8   t | tr| S |  dv rdS |  dv rdS td)N)yestruety1T)nofalsefn0FzBoolean value expected.)
isinstanceboollowerargparseArgumentTypeError)vr   r   r   str2bool>   s   

r7   r   c                 C   s`  t j| | dft jd}t j| | ft jd}| d }t|jd D ]h}t|jd D ]^}|| d  d || d  d  |d kr|| d   |||df< || d   |||df< t || d  d || d  d  }||d kr{d| | |||f< q)d| | d |||f< q)q t|d d	 |d
 d	 \}}	||9 }tj||	dd\}
}t 	|
|f}|S )Nr   )r   dtyper   r   r	          @g       ).r   g:0yE>.r	   F)angleInDegrees)
r   zerosfloat32ranger   sqrtr   cartToPolarpolarToCartdstack)lengthspread_ratioFlowmagradiushwdistance_angxr*   r   r   r   spread_flowI   s&   (& rN   T)nopythonparallelc                 C   s   d}| |k r||k r|S | |k r|d| kr|S | d| kr$||k r$|S | d| kr2|d| kr2|S |d|  ||  d|   |d|  ||  |   }|dk rRd}|dkrXd}|S )N皙?r	   r      r   )rM   r*   v11v12v21v22r)   resultr   r   r   bilinear_interpf   s"   rX   c                 C   s  |j d }|j d }|\}}}	}
|	d }||
 }|| }|d }| }t|D ],}t|D ]$}|}|}| ||f }|||f }t|dk rOt|dk rOq/|||  }|||  }|||
 krq||d krk|d }||k rq|}||| kr||d kr|d }||k r|}||	k r|dk rd}|d |kr|d }||k r|dk rd}|d |kr|d }tt|}tt|}tt|}tt|}|dk rd}||j d d kr|j d d }|dk rd}||j d d kr|j d d }|dk rd}||j d d kr|j d d }|dk rd}||j d d kr&|j d d }tdD ])}t|| || ||||f ||||f ||||f ||||f ||||f< q*q/q(|||||fS )Nr	   r   rQ      )	r   copyr>   r    r   mathfloorceilrX   )rDxrDyoriImg
transRatiopadssrcWsrcHpadTop	padBottompadLeftpadRight
left_boundright_boundbottom_bound	top_boundnewImgij_i_jdeltaXdeltaYnxnynxinyinxi1nyi1llr   r   r   image_warp_grid1}   s   


Kr{   bilinearr<   皙?c                 C   s   |   \}}}}tt|t|g\}	}
|
 |d  d d }
|	 |d  d d }		 tj rIt|
d|	dfdd }nt|
d|	dfdd}|d| |  }t	j
| |||d}|S )z

    Args:
        x: [n, c, h, w]
        flow: [n, h, w, 2]
        mode:
        padding_mode:
        coff:

    Returns:

    r	   r9   r   r   )modepadding_mode)sizetorchmeshgridarangefloatcudais_availablecat	unsqueezeFgrid_sample)rM   flowr   r   coffr/   crH   rI   yvxvgridgrid_xwarp_xr   r   r   warp   s   

"r   	asset/BFMc                 C   s   d}t t| dd}td}||d td}td}||d|  ||d|d  |  |  t|}t||d d	g}t|}t	t| d
}||fS )Ni  zExp_Pca.binrbrn   r	   r.   rY   r   r~   zstd_exp.txt)
openospjoinr   fromfilecloser   reshape	transposeloadtxt)
bfm_foldern_vertexExpbinexp_dimexpMUexpPCexpEVr   r   r   LoadExpBasis  s   

r   BFMc                 C   s  t d tt| d}|d }|d }|d }|d }|d }|d }t \}}	|t|d	d
g }
|
d }
|
d d d df }
|t|	d	dg }|d }|d d d df }|t|d	d
g }|d d d df }tt| d}|d tjd }tt| d}|d tjd }|| }t|
g d}
|
|d d d d f }
t|
d	dg}
t|g d}||d d d d f }t|d	dg}t|g d}||d d d d f }t|d	dg}t|d	dgd }||d d f }t|dd	g}t|d	dg}||d d f }t|dd	g}tt| d}|d }|d }|d }|d }|d }|d }t	t| d|||
||||||||d d S ) Nz'Transfer BFM09 to BFM_model_front......z01_MorphableModel.matshapePCshapeEVshapeMUtexPCtexEVtexMUr~      g     j@P   O   @   zBFM_front_idx.matidxr	   zBFM_exp_idx.mat	trimIndex)r~   rY   r   )r~   rY   r   rY   zfacemodel_info.matfrontmask2_idxskinmask	keypoints	point_buftri	tri_mask2zBFM_model_front.mat)	meanshapemeantexidBaseexBasetexBaser   r   r   r   r   r   )
printr   r   r   r   r   r   astypeint32r   )r   original_BFMr   r   r   r   r   r   r   r   r   r   r   	index_expindex_shaper   r   
other_infor   r   r   r   r   r   r   r   r   transferBFM09  s   

r   c                 C   s   t t| d}|d }tg dd }||d d d f t||ddg d d f dt||ddg d d f d||d	 d d f ||d
 d d f g}tj|dd}|g dd d f }|S )Nzsimilarity_Lm3D_all.matlm   %   (   +   .   1   7   r	   r   r   rY            axisr	   r   r   rY   r   )r   r   r   r   r   meanstack)r   Lm3Dlm_idx
value_listr   r   r   	load_lm3do  s   0r   c                    s  d}|d7 }d| v r:t | d D ](\}}|d|d |d |d | d | d | d | d | d | d 7 }qn| d D ]}|d	|d |d |d 7 }q>d
| v rg| d
 D ]}|d|d |d 7 }qXd| v r| d D ]}|d|d |d |d 7 }qod| v rt | d D ]Y\} d| v sd| v sd
| v rd| v r| d | n d| v r| d | n dd fddtt D  d }ndd fddtt D  d }||7 }q|S )N # Create by HRN
colorsvertices,v {:.6f} {:.6f} {:.6f} {:.6f} {:.6f} {:.6f}
r   r	   r   v {:.6f} {:.6f} {:.6f}
UVsvt {:.6f} {:.6f}
normalsvn {:.6f} {:.6f} {:.6f}
facesfaces_uvfaces_normalf  c                    &   g | ]}d   | | | qS z{}/{}/{}format.0rn   faceface_normalface_uvr   r   
<listcomp>      z"mesh_to_string.<locals>.<listcomp>
c                       g | ]	}d   | qS z{}r   r   r   r   r   r     s    )	enumerater   r   r>   r
   )mesh
out_stringrn   r6   uvvnindrowr   r   r   mesh_to_string  sT     

r  c                    s$  t j| }t jt j| d }d|v rstt j||d |d  tt j||d d:}|	d |	d |	d |	d	 |	d
 |	d |	d |	d |	d
|d  W d    n1 snw   Y  t| d}d|v r|	d |	d
| d|v rt|d D ])\}}|	d
|d |d |d |d | d |d | d |d | d  qn|d D ]}|	d
|d |d |d  qd|v r|d D ]}|	d
|d |d  qd|v r|d D ]}|	d
|d |d |d  qd|v rwt|d D ]h\}	 d|v s)d|v s)d|v r\d|v r5|d |	 n d|v rC|d |	 n dd fd d!tt D  d" }
ndd fd#d!tt D  d" }
|	|
 qW d    d S W d    d S 1 sw   Y  d S )$Nr   texture_mapz.jpgz.mtlrI   z# Created by HRN
znewmtl material_0
zKa 1.000000 0.000000 0.000000
zKd 1.000000 1.000000 1.000000
zKs 0.000000 0.000000 0.000000
zTr 0.000000
zillum 0
zNs 0.000000
z
map_Kd {}
r   zmtllib ./{}.mtl
r   r   r   r	   r   r   r   r   r   r   r   r   r   r   r   c                    r   r   r   r   r   r   r   r     r   zwrite_obj.<locals>.<listcomp>r   c                    r   r   r   r   r   r   r   r     s    )ospathdirnamesplitextbasenamer   imwriter   r   writer   r   r>   r
   )	save_pathr   save_dir	save_namewfrn   r6   r   r   r   r  r   r   r   	write_obj  s   








 "






$r  c                 C   s>  t | d}| }W d    n1 sw   Y  g }g }g }g }g }g }	d}
|D ]}|d d dkrHdd | ddd  D }|| |d d d	kr| ddd  }d
d |D }t|
t|}
t|dkrzt|t|d krzq)|| d|d v rt|d dd dkrdd |D }|| d|d v rt|d ddkrt|d dd dkrdd |D }|	| |d d dkr| ddd  }dd |D }|| |d d dkr| ddd  }dd |D }|| q)t|	tj
}|
dkrt|	tj}|jd dkr-||d}n|d d d df |d d dd f |d}t|dkrWt|	tj
}||d< t|dkrkt|	tj
}||d< t|dkr|
dkrt|	tj}||d< t|	dkr|
dkrt|		tj}	|	|d< |S )Nrr   r   zv c                 S       g | ]}t |d krt|qS r   r
   r   r   ar   r   r   r     s    zread_obj.<locals>.<listcomp>r   r	   r   c                 S   s*   g | ]}t |d krt|dd  qS )r   /r
   r   splitr  r   r   r   r        * r  c                 S   *   g | ]}t |d krt|dd qS )r   r  r	   r  r  r   r   r   r     r  rY   c                 S   r  )r   r  r   r  r  r   r   r   r     s    $zvt c                 S   r  r  r  r  r   r   r   r          zvn c                 S   r  r  r  r  r   r   r   r     r  )r   r   )r   r   r   uvsvnsr   r   )r   	readlinesstripr  appendmaxr
   r   r   r   r=   r   r   )obj_pathprint_shaper.   	bfm_linesr   r   r  r  r   r   max_face_lengthlinevertexitemsr   r   r   r   r   r   r   r   r   read_obj  s   

 
&
$





r)  c                 C   s  | j d }td| dg}| |dd| d dddf< d|dd| d ddf< | |dd| dddf< d|dd| ddf< t|  d| dg}tj||\}}}}|dd }|dd }|d }	|d }
tj|tj| d }tj|	|
gdd}||fS )	Nr	   r      r   rY   r      r   )	r   r   r<   r   r   linalglstsqnormr   )xprM   nptsAbkrK   R1R2sTxsTysr)   r   r   r   POSF  s   
"r9  c                 C   sv  |d }|d }|d }|d }|   }|ddg}tj|dd}|d }|d	 }	|d d df | |d d df< |d d d	f |	 |d d d	f< tt|d d }
||
 }|d	d
g}t|}t||| }dd	td|   d	 }t||| }t|}|d d df |
 | }|d d d	f |
 |	 }d|d d df  |
 }||||g}t	|dgS )NW1B1W2B2r   r   r   r   r	   
      r   )
rZ   r   r   r   r?   sumr   matmulexpr   )pointsparamsw1b1w2b2data	data_meanx_meany_meanrmsinputsrM   r*   rI   rectsr   r   r   BBRegression`  s0     

rQ  c                 C   s   d}|  }td| jd  d| jd  dg}| || jd d | jd | jd d  | jd d | jd | jd d  f< |d | jd d  |d< |d | jd d  |d< |d dk sf|d dk rhd}|||fS )NTr   r   r	   rY   F)rZ   r   r<   r   )r   boxsuccessbboxresr   r   r   img_padding}  s   $&$
rV  c                 C   s~   t | |\}}}|r;||d |d |d  |d |d |d  f }tj|tjdtjd}d|d  }||fS |dfS )Nr	   rY   r   r   )r@  r@  r   r@  )rV  r   r   r   r   uint8r   )r   rT  
padded_imgpadded_bboxflagcrop_imgr   r   r   r   crop  s   r\  c                 C   s  | j d }| j d }tjdd|d  |d  d gdd| d |d  ggtjd}t| |||f} t|| d }t|| d }t| ||f} tj|d d df |d  |d  |d d df |d  |d  gdd| d }|d d }	|d d }
|	|
d	d	g}t	| |\}}|dksJ t|d |d g}t|d d |d d g}|d }t|d |d  |d |d  g}|| || |
dg f}||fS )
Nr	   r   r   r   r8   d   r   p   r@  )r   r   r   r=   r   
warpAffiner   r   r   r\  r   )r   r   r)   r8  imgwimghM_srI   rH   leftuprT  cropped_imgscale2t1r   t2invr   r   r   scale_trans  s8   

2B&rk  c                 C   sX   t |ddg}t||}|d dksJ t |t j}t| |\}}|||fS )Nr	   r>  r   r   )r   r   r   rQ  roundr   r   r\  )r   five_pointsrE  rT  r[  r   r   r   r   align_for_lm  s   

rn        l@c              	   C   s|  | j \}}|| tj}|| tj}	|d |d  t|d |d  |  tj}
|
| }|	d |d  t|d |d  |  tj}|| }| j||	ftjd}||
|||f}|d urw|j||	ftjd}||
|||f}tj	|d d df |d  |d  |d d df |d  |d  gdd| }|t
t|d |d  |	d |d  gddg }|||fS )Nr   r   r	   )resampler   )r   r   r   r   r   r   r   BICUBICr\  r   r   r   )r   r   r)   r8  target_sizemaskw0h0rI   rH   rd  rightre  belownew_imgnew_lmr   r   r   resize_n_crop_img  s@   
B
rz  c                 C   s   t g dd }| |d d d f t | |ddg d d f dt | |ddg d d f d| |d d d f | |d d d f g}t j|dd	}|g d
d d f }|S )Nr   r	   r   r   rY   r   r   r   r   r   )r   r   r   r   )r   r   r   lm5pr   r   r   
extract_5p  s   Br|       Y@c                 C   s   | j \}}|jd dkrt|}n|}t| | \}	}
|	 }	||
 }
t| ||	|
||d\}}}t|||
|	d |	d g}||||fS )aL  
    Return:
        transparams        --numpy.array  (raw_W, raw_H, scale, tx, ty)
        img_new            --PIL.Image  (target_size, target_size, 3)
        lm_new             --numpy.array  (68, 2), y direction is opposite to v direction
        mask_new           --PIL.Image  (target_size, target_size)

    Parameters:
        img                --PIL.Image  (raw_H, raw_W, 3)
        lm                 --numpy.array  (68, 2), y direction is opposite to v direction
        lm3D               --numpy.array  (5, 3)
        mask               --PIL.Image  (raw_H, raw_W, 3)
    r   r   )rr  rs  r	   )	r   r   r|  r9  r   squeezerz  r   r   )r   r   lm3Drs  rr  rescale_factorrt  ru  r{  r)   r8  img_newlm_newmask_newtrans_paramsr   r   r   	align_img  s   

r  c                 C   sZ   t | dddf d | dddf d  | dddf d  dddf }| | } | S )z< Normalize a numpy array of 3 component vectors shape=(n,3) Nr   r   r	   )r   r?   )arrlensr   r   r   normalize_v3  s   Nr  c           	      C   s<  t j| j| jd}| | }t |d d df |d d df  |d d df |d d df  }g d||d d df dk|d d df dk |d d df dk < t|}tdD ]}t|jd D ]}||||f   || 7  < qbqY|d d df dk|d d df dk |d d df dk }g d||< t|}|S )Nr]  r	   r   r   )r   r   r   rY   )r   r<   r   r8   crossr  r>   )	r   r   r.  trisr/   rn   ro   indsrW   r   r   r   estimate_normals  s   DD<r  r  c              
   C   s$  |dkrt g d}nt g d}| j\}}}}|  | } }|d |d  |d< t |t j}t|jd D ]R}|dd|df |dd|df }	}
t| |D ]6}t| |D ]-}t |	| d|d }t |
| d|d }t|jd D ]}|| ||| || f< qq`qXq=| S )am  
    Return:
        img              -- numpy.array, (B, H, W, 3) img with landmark, RGB order, range (0, 255)


    Parameters:
        img              -- numpy.array, (B, H, W, 3), RGB order, range (0, 255)
        landmark         -- numpy.array, (B, 68, 2), y direction is opposite to v direction
        color            -- str, 'r' or 'b' (red or blue)
    r  )     o@r   r   )r   r   r  r	   r:   Nr   )	r   r   r   rZ   rl  r   r   r>   clip)r   landmarkcolorstepr   rK   HWrn   rM   r*   ro   r3  ur6   mr   r   r   draw_landmarks$  s&   &r  c           	      C   s   t | }|jd d \}}|| }|d u rtj| }tjtj| d }t|D ]&}|d d || |d | d d f }t 	tj
|d||d | q,d S )Nr   r   r	   z{}_{:0>2d}.jpg)r   imreadr   r  r  r  r  r  r>   r	  r   r   )	img_path
target_dirr   rH   rI   n_split	base_namern   img_ir   r   r   	split_visC  s   
&r        4@c                 C   sV   t jd }| d jd d \}}t |||||fd}| D ]}|| q|  d S )Nmp4vr   r   T)r   VideoWriter_fourccr   VideoWriterr
  release)
image_listr  fpsfourccrH   rI   outframer   r   r   write_videoQ  s   
r  r   c           
      C   s   g }t ||d | D ]F}t || d | D ]:}|| | || | d |d | | g}|| | d |d | | d |d | | g}	|| ||	 qqt|}|d d g df }|S )Nr	   )r   r   r	   )r>   r   r   r   )
rH   rI   margin_xmargin_yrs  	trianglesrM   r*   	triangle0	triangle1r   r   r   generate_triangles`  s   *2

r  c                 C   s   |   dksJ |  dksJ | jd |jd ksJ | jd dks%J |jd dks.J | jdd \}}|jdd \}}| j}|tj|tjd|| ddddf  }| || df} | |  S )z
    :param vertices: [batch size, number of vertices, 3]
    :param faces: [batch size, number of faces, 3]
    :return: [batch size, number of faces, 3, 3]
    rY   r   r   Nr]  )	
ndimensionr   devicer   r   r   tor   long)r   r   bsnvnfr  r   r   r   face_verticesr  s   r  c                 C   s:  |   dksJ |  dksJ | jd |jd ksJ | jd dks%J |jd dks.J | jdd \}}|jdd \}}| j}t|| d|}|tj|tjd|| ddddf  }| || df|	  }|dd}|ddd}|
d|dddf 	 t|dddf |dddf  |dddf |dddf   |
d|dddf 	 t|dddf |dddf  |dddf |dddf   |
d|dddf 	 t|dddf |dddf  |dddf |dddf   tj|ddd	}|||df}|S )
z
    :param vertices: [batch size, number of vertices, 3]
    :param faces: [batch size, number of faces, 3]
    :return: [batch size, number of vertices, 3]
    rY   r   r   Nr]  r~   r	   gư>)epsdim)r  r   r  r   r<   r  r   r   r   r  
index_add_r  r   	normalize)r   r   r  r  r  r  r   vertices_facesr   r   r   vertex_normals  sL   """r  c                 C   sD   t | ts| S G dd dt}| }| D ]}t| | |j|< q|S )Nc                   @   s   e Zd ZdS )zdict2obj.<locals>.CN)__name__
__module____qualname__r   r   r   r   C  s    r  )r1   dictobjectdict2obj__dict__)dr  or3  r   r   r   r    s   
r  rQ   c                 C   s   | d }| d }| d }| d }|| }|| }	|t ||  }
|
dk r&dn|
}
|t |	|  }|dk r6dn|}|t ||  }||krF|n|}|t |	|  }||krV|n|}|
|||g} dd | D } | S )zU
    :param bbox: [xmin,ymin,xmax,ymax]
    :return: bbox: [xmin,ymin,xmax,ymax]
    r   r	   r   rY   c                 S   s   g | ]}t |qS r   r   )r   rM   r   r   r   r     s    z!enlarged_bbox.<locals>.<listcomp>r  )rT  	img_width
img_heightenlarge_ratiord  toprv  bottom	roi_width
roi_heightnew_leftnew_top	new_right
new_bottomr   r   r   enlarged_bbox  s"   r  Fc              	   C   sv   | tj}tt|d D ]}t| t|| t||d  || q|r9t| t|d t|d || d S d S )Nr	   r   r~   )r   r   r   r>   r
   r   r&  tuple)imrD  r  stroke_sizeclosedrn   r   r   r   	draw_line  s    &r  )r   )N)r   )r|   r<   r}   )r   )r   )T)ro  N)Nro  r}  )r  r   )r  )r   r   N)rQ   )r   F)9r4   r[   r  os.pathr  r   r   r   numbanumpyr   r   torch.nn.functionalnn
functionalr   PILr   scipy.ior   r   listr   r   r&   r7   rN   jitrX   r{   r   r   r   r   r  r  r)  r9  rQ  rV  r\  rk  rn  rz  r|  r  r  r  r  r  r  r  r  r  r  r  r  r   r   r   r   <module>   s`   





]
)
V.
AU


"



*
"