o
    ߥi                     @   s.  d dl Z d dlZd dlZd dlmZ d dlZd dlZd dlm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 dejd< d	d
gZdhddZdd Zdd Zdd Zdd ZdiddZdd ZdiddZdd Zdjdd Zdjd!d"Zd#d$ Zd%d& Zd'd( Z did)d*Z!did+d,Z"d-d. Z#d/d0 Z$d1ej%d2d2fd3d4Z&dkd5d6Z'did7d8Z(d9d: Z)e*d1d1ge*d;d;gd<d=d fd>d?Z+d@dA Z,dBdC Z-dDdE Z.dhdFdGZ/dhdHdIZ0dhdJdKZ1dhdLdMZ2dldQdRZ3dmdSdTZ4dmdUdVZ5dndYdZZ6dnd[d\Z7d]d^ Z8d_d` Z9dodbdcZ:dpddd	Z;dmdedfZ<dpdgd
Z=dS )q    N)datetime)ndimage)interp2d)orth)	make_gridTRUEKMP_DUPLICATE_LIB_OKdegradation_bsrgan_lightdegradation_bsrgan   c                 C   sj   |dkrt | d}tj|dd}|S |dkr3t | t j}|jdkr,t |t j}|S t |t j}|S )N   r      axisr   )	cv2imreadnpexpand_dimsIMREAD_UNCHANGEDndimcvtColorCOLOR_GRAY2RGBCOLOR_BGR2RGB)path
n_channelsimg r   m/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/models/multi_modal/videocomposer/ops/degration.pyimread_uint   s   
r   c                 C      t | d S )N     o@r   float32r   r   r   r   uint2single&      r$   c                 C      t | ddd  S )Nr   r   r    )r   uint8cliproundr#   r   r   r   single2uint*      r*   c                 C   r   )N    @r!   r#   r   r   r   uint162single.   r%   r-   c                 C   r&   )Nr   r   r,   )r   uint16r(   r)   r#   r   r   r   single2uint162   r+   r/   Tc                 C      | j }| tj |tjkr| d9 } |r!t| g dd d }nt| g dg dg dgd g d }|tjkr@| }n|d }||S )zxsame as matlab rgb2ycbcr
    only_y: only return Y channel
    Input:
        uint8, [0, 255]
        float, [0, 1]
    r    )X9^P@V-`@K8@      0@r1   gtB      \@r2   gERgMrWr3   r6   gX962      r;   dtypeastyper   r"   r'   dotmatmulr)   r   only_yin_img_typerltr   r   r   	rgb2ycbcr6   &   



rE   c                 C   st   | j }| tj |tjkr| d9 } t| g dg dg dgd g d }|tjkr1| }n|d }||S )zVsame as matlab ycbcr2rgb
    Input:
        uint8, [0, 255]
        float, [0, 1]
    r    )oݩr?rG   rG   )r   g]	+Yg}3?)gy?gN jr   )gxkgOn`@gL7A`Mq)r=   r>   r   r"   r'   r@   r)   )r   rC   rD   r   r   r   	ycbcr2rgbO   s    



rH   c                 C   r0   )zxbgr version of rgb2ycbcr
    only_y: only return Y channel
    Input:
        uint8, [0, 255]
        float, [0, 1]
    r    )r3   r2   r1   r4   r8   r7   r5   r9   r<   rA   r   r   r   	bgr2ycbcrf   rF   rI   c                 C   sz   | dkr|dkrdd |D }dd |D S | dkr,|dkr,dd |D }dd |D S | d	kr;|d
kr;dd |D S |S )Nr   grayc                 S      g | ]	}t |t jqS r   )r   r   COLOR_BGR2GRAY.0r   r   r   r   
<listcomp>       z#channel_convert.<locals>.<listcomp>c                 S      g | ]	}t j|d dqS r   r   r   r   rM   r   r   r   rO      rP   yc                 S   s   g | ]}t |d dqS )T)rB   )rI   rM   r   r   r   rO      s    c                 S   rQ   rR   rS   rM   r   r   r   rO      rP   r   RGBc                 S   rK   r   )r   r   COLOR_GRAY2BGRrM   r   r   r   rO      rP   r   )in_ctar_typeimg_list	gray_listy_listr   r   r   channel_convert   s   r\   c                 C   s   | j |j ks
td| j d d \}}| ||| ||| f } |||| ||| f }| tj} |tj}t| | d }|dkrLtdS dtdt	|  S )N+Input images must have the same dimensions.r   r   inf   r    )
shape
ValueErrorr>   r   float64meanfloatmathlog10sqrt)img1img2borderhwmser   r   r   calculate_psnr   s   rn   c              	   C   s  | j |j ks
td| j dd \}}| ||| ||| f } |||| ||| f }| jdkr9t| |S | jdkr| j d dkrog }tdD ]}|t| dddd|f |dddd|f  qKt| S | j d dkrtt	| t	|S dS td)zMcalculate SSIM
    the same outputs as MATLAB's
    img1, img2: [0, 255]
    r]   Nr   r   r   zWrong input image dimensions.)
r`   ra   r   ssimrangeappendr   arrayrc   squeeze)rh   ri   rj   rk   rl   ssimsir   r   r   calculate_ssim   s"   


6rv   c                 C   s:  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 )	Ng(\@gzGBM@         ?   r   )	r>   r   rb   r   getGaussianKernelouter	transposefilter2Drc   )rh   ri   C1C2kernelwindowmu1mu2mu1_sqmu2_sqmu1_mu2	sigma1_sq	sigma2_sqsigma12ssim_mapr   r   r   ro      s,   &&&



ro   c                 C   sn   t | }|d }|d }d| d|  d |dk| d| d|  d|  d |dk|dk |  S )Nr   r   rx   g      @r            )torchabstype_as)xabsxabsx2absx3r   r   r   cubic   s   
 0r   c                 C   s  |dk r
|r
|| }t d||}|| ddd|    }t ||d  }t|d }	||d||	t d|	d |	d|	||	 }
||d||	|
 }|dk rc|rc|t||  }nt|}t |d|d}||||	 }t |dkd}tj	|d ddds|

dd|	d }
|
dd|	d }tj	|d ddds|

dd|	d }
|
dd|	d }| }|
 }
|
  d }|
 |  }|
| d }
||
t|t|fS )Nr         ?r   r   gư>)rel_tolry   )r   linspacefloorre   ceilviewexpandr   sumisclosenarrow
contiguousminmaxint)	in_length
out_lengthscaler   kernel_widthantialiasingr   uleftPindicesdistance_to_centerweightsweights_sumweights_zero_tmp	sym_len_s	sym_len_er   r   r   calculate_weights_indices   s<   
r   c                 C   sR  |   dkrdnd}|r| d |  \}}}|t|| t|| }}}	d}
d}t|||||
|\}}}}t||	|||
|\}}}}t||| | |}|d||	|  | d d d |d d f }t
|dd dd }|d|}|dd|	| | d d | d d d f }t
|dd dd }|d|}|d|| |	| t|||}|d}
t|D ].}t|| d }t|D ]}|||||
 d d f dd|| |||d d f< qqt|||| | }|d||	| |d d d d d |f }t
|dd dd }|d|}|dd|	| |d d d d | d f }t
|dd dd }|d|}|d|| |	| t|||	}|d}
t|	D ],}t|| d }t|D ]}||d d |||
 f || ||d d |f< qqs|r|  |S )	Nr   TFr   r   r   r   ry   )dim
unsqueeze_sizere   r   r   r   FloatTensorr   copy_arangelongindex_selectrp   r   r~   mvsqueeze_)r   r   r   need_squeezein_Cin_Hin_Wout_Cout_Hout_Wr   r   	weights_H	indices_H
sym_len_Hs
sym_len_He	weights_W	indices_W
sym_len_Ws
sym_len_Weimg_aug	sym_patchinv_idxsym_patch_invout_1ru   idxj	out_1_augout_2r   r   r   imresize  sx   






r   c                 C   s`  t | } |  dkrdnd}|r| d |  \}}}|t|| t|| }}}	d}
d}t|||||
|\}}}}t||	|||
|\}}}}t || | ||}|	d||
|  | d |d d d d f }t |dd dd }|d|}|	dd|
| | | d d d d d f }t |dd dd }|d|}|	d|| |
| t |||}|d}
t|D ].}t|| d }t|D ]}||||
 d d |f dd|| ||d d |f< qqt ||| | |}|	d||
| |d d d |d d f }t |dd dd }|d|}|	dd|
| |d d | d d d f }t |dd dd }|d|}|	d|| |
| t ||	|}|d}
t|	D ],}t|| d }t|D ]}|d d |||
 |f || |d d ||f< qqx|r|  | S )	Nr   TFr   r   r   r   ry   )r   
from_numpyr   r   r   re   r   r   r   r   r   r   r   r   rp   r   r~   r   r   numpy)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ru   r   r   r   r   r   r   r   imresize_np]  sz   




r   c                 C   sB   | j dd \}}t| }|d|||  d|||  df S )zq
    Args:
        img: numpy image, WxH or WxHxC
        sf: scale factor
    Return:
        cropped image
    Nr   .)r`   r   copy)r   sfrl   rk   imr   r   r   
modcrop_np  s   
&r   c                 C   s   | j d }td| d d| d f}t|D ])}t|D ]"}|d| d| | d| d| | f  | ||f |  7  < qq|d }||| || f }||  S )zLCalculate the X4 kernel from the X2 kernel (for proof see appendix in paper)r   r   r   )r`   r   zerosrp   r   )kk_sizebig_krccropcropped_big_kr   r   r   analytic_kernel  s   
Br         c           	   	   C   s   t t t |t | gt |t |ggt ddg}t |d |d g|d |d  gg}t |dgd|gg}t t ||t j|}tddg|| d}|S )aM   generate an anisotropic Gaussian kernel
    Args:
        ksize : e.g., 15, kernel size
        theta : [0,  pi], rotation angle range
        l1    : [0.1,50], scaling of eigenvalues
        l2    : [0.1,l1], scaling of eigenvalues
        If l1 = l2, will get an isotropic Gaussian kernel.
    Returns:
        k     : kernel
          ?        r   r   )rc   covr   )r   r?   rr   cossinlinalginvgm_blur_kernel)	ksizethetal1l2vVDSigmar   r   r   r   anisotropic_Gaussian  s   (r   c           	      C   s~   |d d }t ||g}t|D ]$}t|D ]}|| d }|| d }tjj||g| |d|||f< qq|t | }|S )N       @r   r   )rc   r   )r   r   rp   statsmultivariate_normalpdfr   )	rc   r   r   centerr   rT   r   cycxr   r   r   r     s   r   c                 C   s   | j dd \}}|d d }td|dtd|d}}|r)|| }|| }	n|| }|| }	t|d|d }t|	d|d }	| jdkrQt||| ||	} | jdkr{t| j d D ]}
t||| dddd|
f ||	| dddd|
f< q]| S )	zshift pixel for super-resolution with different scale factors
    Args:
        x: WxHxC or WxH
        sf: scale factor
        upper_left: shift direction
    Nr   r   r   r   r   r   ry   )r`   r   r   r(   r   r   rp   )r   r   
upper_leftrk   rl   shiftxvyvx1y1ru   r   r   r   shift_pixel  s    


8r  c                 C   s   | j dd \}}|j d d d |j d d d }}tjjj| ||||fdd} |d|dd}|dd|j d |j d }| dd| j d | j d } tjjj| |ddd	|| d
} | ||| j d | j d } | S )z2
    x: image, NxcxHxW
    k: kernel, Nx1xhxw
    Nr   r   ry   	replicate)padmoder   r   )biasstridepaddinggroups)r`   r   nn
functionalr  repeatr   conv2d)r   r   nr   p1p2r   r   r   blur  s   &r  r   333333?g      $@c                 C   s  |t j ||   }|t j ||   }t j t j }| t jj|  | d  }t ||g}	t t |t | gt |t |gg}
|
|	 |
j }t j	
|ddddddf }| d d|d   }|dddddf }t t| d t| d \}}t ||gddddddddf }|| }|dddd}t dt || |  d|  }|t | }|S )z"
    # modified version of https://github.com/assafshocher/BlindSR_dataset_generator
    # Kai Zhang
    # min_var = 0.175 * sf  # variance of the gaussian kernel will be sampled between min_var and max_var
    # max_var = 2.5 * sf
    r   Nr   r   r   r   r   )r   randomrandpidiagrr   r   r   Tr   r   meshgridrp   stackr~   exprs   r   )r   scale_factormin_varmax_varnoise_levellambda_1lambda_2r   noiseLAMBDAQSIGMA	INV_SIGMAMUXYZZZZZ_t
raw_kernelr   r   r   r   
gen_kernel  s&     ($r4  c           	      C   s   | | g} | d d d | d d d g}|}t t |d  |d d t |d  |d d \}}|| ||   d| |  }t |}d||ttj|  k < |	 }|dkrb|| }|S )Nr   r   r   r   r   )
r   r  r   r!  scipyfinford   epsr   r   )	hsizesigmasizstdr   rT   argrk   sumhr   r   r   fspecial_gaussianI  s    0
r>  c                 C   sb   t dt| dgg} | | d  }d|  | d  }|||g|d| d  |g|||gg}t|}|S )Nr   r   )r   r   r   rr   )alphah1h2rk   r   r   r   fspecial_laplacianX  s   $
rC  c                 O   s0   | dkrt |i |S | dkrt|i |S d S )Ngaussian	laplacian)r>  rC  )filter_typeargskwargsr   r   r   fspeciala  s
   rI  c                 C   s   t | d| d} | S )z
    Args:
        x: HxWxC image, [0, 1]
        sf: down-scale factor
    Return:
        bicubicly downsampled LR image
    r   )r   )r   )r   r   r   r   r   bicubic_degradationh  s   rJ  c                 C   s,   t jj| tj|dddd} t| |d} | S )a   blur + bicubic downsampling
    Args:
        x: HxWxC image, [0, 1]
        k: hxw, double
        sf: down-scale factor
    Return:
        downsampled LR image
    Reference:
        @inproceedings{zhang2018learning,
          title={Learning a single convolutional super-resolution network for multiple degradations},
          author={Zhang, Kai and Zuo, Wangmeng and Zhang, Lei},
          booktitle={IEEE Conference on Computer Vision and Pattern Recognition},
          pages={3262--3271},
          year={2018}
        }
    r   r   wrapr  r   )r   filtersconvolver   r   rJ  r   r   r   r   r   r   srmd_degradationt  s   rQ  c                 C   s,   t | |d} tjj| tj|dddd} | S )a   bicubic downsampling + blur
    Args:
        x: HxWxC image, [0, 1]
        k: hxw, double
        sf: down-scale factor
    Return:
        downsampled LR image
    Reference:
        @inproceedings{zhang2019deep,
          title={Deep Plug-and-Play Super-Resolution for Arbitrary Blur Kernels},
          author={Zhang, Kai and Zuo, Wangmeng and Zhang, Lei},
          booktitle={IEEE Conference on Computer Vision and Pattern Recognition},
          pages={1671--1681},
          year={2019}
        }
    rM  r   r   rK  rL  )rJ  r   rN  rO  r   r   rP  r   r   r   dpsr_degradation  s   rR  c                 C   s:   t jj| tj|dddd} d}| |d||d|df S )z blur + downsampling
    Args:
        x: HxWxC image, [0, 1]/[0, 255]
        k: hxw, double
        sf: down-scale factor
    Return:
        downsampled LR image
    r   r   rK  rL  r   N.)r   rN  rO  r   r   )r   r   r   str   r   r   classical_degradation  s   	rT  r   2   
   c           	      C   s   |d dkr
|d7 }t | ||fd}| | }t|d |k}|d}t |||fd}| ||  }t|dd}|| d| |   S )a  USM sharpening. borrowed from real-ESRGAN
    Input image: I; Blurry image: B.
    1. K = I + weight * (I - B)
    2. Mask = 1 if abs(I - B) > threshold, else: 0
    3. Blur mask:
    4. Out = Mask * K + (1 - Mask) * I
    Args:
        img (Numpy array): Input image, HWC, BGR; float32, [0, 1].
        weight (float): Sharp weight. Default: 1.
        radius (float): Kernel size of Gaussian blur. Default: 50.
        threshold (int):
    r   r   r      r"   )r   GaussianBlurr   r   r>   r(   )	r   weightradius	thresholdr  residualmask	soft_maskKr   r   r   add_sharpening  s   
r`  c                 C   s   d| }dd|  }|d }|d }t   dk r8|t    }|t    }tt ddd t   tj ||d	}ntd
t ddd |t    }tjj| tj	|dddd} | S )N      @r   皙?r   r   r   rw   r   r   r   r   r   rD  r   mirrorrL  
r  r   randintr   r  rI  r   rN  rO  r   r   r   wd2wdr   r   r   r   r   r   
add_blur_1  s(   rj  c                 C   s   t j }|dkrtdd}n|dk rtd| d}nd}tj| t|| jd  t|| jd  ftg dd	} t 	| d
d} | S )N皙?r   r   gffffff?r   r   r   r   r   r   interpolationr   )
r   r  r  uniformr   resizer   r`   choicer(   )r   r   rnumsf1r   r   r   
add_resize  s   
$rt  r      c           	   	   C   s  t ||}tj  }|dkr!| tj d|d | jtj } n^|dk r@| tj d|d g | jd d dR tj } n?|d }ttj d}t	tj dd}t
t
t|||}| tj g dt|d | | jd d tj } t| d	d
} | S )Nr  r   r    皙?r   r   r   r   r   r   r   r   )r  rf  r   r  normalr`   r>   r"   r  r   r?   r~   r   r   r(   	r   noise_level1noise_level2r%  rr  Lr   Uconvr   r   r   add_Gaussian_noise  s2   

r  c           	   
   C   s(  t ||}t| dd} t   }|dkr)| | tj d|d | jtj 7 } nb|dk rJ| | tj d|d g | jd d dR tj 7 } nA|d }ttj 	d	}t
tj 	d	d	}ttt|||}| | tj g d
t|d | | jd d tj 7 } t| dd} | S )Nr   r   r  r   r    rv  r   r   r   rw  )r  rf  r   r(   rx  r`   r>   r"   r  r  r   r?   r~   r   r   ry  r   r   r   add_speckle_noise  s4   
"r  c                 C   s   t | d  ddd } ddt  d  }t dk r,t j| | t j| } n9t | dd d	f g d
}t |d  ddd }t j|| t j| | }| |d d d d t jf 7 } t | dd} | S )Nr    r   rW  rV  r   r   r   .r   )gA`"?gbX9?gv/?r   r   )	r   r(   r)   r  poissonr>   r"   r?   newaxis)r   valsimg_gray
noise_grayr   r   r   add_Poisson_noise  s    r  c                 C   s\   t dd}tt| tj} td| ttj|g\}}t	|d} tt
| tj} | S )NP   _   z.jpgr   )r  rf  r   r   r*   COLOR_RGB2BGRimencoder   IMWRITE_JPEG_QUALITYimdecoder$   r   )r   quality_factorresultencimgr   r   r   add_JPEG_noise(  s   r  @   c           
      C   s   | j d d \}}td|| }td|| }| ||| ||| d d f } t|| t|| }}	|||||  |	|	||  d d f }| |fS )Nr   r   )r`   r  rf  r   )
lqhqr   lq_patchsizerk   rl   rnd_hrnd_wrnd_h_Hrnd_w_Hr   r   r   random_crop2  s   "r  c              	   C   s  t | } d\}}}| jdd \}}|  d|||  d|||  df } | jdd \}}	|dkrnt |k rntj dk r_tj| td| jd  td| jd  ft	g d	d
} nt
| dd} t| dd} d}ttdd}
|
d|
d}}||kr|
| |
| |
|< |
|< |
D ]}|dkrt| |d} q|dkr| jd | jd }}t dk rtdd| }tj| td| | jd  td| | jd  ft	g d	d
} n2tddtdd| }t||}||  }tjj| tj|dddd} | dd|dd|df } t| dd} q|dkrCtj| td| | td| | ft	g d	d
} t| dd} q|dkrPt| ddd} q|dkr`t |k r`t| } qt| } t| } | S )  
    This is the variant of the degradation model of BSRGAN from the paper
    "Designing a Practical Degradation Model for Deep Blind Image Super-Resolution"
    sf: scale factor
    isp_model: camera ISP model
    Returns
    img: low-quality patch, size: lq_patchsizeXlq_patchsizeXC, range: [0, 1]
    hq: corresponding high-quality patch, size: (lq_patchsizexsf)X(lq_patchsizexsf)XC, range: [0, 1]
          ?g?r  Nr   .r   r   r   r   rl  rm  Tr   r      r   rM  rk  rD  ru  皙?r  r   rd  rL  rz  r{  rz   )r$   r`   r   r  r   r  r   rp  r   rq  r   r(   samplerp   indexrj  ro  rI  r  r   r   rN  rO  r   r  r  r*   imager   	isp_model_	jpeg_probscale2_probrA  w1rk   rl   shuffle_orderidx1idx2ru   abrs  r   	k_shiftedr   r   r   r	   >  sv   

*"


 

c                 C   s   d| }dd|  }t   dk r2|t    }|t    }tdt dd d t   tj ||d}ntd	dt dd d |t    }tjj| tj	|dd
dd} | S )Nra  r   rb  r   r   rw   r   rc  rD  r   rd  rL  re  rg  r   r   r   
add_blur_2  s$   
r  c              	   C   s  t | } d\}}}| jdd \}}|  d|||  d|||  df } | jdd \}}	|dkrnt |k rntj dk r_tj| td| jd  td| jd  ft	g d	d
} nt
| dd} t| dd} d}ttdd}
|
d|
d}}||kr|
| |
| |
|< |
|< |
D ]}|dkrt| |d} q|dkrt| |d} q|dkr&| jd | jd }}t dk rtdd| }tj| td| | jd  td| | jd  ft	g d	d
} n2tddtdd| }t||}||  }tjj| tj|dddd} | dd|dd|df } t| dd} q|dkrNtj| td| | td| | ft	g d	d
} t| dd} q|dkr[t| ddd} q|dkrkt |k rkt| } qt| } t| } | S )r  r  Nr   .r   r   r   r   rl  rm  Tr   r   r  r   rM  g      ?rD  ru  r  r  r   rd  rL  r  rz   )r$   r`   r   r  r   r  r   rp  r   rq  r   r(   r  rp   r  r  ro  rI  r  r   r   rN  rO  r   r  r  r*   r  r   r   r   r
     sz   

*"


 

)r   )T)r   )r   )r   rU  rV  )r   )r   ru  )r   r  )r   N)>re   osr  r   r   r   r5  scipy.statsr   r   r   scipy.interpolater   scipy.linalgr   torchvision.utilsr   environ__all__r   r$   r*   r-   r/   rE   rH   rI   r\   rn   rv   ro   r   r   r   r   r   r   r  r   r   r  r  rr   r4  r>  rC  rI  rJ  rQ  rR  rT  r`  rj  rt  r  r  r  r  r  r	   r  r
   r   r   r   r   <module>   sx   






9
JL


/	












K