o
    ߥi                     @   s   d Z ddlm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 ddlmZ ddlmZ ddlmZmZ d	d
lmZ d	dlmZmZ dd ZdddZG dd dejjZG dd dejjZejeej dG dd deZ!dS )zx
Part of the implementation is borrowed and modified from LaMa, publicly available at
https://github.com/saic-mdal/lama
    )DictN)linalg)Metrics)InceptionV3)default_group)torch_nested_detachtorch_nested_numpify   )Metric)METRICS
MetricKeysc                 C   s$   t j| dd}t j| dd}||fS )Nr   )axisF)rowvar)npmeancov)actmusigma r   ^/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/metrics/image_inpainting_metric.py#fid_calculate_activation_statistics   s   r   ư>c                 C   s   t | \}}t |\}}|| }tj||dd\}}	t| s9t|jd | }
t||
 ||
 }t	|r]tj
t|jdddsZtt|j}td||j}t|}||t| t| d|  S )NF)dispr   g{Gz?)atolzImaginary component {}   )r   r   sqrtmdotr   isfinitealleyeshapeiscomplexobjallclosediagonalimagmaxabs
ValueErrorformatrealtrace)activations_predactivations_targetepsmu1sigma1mu2sigma2diffcovmean_offsetm
tr_covmeanr   r   r   calculate_frechet_distance   s    

r9   c                       s@   e Zd Zd fdd	ZdddZdd	 Zd
d Zdd Z  ZS )FIDScore   r   c                    sN   t    ttdd d u rtj| }t|g t_tj| _|| _	| 
  d S )N_MODEL)super__init__getattrr:   r   BLOCK_INDEX_BY_DIMevalr<   modelr.   reset)selfdimsr.   	block_idx	__class__r   r   r>   7   s   

zFIDScore.__init__Nc                 C   s@   |  |}|  |}| j|   | j|   d S N)_get_activationsr,   appenddetachcpur-   )rD   
pred_batchtarget_batchmaskr,   r-   r   r   r   forward@   s   

zFIDScore.forwardc                 C   sN   | j | j}}t|  }t|  }t||| jd}|   |S )N)r.   )	r,   r-   torchcatrM   numpyr9   r.   rC   )rD   r,   r-   total_distancer   r   r   	get_valueG   s   zFIDScore.get_valuec                 C   s   g | _ g | _d S rI   )r,   r-   rD   r   r   r   rC   S   s   
zFIDScore.resetc                 C   sF   |  |d }|jd dks|jd dkrJ d|dd}|S )Nr   r   r	      FzNWe should not have got here, because Inception always scales inputs to 299x299)rB   r!   squeeze)rD   batchactivationsr   r   r   rJ   W   s   zFIDScore._get_activations)r;   r   rI   )	__name__
__module____qualname__r>   rQ   rV   rC   rJ   __classcell__r   r   rG   r   r:   5   s    
	r:   c                       sN   e Zd ZdZd fdd	Zdd Zdd	 Zd
d Z	dddZdd Z	  Z
S )SSIMzmSSIM. Modified from:
    https://github.com/Po-Hsun-Su/pytorch-ssim/blob/master/pytorch_ssim/__init__.py
       Tc                    s6   t    || _|| _d| _| d| || j d S )Nr	   window)r=   r>   window_sizesize_averagechannelregister_buffer_create_window)rD   rd   re   rG   r   r   r>   e   s   
zSSIM.__init__c                 C   s   t |jdks	J | d }|| jkr#| jj |j kr#| j}n| | j|}|	|}|| _|| _| 
|||| j|| jS )N   r	   )lenr!   sizerf   rc   datatyperh   rd   type_as_ssimre   )rD   img1img2rf   rc   r   r   r   rQ   m   s   
zSSIM.forwardc                    s*   t  fddtD }||  S )Nc              	      s4   g | ]}t |d   d   td  d    qS )r   )r   expfloat).0xr   rd   r   r   
<listcomp>   s    &z"SSIM._gaussian.<locals>.<listcomp>)rR   Tensorrangesum)rD   rd   r   gaussr   rv   r   	_gaussian   s   zSSIM._gaussianc                 C   sD   |  |dd}||  dd}||d|| S )Ng      ?r	   r   )r|   	unsqueezemmtrs   expand
contiguous)rD   rd   rf   
_1D_window
_2D_windowr   r   r   rh      s   
zSSIM._create_windowc                 C   s   t j|||d |d}t j|||d |d}|d}	|d}
|| }t j|| ||d |d|	 }t j|| ||d |d|
 }t j|| ||d |d| }d}d}d| | d| |  |	|
 | || |   }|rs| S |dddS )Nr   )paddinggroupsg-C6?gH}M?r	   )Fconv2dpowr   )rD   rp   rq   rc   rd   rf   re   r/   r1   mu1_sqmu2_sqmu1_mu2	sigma1_sq	sigma2_sqsigma12C1C2ssim_mapr   r   r   ro      sF   

z
SSIM._ssimc                 C   s   d S rI   r   )rD   
state_dictprefixlocal_metadatastrictmissing_keysunexpected_keys
error_msgsr   r   r   _load_from_state_dict   s   zSSIM._load_from_state_dict)rb   T)T)r]   r^   r_   __doc__r>   rQ   r|   rh   ro   r   r`   r   r   rG   r   ra   `   s    
%ra   )	group_keymodule_namec                   @   sL   e Zd ZdZdd ZdedefddZdd	 ZdddZdd Z	dd Z
dS )ImageInpaintingMetricz?The metric computation class for image inpainting classes.
    c                 C   sB   g | _ g | _tddd | _tj rdnd}t || _	d S )Nrb   F)rd   re   cudarM   )
predstargetsra   rA   rR   r   is_availabler:   toFID)rD   devicer   r   r   r>      s
   zImageInpaintingMetric.__init__outputsinputsc                 C   s4   |d }|d }| j t| | jt| d S )N	inpaintedimage)r   rK   r   r   )rD   r   r   predtargetr   r   r   add   s   zImageInpaintingMetric.addc                 C   sb   g }t | j| jD ]\}}|| || | || q	t|}| j }tjt	
|tj|iS rI   )zipr   r   rK   ra   r   r   rV   r   r   r   )rD   	ssim_listr   r   fidr   r   r   evaluate   s   
zImageInpaintingMetric.evaluateotherc                 C   s    | j |j  | j|j d S rI   )r   extendr   )rD   r   r   r   r   merge   s   zImageInpaintingMetric.mergec                 C   s   | j | jfS rI   )r   r   rW   r   r   r   __getstate__   s   z"ImageInpaintingMetric.__getstate__c                 C   s   |    |\| _| _d S rI   )r>   r   r   )rD   stater   r   r   __setstate__   s   z"ImageInpaintingMetric.__setstate__N)r   r   )r]   r^   r_   r   r>   r   r   r   r   r   r   r   r   r   r   r      s    
	r   )r   )"r   typingr   rT   r   rR   torch.nn.functionalnn
functionalr   scipyr   modelscope.metainfor   7modelscope.models.cv.image_inpainting.modules.inceptionr   modelscope.utils.registryr   modelscope.utils.tensor_utilsr   r   baser
   builderr   r   r   r9   Moduler:   ra   register_moduleimage_inpainting_metricr   r   r   r   r   <module>   s(    
+X