o
    oiI                     @   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 dej	dee
 dej	fd	d
Z			ddej	dej	de
dedededej	fddZG dd dejZdS )    )ListN)nn)filter2d_separableget_gaussian_kernel1d)_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      )torchr   
functionalpad)r   r    r   G/home/ubuntu/.local/lib/python3.10/site-packages/kornia/metrics/ssim.py_crop   s   $r         ?-q=sameimg1img2window_sizemax_valepspaddingc                 C   s  t | tjstdt|  t |tjstdt| t |ts,tdt| t| jdks;td| j t|jdksJtd|j | j|jks\td| j d|j t	|d	| j
| jd
}d| d }d| d }t| ||}	t|||}
g }|dkr|jd  }}t||g}t|	|}	t|
|}
n|dkr	 |	d }|
d }|	|
 }t| d ||}t|d ||}t| | ||}|dkrt||}t||}t||}n|dkr	 || }|| }|| }d| | d| |  }|| | || |  }|||  S )aO  Compute 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 g      ?)devicedtypeg{Gz?r
   gQ?validr   g       @)
isinstancer   Tensor	TypeErrortypefloatlenshape
ValueErrorr   r   r   r   r   r   )r   r   r   r   r   r   kernelC1C2mu1mu2r   heightwidthmu1_sqmu2_sqmu1_mu2
mu_img1_sq
mu_img2_sqmu_img1_img2	sigma1_sq	sigma2_sqsigma12numdenr   r   r   ssim"   sV   +



r;   c                       sT   e Zd ZdZddedededed	d
f
 fddZdej	dej	d	ej	f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   r   r   r   r   r	   Nc                    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   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"   rC   __classcell__r   r   rA   r   r<      s    $%$r<   rD   )typingr   r   r   kornia.filtersr   r   kornia.filters.filterr   r"   rI   r   r%   rJ   r;   Moduler<   r   r   r   r   <module>   s2   
l