
    3j                    p    S SK Jr  S SKJrJr  S SKrS SKJs  Jr	  S SKJr   " S S\R                  5      rg)    )annotations)OptionalSequenceN)nnc                     ^  \ rS rSrSr      S             S	U 4S jjjr S
         SS jjr S
         SS jjrSS jrSr	U =r
$ )MS_SSIMLoss   a  Creates a criterion that computes MSSIM + L1 loss.

According to [1], we compute the MS_SSIM + L1 loss as follows:

.. math::
    \text{loss}(x, y) = \alpha \cdot \mathcal{L_{MSSIM}}(x,y)+(1 - \alpha) \cdot G_\alpha \cdot \mathcal{L_1}(x,y)

Where:
    - :math:`\alpha` is the weight parameter.
    - :math:`x` and :math:`y` are the reconstructed and true reference images.
    - :math:`\mathcal{L_{MSSIM}}` is the MS-SSIM loss.
    - :math:`G_\alpha` is the sigma values for computing multi-scale SSIM.
    - :math:`\mathcal{L_1}` is the L1 loss.

Reference:
    [1]: https://research.nvidia.com/sites/default/files/pubs/2017-03_Loss-Functions-for/NN_ImgProc.pdf#page11

Args:
    sigmas: gaussian sigma values.
    data_range: the range of the images.
    K: k values.
    alpha : specifies the alpha value
    compensation: specifies the scaling coefficient.
    reduction : Specifies the reduction to apply to the
     output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction will be applied,
     ``'mean'``: the sum of the output will be divided by the number of elements
     in the output, ``'sum'``: the output will be summed.

Returns:
    The computed loss.

Shape:
    - Input1: :math:`(N, C, H, W)`.
    - Input2: :math:`(N, C, H, W)`.
    - Output: :math:`(N, H, W)` or scalar if reduction is set to ``'mean'`` or ``'sum'``.

Examples:
    >>> input1 = torch.rand(1, 3, 5, 5)
    >>> input2 = torch.rand(1, 3, 5, 5)
    >>> criterion = kornia.losses.MS_SSIMLoss()
    >>> loss = criterion(input1, input2)

c                H  > [         TU ]  5         X l        US   U-  S-  U l        US   U-  S-  U l        [        SUS   -  5      U l        X@l        XPl        X`l	        [        SUS   -  S-   5      n[        R                  " S[        U5      -  SXw45      n[        U5       Hk  u  pU R                  Xz5      USU	-  S-   SS S 2S S 24'   U R                  Xz5      USU	-  S-   SS S 2S S 24'   U R                  Xz5      USU	-  S-   SS S 2S S 24'   Mm     U R                  SU5        g )Nr               _g_masks)super__init__DRC1C2intpadalphacompensation	reductiontorchzeroslen	enumerate_fspecial_gauss_2dregister_buffer)selfsigmas
data_rangeKr   r   r   filter_sizeg_masksidxsigma	__class__s              O/home/wildlama/miniconda3/lib/python3.13/site-packages/kornia/losses/ms_ssim.pyr   MS_SSIMLoss.__init__K   s0    	#A$+1A$+1q6":~&!
#/' !fRj.1,-++q3v;;LM $F+JC,0,C,CK,WGAGaKAq(),0,C,CK,WGAGaKAq(),0,C,CK,WGAGaKAq() ,
 	Z1    c                    [         R                  " XUS9nXQS-  -  n[         R                  " US-  * SUS-  -  -  5      nXfR                  5       -  nUR	                  S5      $ )zCreate 1-D gauss kernel.

Args:
    size: the size of gauss kernel.
    sigma: sigma of normal distribution.
    device: device to store the result on.
    dtype: dtype of the result.

Returns:
    1D kernel (size).

)devicedtyper   r   )r   arangeexpsumreshape)r!   sizer(   r.   r/   coordsgs          r*   _fspecial_gauss_1dMS_SSIMLoss._fspecial_gauss_1di   s\     d?!)II	la%(l34	UUWyy}r,   c                R    U R                  XX45      n[        R                  " XU5      $ )zCreate 2-D gauss kernel.

Args:
    size: the size of gauss kernel.
    sigma: sigma of normal distribution.
    device: device to store the result on.
    dtype: dtype of the result.

Returns:
    2D kernel (size x size).

)r7   r   outer)r!   r4   r(   r.   r/   gaussian_vecs         r*   r   MS_SSIMLoss._fspecial_gauss_2d~   s%     ..tFJ{{<66r,   c                   [        U[        R                  5      (       d  [        S[	        U5       35      e[        U[        R                  5      (       d  [        S[	        U5       35      e[        UR                  5      [        UR                  5      :X  d$  [        S[	        U5       S[	        U5       S35      e[        R                  R                  [        R                  U R                  5      nUR                  S   n[        R                  " XX@R                  S9n[        R                  " X#X@R                  S9nXU-  nXf-  nXV-  n	[        R                  " X-  X4U R                  S9U-
  n
[        R                  " X"-  X4U R                  S9U-
  n[        R                  " X-  X4U R                  S9U	-
  nSU	-  U R                  -   Xx-   U R                  -   -  nSU-  U R                  -   X-   U R                  -   -  nUS	S	2S
S	S	2S	S	24   US	S	2SS	S	2S	S	24   -  US	S	2SS	S	2S	S	24   -  nUR!                  SS9nSUU-  -
  n[        R"                  " XSS9n[        R                  " UX4* S	 X@R                  S9R%                  S5      nU R&                  U-  SU R&                  -
  U-  U R(                  -  -   nU R*                  U-  nU R,                  S:X  a  [        R$                  " U5      nU$ U R,                  S:X  a  [        R.                  " U5      nU$ U R,                  S:X  a   U$ [1        SU R,                   35      e)zCompute MS_SSIM loss.

Args:
    img1: the predicted image with shape :math:`(B, C, H, W)`.
    img2: the target image with a shape of :math:`(B, C, H, W)`.

Returns:
    Estimated MS-SSIM_L1 loss.

z&Input type is not a torch.Tensor. Got z'Output type is not a torch.Tensor. Got z!Input shapes should be same. Got z and .)groupspaddingr   Nr   r   )dimnone)r   meanr2   zInvalid reduction mode: )
isinstancer   Tensor	TypeErrortyper   shape
ValueErrorjitannotater   Fconv2dr   r   r   prodl1_lossrE   r   r   r   r   r2   NotImplementedError)r!   img1img2r&   CHmuxmuymux2muy2muxysigmax2sigmay2sigmaxylccslMPIcsloss_ms_ssimloss_l1gaussian_l1losss                        r*   forwardMS_SSIMLoss.forward   s    $--DT$ZLQRR$--Ed4j\RSS4::#djj/1@dERVW[R\Q]]^_`` %		 2 25<< O**R.hhtRBhhtRByyy((4;DHHMPTT((4;DHHMPTT((4;DHHMPTT$h T[477%:;'kDGG#(9DGG(CD2q!_r!RA+.Ar1aK@ww1w~ 29} ))D&9 hhwb((SXXYZ[ zzL(A

Nk+IDGG+SS  4'>>V#::d#D  ^^u$99T?D
 	 ^^v%  &(@@P&QRRr,   )r   r   r   r   r   r   r   ))g      ?      ?g       @g      @g       @rh   )g{Gz?gQ?g?g      i@rE   )r"   zSequence[float]r#   floatr$   ztuple[float, float]r   ri   r   ri   r   strreturnNone)NN)
r4   r   r(   ri   r.   zOptional[torch.device]r/   zOptional[torch.dtype]rk   torch.Tensor)rS   rm   rT   rm   rk   rm   )__name__
__module____qualname____firstlineno____doc__r   r7   r   rf   __static_attributes____classcell__)r)   s   @r*   r   r      s    *\ #<!-#22 2 	2
 2 2 2 
2 2> nr %/EUj	, nr77 %7/E7Uj7	7$< <r,   r   )
__future__r   typingr   r   r   torch.nn.functionalr   
functionalrN   Moduler    r,   r*   <module>r{      s+   $ # %    n")) nr,   