a
    d}                  	   @   s   d dl mZ d dlZd dlmZ d dlmZmZ d dlm	Z	 ej
ee ej
dddZdej
ej
eeeeej
dddZG dd dejZdS )    )ListN)filter2dget_gaussian_kernel2d)_compute_padding)imgcropping_shapereturnc                 C   s0   t jj| |d  |d  |d  |d  fS )z.Crop out the part of "valid" convolution area.      r      )torchnnZ
functionalpad)r   r    r   \/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/metrics/ssim.py_crop
   s    $r         ?-q=same)img1img2window_sizemax_valepspaddingr   c                 C   s  t | tjstdt|  t |tjs<tdt| t |tsXtdt| t| jdksvtd| j t|jdkstd|j | j|jkstd| j d|j t	||fd	
d
}d| d }d| d }t| |}	t||}
g }|dkr:|jdd \}}t||g}t|	|}	t|
|}
n
|dkrD|	d }|
d }|	|
 }t| d |}t|d |}t| | |}|dkrt||}t||}t||}n
|dkr|| }|| }|| }d| | d| |  }|| | || |  }|||  S )a]  Function that computes the Structural Similarity (SSIM) index map between two images.

    Measures the (SSIM) index between each element in the input `x` and target `y`.

    The index can be described as:

    .. math::

      \text{SSIM}(x, y) = \frac{(2\mu_x\mu_y+c_1)(2\sigma_{xy}+c_2)}
      {(\mu_x^2+\mu_y^2+c_1)(\sigma_x^2+\sigma_y^2+c_2)}

    where:
      - :math:`c_1=(k_1 L)^2` and :math:`c_2=(k_2 L)^2` are two variables to
        stabilize the division with weak denominator.
      - :math:`L` is the dynamic range of the pixel-values (typically this is
        :math:`2^{\#\text{bits per pixel}}-1`).

    Args:
        img1: the first input image with shape :math:`(B, C, H, W)`.
        img2: the second input image with shape :math:`(B, C, H, W)`.
        window_size: the size of the gaussian kernel to smooth the images.
        max_val: the dynamic range of the images.
        eps: Small value for numerically stability when dividing.
        padding: ``'same'`` | ``'valid'``. Whether to only use the "valid" convolution
         area to compute SSIM to match the MATLAB implementation of original SSIM paper.

    Returns:
       The ssim index map with shape :math:`(B, C, H, W)`.

    Examples:
        >>> input1 = torch.rand(1, 4, 5, 5)
        >>> input2 = torch.rand(1, 4, 5, 5)
        >>> ssim_map = ssim(input1, input2, 5)  # 1x4x5x5
    z+Input img1 type is not a torch.Tensor. Got z+Input img2 type is not a torch.Tensor. Got z'Input max_val type is not a float. Got    z,Invalid img1 shape, we expect BxCxHxW. Got: z,Invalid img2 shape, we expect BxCxHxW. Got: z,img1 and img2 shapes must be the same. Got: z and )      ?r   r   g{Gz?r	   gQ?ZvalidNr   g       @)
isinstancer   Tensor	TypeErrortypefloatlenshape
ValueErrorr   Z	unsqueezer   r   r   )r   r   r   r   r   r   kernelZC1ZC2Zmu1Zmu2r   heightwidthZmu1_sqZmu2_sqZmu1_mu2Z
mu_img1_sqZ
mu_img2_sqZmu_img1_img2Z	sigma1_sqZ	sigma2_sqZsigma12numZdenr   r   r   ssim   sR    *









r*   c                       sH   e Zd ZdZdeeeedd fddZej	ej	ej	d	d
dZ
  ZS )SSIMa&  Create a module that computes the Structural Similarity (SSIM) index between two images.

    Measures the (SSIM) index between each element in the input `x` and target `y`.

    The index can be described as:

    .. math::

      \text{SSIM}(x, y) = \frac{(2\mu_x\mu_y+c_1)(2\sigma_{xy}+c_2)}
      {(\mu_x^2+\mu_y^2+c_1)(\sigma_x^2+\sigma_y^2+c_2)}

    where:
      - :math:`c_1=(k_1 L)^2` and :math:`c_2=(k_2 L)^2` are two variables to
        stabilize the division with weak denominator.
      - :math:`L` is the dynamic range of the pixel-values (typically this is
        :math:`2^{\#\text{bits per pixel}}-1`).

    Args:
        window_size: the size of the gaussian kernel to smooth the images.
        max_val: the dynamic range of the images.
        eps: Small value for numerically stability when dividing.
        padding: ``'same'`` | ``'valid'``. Whether to only use the "valid" convolution
         area to compute SSIM to match the MATLAB implementation of original SSIM paper.

    Shape:
        - Input: :math:`(B, C, H, W)`.
        - Target :math:`(B, C, H, W)`.
        - Output: :math:`(B, C, H, W)`.

    Examples:
        >>> input1 = torch.rand(1, 4, 5, 5)
        >>> input2 = torch.rand(1, 4, 5, 5)
        >>> ssim = SSIM(5)
        >>> ssim_map = ssim(input1, input2)  # 1x4x5x5
    r   r   r   N)r   r   r   r   r   c                    s&   t    || _|| _|| _|| _d S N)super__init__r   r   r   r   )selfr   r   r   r   	__class__r   r   r.      s
    
zSSIM.__init__)r   r   r   c                 C   s   t ||| j| j| j| jS r,   )r*   r   r   r   r   )r/   r   r   r   r   r   forward   s    zSSIM.forward)r   r   r   )__name__
__module____qualname____doc__intr"   strr.   r   r   r2   __classcell__r   r   r0   r   r+   |   s   $r+   )r   r   r   )typingr   r   Ztorch.nnr   Zkornia.filtersr   r   Zkornia.filters.filterr   r   r7   r   r"   r8   r*   Moduler+   r   r   r   r   <module>   s$      k