o
    W+ i'                     @   s   d dl mZ 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
mZ ddlmZmZ eje	ejdG d	d
 d
eZdddZdddZdddZdd Zdd Zdd Zdd ZdS )    )DictN)Metrics)default_group   )Metric)METRICS
MetricKeys)Z	group_keymodule_namec                       s\   e Zd ZdZdZdZ fddZdedefdd	Zd
d Z	dddZ
dd Zdd Z  ZS )ImageDenoiseMetricz<The metric computation class for image denoise classes.
    predtargetc                    s   t t|   g | _g | _d S N)superr
   __init__predslabelsself	__class__ s/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/modelscope/metrics/image_denoise_metric.pyr      s   
zImageDenoiseMetric.__init__outputsinputsc                 C   s0   |t j }|t j }| j| | j| d S r   )r
   
label_name	pred_namer   appendr   )r   r   r   Zground_truthsZeval_resultsr   r   r   add   s   

zImageDenoiseMetric.addc                 C   sv   g g }}t | j| jD ] \}}|t|d |d dd |t|d |d dd qtjt	|tj
t	|iS )Nr   )crop_border)zipr   r   r   calculate_psnrcalculate_ssimr   ZPSNRnpmeanZSSIM)r   Z	psnr_listZ	ssim_listr   labelr   r   r   evaluate%   s   
zImageDenoiseMetric.evaluateotherc                 C   s    | j |j  | j|j d S r   )r   extendr   )r   r&   r   r   r   merge/   s   zImageDenoiseMetric.mergec                 C   s   | j | jfS r   )r   r   r   r   r   r   __getstate__3   s   zImageDenoiseMetric.__getstate__c                 C   s   |    |\| _| _d S r   )r   r   r   )r   stater   r   r   __setstate__6   s   zImageDenoiseMetric.__setstate__)r&   r
   )__name__
__module____qualname____doc__r   r   r   r   r   r%   r(   r)   r+   __classcell__r   r   r   r   r
      s    

r
   HWCc                 C   sH   |dvrt d| dt| jdkr| d } |dkr"| ddd} | S )	a  Reorder images to 'HWC' order.
    If the input_order is (h, w), return (h, w, 1);
    If the input_order is (c, h, w), return (h, w, c);
    If the input_order is (h, w, c), return as it is.
    Args:
        img (ndarray): Input image.
        input_order (str): Whether the input order is 'HWC' or 'CHW'.
            If the input image shape is (h, w), input_order will not have
            effects. Default: 'HWC'.
    Returns:
        ndarray: reordered image.
    r1   CHWWrong input_order z,. Supported input_orders are 'HWC' and 'CHW'   ).Nr3   r   r   )
ValueErrorlenshape	transpose)imginput_orderr   r   r   reorder_image;   s   
r<   c                 C   s<  | j |j ksJ d| j  d|j  d|dvrtd| dt| tjkr?t| j dkr2| d} |   	 
d	d
d} t|tjkr_t|j dkrR|d}|  	 
d	d
d}t| |d} t||d}| tj} |tj}|dkr| || || df } ||| || df }dd }|| |S )a^  Calculate PSNR (Peak Signal-to-Noise Ratio).
    Ref: https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio
    Args:
        img1 (ndarray/tensor): Images with range [0, 255]/[0, 1].
        img2 (ndarray/tensor): Images with range [0, 255]/[0, 1].
        crop_border (int): Cropped pixels in each edge of an image. These
            pixels are not involved in the PSNR calculation.
        input_order (str): Whether the input order is 'HWC' or 'CHW'.
            Default: 'HWC'.
        test_y_channel (bool): Test on Y channel of YCbCr. Default: False.
    Returns:
        float: psnr result.
    Image shapes are different: , .r2   r4   ,. Supported input_orders are "HWC" and "CHW"   r   r   r5   r;   .c                 S   sN   t | | d }|dkrtdS |  dkrdnd}dt |t |  S )Nr5   r   infr   g      ?g     o@g      4@)r"   r#   floatmaxlog10sqrt)img1img2Zmse	max_valuer   r   r   _psnr{   s
   zcalculate_psnr.<locals>._psnrr8   r6   typetorchZTensorr7   squeezedetachcpunumpyr9   r<   astyper"   float64)rH   rI   r   r;   rK   r   r   r   r    T   s0   



r    Tc                    s@  | j |j ksJ d| j  d|j  d|dvrtd| dt| tjkr?t| j dkr2| d} |   	 
d	d
d} t|tjkr_t|j dkrR|d}|  	 
d	d
d}t| |d} t||d}| tj} |tj}|dkr| || || df } ||| || df } fdd}|| |S )a-  Calculate SSIM (structural similarity).
    Ref:
    Image quality assessment: From error visibility to structural similarity
    The results are the same as that of the official released MATLAB code in
    https://ece.uwaterloo.ca/~z70wang/research/ssim/.
    For three-channel images, SSIM is calculated for each channel and then
    averaged.
    Args:
        img1 (ndarray): Images with range [0, 255].
        img2 (ndarray): Images with range [0, 255].
        crop_border (int): Cropped pixels in each edge of an image. These
            pixels are not involved in the SSIM calculation.
        input_order (str): Whether the input order is 'HWC' or 'CHW'.
            Default: 'HWC'.
        test_y_channel (bool): Test on Y channel of YCbCr. Default: False.
    Returns:
        float: ssim result.
    r=   r>   r?   r2   r4   r@   rA   r   r   r5   rB   .c                    st   g }|   dkr
dnd}t   rt| ||nt| ||}|| W d    n1 s.w   Y  t| S )Nr      )	rE   rN   Zno_grad_ssim_3d_ssimr   r"   arrayr#   )rH   rI   ZssimsrJ   Z
final_ssimssim3dr   r   	_cal_ssim   s   
z!calculate_ssim.<locals>._cal_ssimrL   )rH   rI   r   r;   rZ   r[   r   rY   r   r!      s0   



r!   c                 C   sR  d| d }d| d }|  tj} | tj}tdd}t|| }t| d|ddddf }t|d|ddddf }|d }	|d }
|| }t| d d|ddddf |	 }t|d d|ddddf |
 }t| | d|ddddf | }d| | d| |  }|	|
 | || |  }|| }| S )	a*  Calculate SSIM (structural similarity) for one channel images.
    It is called by func:`calculate_ssim`.
    Args:
        img (ndarray): Images with range [0, 255] with order 'HWC'.
        img2 (ndarray): Images with range [0, 255] with order 'HWC'.
    Returns:
        float: SSIM result.
    {Gz?r5   Q?         ?   )	rS   r"   rT   cv2getGaussianKernelouterr9   Zfilter2Dr#   )r:   rI   rJ   c1c2kernelwindowmu1mu2mu1_sqmu2_sqmu1_mu2	sigma1_sq	sigma2_sqsigma12tmp1tmp2ssim_mapr   r   r   rW      s(   
&&&rW   c                 C   s$   ||  d ddd}|S )Nr   )Z	unsqueezerO   )r:   conv3doutr   r   r   _3d_gaussian_calculator   s    rw   c               	      s   t dd} t| |   t dd}ttj fdd|D dd} tjj	ddddd	d
dd}d
|j
_| |j
ddd d d d d d f< |S )Nr^   r_   c                    s   g | ]} | qS r   r   ).0kri   r   r   
<listcomp>   s    z0_generate_3d_gaussian_kernel.<locals>.<listcomp>r   )Zaxisr   )r^   r^   r^   )ra   ra   ra   FZ	replicate)ZstridepaddingZbiasZpadding_mode)rc   rd   r"   re   r9   rN   tensorstacknnZConv3dweightZrequires_grad)rh   Zkernel_3ru   r   rz   r   _generate_3d_gaussian_kernel   s   " r   c                 C   s&  t | jdkrt |jdksJ 	 d| d }d| d }| tj} |tj}t  }t| 	  } t|	  }t
| |}t
||}|d }|d }	|| }
t
| d || }t
|d ||	 }t
| | ||
 }d|
 | d| |  }||	 | || |  }|| }t	| S )N   r\   r5   r]   )r7   r8   rS   r"   rT   r   cudarN   r}   rD   rw   r#   )rH   rI   rJ   ZC1ZC2rh   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   r   r   r   rV      s*    


rV   )r1   )r1   T)typingr   rc   rR   r"   rN   Zmodelscope.metainfor   Zmodelscope.utils.registryr   baser   Zbuilderr   r   Zregister_moduleZimage_denoise_metricr
   r<   r    r!   rW   rw   r   rV   r   r   r   r   <module>   s&   
'

2<"