o
    ॵi$m                     @   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
m  mZ d dlmZ d dlmZ d dlmZ d dlmZ e ZG dd dZdd	 ZdLddZdd Zdd Zdd Zdd Zdd Z		dMddZ dd Z!dd Z"dd Z#d d! Z$d"d# Z%d$d% Z&d&d' Z'd(d) Z(d*d+ Z)d,d- Z*d.d/ Z+	dNd0d1Z,d2d3 Z-d4d5 Z.dOd7d8Z/dPd9d:Z0d;d< Z1d=d> Z2d?g d@fdAdBZ3dCdD Z4ddg dEdfdFdGZ5	H	IdQdJdKZ6dS )R    N)Image)
OutputKeys)
load_image)loggerc                   @   s*   e Zd ZdZd
ddZdd Zdd Zd	S )InputPadderz5 Pads images such that dimensions are divisible by 8 sintelc                 C   s   |dd  \| _ | _| j d d d | j  d }| jd d d | j d }|dkr?|d ||d  |d ||d  g| _d S |d ||d  d|g| _d S )N      r      r   )htwd_pad)selfdimsmodepad_htpad_wd r   S/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/utils/cv/image_utils.py__init__   s   

zInputPadder.__init__c                    s    fdd|D S )Nc                    s   g | ]}t j| jd dqS )	replicate)r   )Fpadr   ).0xr   r   r   
<listcomp>$   s    z#InputPadder.pad.<locals>.<listcomp>r   )r   inputsr   r   r   r   #   s   zInputPadder.padc                 C   sd   |j dd  \}}| jd || jd  | jd || jd  g}|d|d |d |d |d f S )Nr   r      r   r
   .)shaper   )r   r   r   r   cr   r   r   unpad&   s   ,&zInputPadder.unpadN)r   )__name__
__module____qualname____doc__r   r   r"   r   r   r   r   r      s
    
r   c                 C   sB   | |    |  |    d  } | d tj} t| tj} | S )zto convert a np.array with shape(h, w) to cv2 img

    Args:
        img_array (np.array): input data

    Returns:
        cv2 img
    h㈵>   )minmaxastypenpuint8cv2applyColorMapCOLORMAP_JET)	img_arrayr   r   r   numpy_to_cv2img,   s   
	r2   皙?c              
   C   sr  g d}g d}g d}g d}g d}g d}	|j d dkr&|}
|}|}n|j d d	kr3|}
|}|	}tt|
D ]U}|
| }||krDq9|| |k sP|d
 |k rQq9||v r\||v r\d}n||v rg||v rgd}nd}t| t||df t||d
f ft|| d t||d
f f|d q9t|j d D ] }|| |k rqt| t||df t||d
f fddd qd S )N)r   r   r   r
   r   r   r            r	   r4   r5               )r
   r   r4   r6   	   r7   r9      )r      r5   r	   
   r8   r:      )r   r   r
   r   r   r
   r4   r5   r:   r	   r;   r:   r7   r8   r
   )r   r   r=   r	   r;   r>   )r4   r5   r6   r7   r8   r9   r      r<   r
   r   r(   r   r(   r   r   r   r(   r(   r   r4   r   r   r(   )r    rangelenr.   lineintcircle)imagenp_kpsscore	thresholdlst_parent_ids_17lst_left_ids_17lst_right_ids_17lst_parent_ids_15lst_left_ids_15lst_right_ids_15lst_parent_idslst_left_idslst_right_idsipidcolorr   r   r   draw_joints<   sF   $"&r[   c                 C   s>   t | t|d t|d ft|d t|d fdd d S )Nr   r
   r   r   rD   )r.   	rectanglerI   )rK   boxr   r   r   draw_boxh   s   r^   c                 C   s8   |D ]}t | |d |d f|d |d fdd q| S )Nr   r
   r   r   rB   )r.   r\   )rK   bboxesbboxr   r   r   "realtime_object_detection_bbox_vism   s
   "ra   c           	   
   C   s   t | t|d t|d ft|d t|d fdd g d}tjddtjddtjddf}t|d d t|d d	 f}t|D ]!\}}|| | }t | | |d |d |d	  ft jd
|d qId S )Nr   r
   r   r   rD   )zgender      : zage         : zorient      : zhat         : zglass       : zhand_bag    : zshoulder_bag: zback_pack   : zupper_wear  : zlower_wear  : zupper_color : zlower_color : r(   r4            ?)	r.   r\   rI   r,   randomrandint	enumerateputTextFONT_HERSHEY_SIMPLEX)	rK   r]   labelstitleclrpointidxlbszr   r   r   draw_attributet   s     
rp   c                 C   s   t | tj }t | tj }t | tj }t|t|kr(t|t|ks*J t|d}t	t|D ]}t
|t ||  t|t || t ||  q6|S NrE   )r,   arrayr   	KEYPOINTSSCORESBOXESrG   r.   imreadrF   r^   r[   )outputoriginal_imageposesscoresboxesrK   rX   r   r   r   draw_keypoints   s   $"r|   c                 C   sp   t | tj }t | tj }t|t|ksJ t|d}tt|D ]}t	|t || ||  q&|S rq   )
r,   rr   r   LABELSru   rG   r.   rv   rF   rp   )rw   rx   ri   r{   rK   rX   r   r   r   draw_pedestrian_attribute   s   r~         @c                    s  g d}g d}g d}g d}g d}	g d}
g d}g d}g d	}t | }tt|D ]}t|t||  q/t j|d   d
} fdd}tt|D ]}|| }|||| |||| |||| |||| ||	|| ||
|| |||| |||| |||| t|}t|D ]>}t|| d }t|| d }t 	|t
|t|  t|  ft jddd t |t|  t|  fddt j qqQ|d urt || |S )N)!r   r
   r   r   r=   r4   r5   r6   r	   r;   r>   r7   r8   r9   r:   r<   r?   r@         rb                                        )
!   "   #   $   %   &   '   (   )   r   )
*   +   ,   -   .   /   0   1   2   r   )	B   C   D   E   F   G   H   I   r   )	K   L   M   N   O   P   Q   R   r   )3   4   5   6   )7   8   9   :   ;   <   =   >   ?   @   A   )T   U   V   W   X   Y   Z   [   \   ]   ^   _   r   )	`   a   b   c   d   e   f   g   r   )dsizefxfyc                    s   t t| d D ]>}| | }| |d  }t|| d   t|| d   f}t|| d   t|| d   f}tj|||ddd qd S )Nr
   r   rD   r   )	thickness)rF   rG   rI   r.   rH   )point_indexrK   rl   rX   	cur_index
next_indexcur_ptnext_ptscaler   r   	draw_line   s   z)draw_106face_keypoints.<locals>.draw_liner   r
   rc   rA   r   )r.   rv   rF   rG   r^   r,   rr   resizerI   rg   strrh   rJ   FILLEDimwrite)in_path	keypointsr{   r   	save_pathface_contour_point_indexleft_eye_brow_point_indexright_eye_brow_point_indexleft_eye_point_indexright_eye_point_indexnose_bridge_point_indexnose_contour_point_indexmouth_outer_point_indexmouth_inter_point_indeximgrX   rK   r   pointssizer   yr   r   r   draw_106face_keypoints   sN   

"
 r   c                 C   s   t |tj }t |tj }t| }|d us J d|  tt|D ]2}|| 	t j
}|\}}}	}
|| }t|||f|	|
fdd tj||d||
fdddddd	 q&td
t| d |S )NCan't read img: rB   r   .2fr
         ?rA   r	   r   lineTypeFound  faces)r,   rr   r   ru   rt   r.   rv   rF   rG   r+   int32r\   rg   print)img_pathdetection_resultr_   rz   r   rX   r`   x1y1x2y2rM   r   r   r    draw_face_detection_no_lm_result   s&   
r  c              
   C   st   |t j }|t j }|t| }t| }|d us!J d|  tj|d|ddddddd t	d| |S )	Nr   zfacial expression: {}r>   r>   r
   r   rA   r	   r   )
r   rt   r}   r,   argmaxr.   rv   rg   formatr   )r   facial_expression_resultrz   ri   labelr   r   r   r   draw_facial_expression_result   s   



r	  c              
   C   s   |t j }|t j }|d t|d  }|d t|d  }t| }|d us0J d|  tj|d|ddddddd	 tj|d
|ddddddd	 t	
d| t	
d
| |S )Nr   r
   r   zface gender: {}r  r   rA   r	   r   zface age interval: {})r>   r   rB   )r   rt   r}   r,   r  r.   rv   rg   r  r   info)r   face_attribute_resultrz   ri   label_gender	label_ager   r   r   r   draw_face_attribute_result  s2   




r  c                 C   s  t |tj }t |tj }t |tj }t| }|d us(J d|  tt	|D ]N}|| 
t j}|| dd
t j}|| }	|\}
}}}t||
|f||fdd |D ]}t|t|ddd q]tj||	d|
|fddd	dd
d q.tdt	| d |S )Nr   rE   r   rB   r
   rD   r   r   rA   r	   r   r   r   )r,   rr   r   ru   rs   rt   r.   rv   rF   rG   r+   r   reshaper\   rJ   tuplerg   r   )r   r   r_   kpssrz   r   rX   r`   kpsrM   r   r   r  r  kpr   r   r   draw_face_detection_result  s.   
r  c                 C   s  dd }t |tj }t |tj }t |tj }g }g d}t| }||g7 }|d us7J d|  tt	|D ]}	||	 
t j}
||	 dd
t j}|d d |d d  d |d d	 |d d	  d  }|d d |d	 d  d |d d	 |d	 d	  d  }||krd
nd}||||}||g7 }||	 }|
\}}}}t|||f||fdd t|D ]\}}tj|t|d	|| dd qtj||d||fd	ddd	dd q=|S )Nc           
      S   s   d}|dkr|}t || }n|}t || }t|d |d |d |d g}td|d gddg|d dg|d |d gg}t||}t| |||f}	|	S )Ni  r
   r   r   r   )rI   r,   float32r.   getPerspectiveTransformwarpPerspective)
src_imgr  ratio
short_sizeobj_hobj_w	input_pts
output_ptsMobj_imgr   r   r   warp_img:  s   "z,draw_card_detection_result.<locals>.warp_img)rB   rA   rD   rC   r   rE   r   r   r   r
   gq=
ףp?gɝ3 ?rB   r=   r>   rZ   r   r   r   rA   r	   r   )r,   rr   r   ru   rs   rt   r.   rv   rF   rG   r+   r   r  r\   rf   rJ   r  rg   )r   r   r!  r_   r  rz   img_listver_colr   rX   r`   r  _w_hr  card_imgrM   r   r   r  r  kr  r   r   r   draw_card_detection_result8  s>   

88
r)  c                 C   sZ   t | }tt|tj}t|t|d t|d ft|d t|d fdd |S )Nr   r
   r   r   rA   )r   r.   cvtColorr,   asarrayCOLOR_RGB2BGRr\   rI   )image_inr]   rK   r   r   r   r   created_boxed_imageh  s   2r.  c                 C   s   t | }tt|D ]R}|| }| \}}|du r t| d|dkrC|jd |jd f}t dddd}	t ||	|	t j
|d	}
t ||d |d f|d
 |d fdd |
| q|
j |  d S )NF( can not be correctly decoded by OpenCV.r   r
   r  JPGTr   r   rA   r4   )r.   VideoCapturerF   rG   read	Exceptionr    VideoWriter_fourccVideoWritergetCAP_PROP_FPSr\   writerelease)video_in_pathr_   video_save_pathcaprX   r]   successframer   fourccvideo_writerr   r   r   show_video_tracking_resultp  s*   
$rC  c                 C   sF  g dg dg dg dg dg dg dg dd	}d
dl m } d
d l}t| }|t|d}|d| tt|D ]}	||	 t	}
||	 }|
 \}}|du r\t| d|	d
kr|jd |jd
 f}tdddd}t|||tj|d}d}d}d}|j\}}}t|jtj}t|
|D ][\}}t||d
 |d f|d |d f|| d tj|||d
 |d t	||  ftjt||| |t||| || d tj||d
 |d f|d |d f|| dd}qt|d|dd
}|| |d q@W d    n	1 sw   Y  |j |  d S )N)   r   r   )rD  rD  r   )r   r   r   )r   rD  rD  )r   rD  r   )   rD  r   )r   r   rD  )rE  r   rD  )personbicyclecar
motorcyclebustruckztraffic lightz	stop signr   )tqdm)totalzWriting results to video: {}Fr/  r
   r  r0  r1  r2  TgMbP?{Gz?r   r   )fontFace	fontScaler   rZ   rE   r"  r   g?)rL  mathr.   r3  rG   set_descriptionr  rF   r+   rI   r4  r5  r    r6  r7  r8  r9  r,   zerosr-   zipr\   rg   FONT_HERSHEY_TRIPLEXr)   ceiladdWeightedr:  updater;  )r<  bboxes_listlabels_listr=  PALETTErL  rQ  r>  pbarrX   r_   ri   r?  r@  r   rA  rB  
FONT_SCALETHICKNESS_SCALETEXT_Y_OFFSET_SCALEHW_
zeros_maskr`   lr   r   r   "show_video_object_detection_result  sx   

"
(re  c           	      C   s   t | d jd | d jd dg}ddlm} |dd}ddlm} tg d}t| D ](\}}|| }t	||v rE||}t	||v s;|
t	| |t}|||< q-|S )	Nr   r
   r   get_palettecoco   )_get_bias_color)r   r   r   )r,   rS  r     mmdet.core.visualization.paletterg  mmdet.core.visualization.imagerj  setrf   r  addr+   bool)	masksdraw_imgrg  mask_paletterj  taken_colorsrX   mask
color_maskr   r   r   panoptic_seg_masks_to_image  s   $


rv  c                 C   sj   ddl m} |dd}t| d jd | d jd dg}t| D ]\}}|| }|t}|||< q!|S )Nr   rf  rh  ri  r
   r   )rk  rg  r,   rS  r    rf   r+   ro  )rp  rg  rr  rq  rX   rt  ru  r   r   r   semantic_seg_masks_to_image  s   
$

rw  c                 C   s   |t j }t| }tt|D ]A}|| }| \}}|du r%t| d|dkrH|jd |jd f}	t	dddd}
t
||
|tj|	d	}|dkrQ|| q|  |  d S )
NFr/  r   r
   r  r0  r1  r2  T)r   OUTPUTr.   r3  rF   rG   r4  r5  r    r6  r7  r8  r9  r:  r;  )r<  resultr=  frame_indexesr>  rX   rm   r?  r@  r   rA  rB  r   r   r   show_video_summarization_result  s*   


r{  c           
      C   s  |t j }|t j }|t j }t| }|d usJ d|  t|||D ]R\}}}	t|t|	d t|	d ft|	d t|	d fdd tj	||dt|	d t|	d fddd	dd
d tj	||t|	d t|	d fddd	dd
d q%|d urt
|| |S )Nr   r   r
   r   r   rD   r   r   rA   r	   r   )r   rt   r}   ru   r.   rv   rT  r\   rI   rg   r   )
r   r   r   rz   ri   r_   r   rM   r  r]   r   r   r   'show_image_object_detection_auto_result  s8   



r|  c                 C   sV   t d}||  |  |   d tjd d d d d df }t|tj}|S )Nplasma   r   )	pltget_cmapr*   r+   r,   r-   r.   r*  r,  )depthcolormapdepth_colorr   r   r   depth_to_color  s   
r  c            	      C   s  d} d}d}d}d}d}| | | | | | }t |df}d}d|d| df< t dt d|  |  |d| d	f< ||  }dt dt d| |  |||| df< d|||| d	f< || }d|||| d	f< t dt d| | |||| d
f< || }dt dt | |  |||| d	f< d|||| d
f< || }d|||| d
f< t dt d| | |||| df< || }dt dt | |  |||| d
f< d|||| df< |S )a  
    Generates a color wheel for optical flow visualization as presented in:
        Baker et al. "A Database and Evaluation Methodology for Optical Flow" (ICCV, 2007)
        URL: http://vision.middlebury.edu/flow/flowEval-iccv07.pdf

    Code follows the original C++ source code of Daniel Scharstein.
    Code follows the the Matlab source code of Deqing Sun.

    Returns:
        np.ndarray: Color wheel
    r<   r5   r=   r7   r9   r   r   r(   r
   r   )r,   rS  floorarange)	RYYGGCCBBMMRncols
colorwheelcolr   r   r   make_colorwheel  s6   &.*,*,r  Fc                 C   s^  t | jd | jd dft j}t }|jd }t t | t | }t | |  t j }|d d |d  }t 	|
t j}	|	d }
d|
|
|k< ||	 }t|jd D ]T}|dd|f }||	 d }||
 d }d| | ||  }|dk}d|| d||    ||< ||  d || < |rd| n|}t 	d| |dddd|f< qX|S )	a  
    Applies the flow color wheel to (possibly clipped) flow components u and v.

    According to the C++ source code of Daniel Scharstein
    According to the Matlab source code of Deqing Sun

    Args:
        u (np.ndarray): Input horizontal flow of shape [H,W]
        v (np.ndarray): Input vertical flow of shape [H,W]
        convert_to_bgr (bool, optional): Convert output image to BGR. Defaults to False.

    Returns:
        np.ndarray: Flow visualization image of shape [H,W,3]
    r   r
   r   r   Ng     o@g      ?r(   )r,   rS  r    r-   r  sqrtsquarearctan2pir  r+   r   rF   )uvconvert_to_bgr
flow_imager  r  radafkk0k1frX   tmpcol0col1r  rm   ch_idxr   r   r   flow_uv_to_colorsP  s*    
"r  c                 C   s   | j dks	J d| jd dksJ d|durt| d|} | dddddf }| dddddf }tt|t| }t|}d}|||  }|||  }t|||S )	ay  
    Expects a two dimensional flow image of shape.

    Args:
        flow_uv (np.ndarray): Flow UV image of shape [H,W,2]
        clip_flow (float, optional): Clip maximum of flow values. Defaults to None.
        convert_to_bgr (bool, optional): Convert output image to BGR. Defaults to False.

    Returns:
        np.ndarray: Flow visualization image of shape [H,W,3]
    r   z%input flow must have three dimensionsr   z"input flow must have shape [H,W,2]Nr   r
   r'   )ndimr    r,   clipr  r  r*   r  )flow_uv	clip_flowr  r  r  r  rad_maxepsilonr   r   r   flow_to_imagew  s   
r  c                 C   s&   | d  ddd  } t| }|S )Nr   r
   r   )permutecpunumpyr  )flow
flow_colorr   r   r   flow_to_color  s   r  c                 C   sd   | d j \}}}t|tjd d||f}t| D ]\}}|t|tj	tj
 q|  d S )Nr   MP4Vr   )r    r.   r7  r6  rf   r:  r*  r+   r,   r-   r,  r;  )depthsr=  heightwidthlayersoutrX   r   r   r   r   "show_video_depth_estimation_result  s   r  z
result.jpg)r
   r
   r
   c              	   C   s>  | tj}|d r6|D ])}t|d t|d ft|d t|d f}}tj| ||g ddtjd q| tj}tj	|d j
d |d j
d dftjd}	|d r_g d|	|d dk< |d rmg d	|	|d dk< |	}
t|
d}|dk}| | d
 |
| d
  | |< |d urt|| d d d d d d df  | S )Nr   r
   r   r   )r(   r(   r   r   )dtyperA   rB   rc   rE   )r8  r   ru   rI   r.   r\   LINE_AAMASKSr,   rS  r    r-   meanr   )r   resultsout_fileif_drawr_   r   c1c2ry  
color_area	color_segru  msk_idxr   r   r   $show_image_driving_perception_result  s,   2 $r  c                 C   s>   g }t | jd D ]}t| | }|| || q	|S )Nr   )rF   r    r   	fromarray
putpaletteappend)rp  palette	vis_masksr  img_Er   r   r   masks_visualization  s   
r  r   c
              
      s  |j d |j d ksJ d|j d  d|j d  tjddd|d\}
|
d j| dd	 |
d j|dd	 tdD ]#}|
|  g  |
|  g  |
| j	 D ]}|
d
 qVq;tjdd |d ur|d usoJ |
d j|d d df |d d df ddd |
d j|d d df |d d df ddd |j d dkr|j d dkrj  j }||
d j|||
d j| fddtt|D _|
d j|d d df |d d df  dd |
d j|d d df |d d df  dd | d dd df  dkrdnd}jddd|jd jddd|d |	rFtjt|	ddd t  d S S )Nr   zmkpts0: z v.s. mkpts1: r
   r   )r>   r5   )figsizedpigray)cmapF)r   w)r!   sc              	      sP   g | ]$}t jj|d f |d f f|df |df fj | ddqS )r   r
   )	transformr!   	linewidth)
matplotliblinesLine2DtransFigure)r   rX   rZ   figfkpts0fkpts1r   r   r     s    z(make_matching_figure.<locals>.<listcomp>r=   r      r(  rN  gGz?
r<   topleft)r  fontsizevaharZ   tight)bbox_inches
pad_inches)r    r  subplotsimshowrF   	get_yaxis	set_ticks	get_xaxisspinesvaluesset_visibletight_layoutscattercanvasdrawr  invertedr  	transDatarG   r  r  textjoinaxes	transAxessavefigr   close)img0img1mkpts0mkpts1rZ   kpts0kpts1r  r  pathr  rX   spiner  	txt_colorr   r  r   make_matching_figure  sX   .. 


..&
r  quadtree_match.pngQuadTreeAttentionc                 C   sx   t dt| d tt| }tt|}t|}	|dt|g}
t|||||	|
d}|j	t|ddd d S )Nr   z matcheszMatches: {})r  i,  r  )r  r  )
r   rG   r.   rv   r   cmjetr  r  r  )	img_name0	img_name1r  r  confoutput_filenamemethodr  r  rZ   r  r  r   r   r   match_pair_visualization  s   
r  )r3   )r   N)N)F)NF)r  r  )7osr.   r  matplotlib.cmr  matplotlib.pyplotpyplotr  r  r,   torch.nn.functionalnn
functionalr   PILr   modelscope.outputsr   modelscope.preprocessors.imager   modelscope.utilsr   logging
get_loggerr   r2   r[   r^   ra   rp   r|   r~   r   r  r	  r  r  r)  r.  rC  re  rv  rw  r{  r|  r  r  r  r  r  r  r  r  r  r  r   r   r   r   <module>   sn   
,
A0<
 
2
'

F