o
    yi(2                     @   s   d dl mZmZmZmZmZmZ d dlZd dlmZ d dl	m
Z
 d dlmZmZmZ d dlmZ d dlmZ G dd	 d	eZG d
d deZdS )    )AnyListOptionalSequenceTupleUnionN)Tensor)Literal)_multiscale_ssim_update_ssim_check_inputs_ssim_update)Metric)dim_zero_catc                       s   e Zd ZU dZdZeed< dZeed< dZeed< e	e
 ed< e	e
 ed< 				
						d!dedeeee f deeee f ded dee dedededededdf fddZde
de
ddfddZdee
ee
e
f f fdd Z  ZS )" StructuralSimilarityIndexMeasurea  Computes Structual Similarity Index Measure (SSIM_).

    As input to ``forward`` and ``update`` the metric accepts the following input

    - ``preds`` (:class:`~torch.Tensor`): Predictions from model
    - ``target`` (:class:`~torch.Tensor`): Ground truth values

    As output of `forward` and `compute` the metric returns the following output

    - ``ssim`` (:class:`~torch.Tensor`): if ``reduction!='none'`` returns float scalar tensor with average SSIM value
      over sample else returns tensor of shape ``(N,)`` with SSIM values per sample

    Args:
        preds: estimated image
        target: ground truth image
        gaussian_kernel: If ``True`` (default), a gaussian kernel is used, if ``False`` a uniform kernel is used
        sigma: Standard deviation of the gaussian kernel, anisotropic kernels are possible.
            Ignored if a uniform kernel is used
        kernel_size: the size of the uniform kernel, anisotropic kernels are possible.
            Ignored if a Gaussian kernel is used
        reduction: a method to reduce metric score over individual batch scores

            - ``'elementwise_mean'``: takes the mean
            - ``'sum'``: takes the sum
            - ``'none'`` or ``None``: no reduction will be applied

        data_range: Range of the image. If ``None``, it is determined from the image (max - min)
        k1: Parameter of SSIM.
        k2: Parameter of SSIM.
        return_full_image: If true, the full ``ssim`` image is returned as a second argument.
            Mutually exclusive with ``return_contrast_sensitivity``
        return_contrast_sensitivity: If true, the constant term is returned as a second argument.
            The luminance term can be obtained with luminance=ssim/contrast
            Mutually exclusive with ``return_full_image``
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Example:
        >>> from torchmetrics import StructuralSimilarityIndexMeasure
        >>> import torch
        >>> preds = torch.rand([3, 3, 256, 256])
        >>> target = preds * 0.75
        >>> ssim = StructuralSimilarityIndexMeasure(data_range=1.0)
        >>> ssim(preds, target)
        tensor(0.9219)
    Thigher_is_betteris_differentiableFfull_state_updatepredstarget      ?   elementwise_meanN{Gz?Q?gaussian_kernelsigmakernel_size	reductionr   sumnoneN
data_rangek1k2return_full_imagereturn_contrast_sensitivitykwargsreturnc
                    s   t  jdi |
 d}||vrtd| d| |dv r)| jdtddd n| jdg d	d | jd
tddd |	s@|rH| jdg d	d || _|| _|| _|| _	|| _
|| _|| _|| _|	| _d S )Nr   $Argument `reduction` must be one of 
, but got r   r   
similarity        r   defaultdist_reduce_fxcattotalimage_return )super__init__
ValueError	add_statetorchtensorr   r   r   r   r!   r"   r#   r$   r%   )selfr   r   r   r   r!   r"   r#   r$   r%   r&   valid_reduction	__class__r3   K/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/image/ssim.pyr5   O   s&   
z)StructuralSimilarityIndexMeasure.__init__c                 C   s   t ||\}}t||| j| j| j| j| j| j| j| j	
}t
|tr&|\}}n|}| j	s.| jr4| j| | jdv rN|  j| 7  _|  j|jd 7  _dS | j| dS )*Update state with predictions and targets.r*   r   N)r   r   r   r   r   r!   r"   r#   r$   r%   
isinstancetupler2   appendr   r+   r   r1   shape)r:   r   r   similarity_packr+   imager3   r3   r>   updatev   s,   


z'StructuralSimilarityIndexMeasure.updatec                 C   sV   | j dkr| j| j }n| j dkr| j}nt| j}| js | jr)t| j}||fS |S )zComputes SSIM over state.r   r   )r   r+   r1   r   r%   r$   r2   )r:   r+   r2   r3   r3   r>   compute   s   



z(StructuralSimilarityIndexMeasure.compute)	Tr   r   r   Nr   r   FF)__name__
__module____qualname____doc__r   bool__annotations__r   r   r   r   r   floatr   intr	   r   r   r5   rF   r   rG   __classcell__r3   r3   r<   r>   r      sR   
 .	
'&r   c                       s   e Zd ZU dZdZeed< dZeed< dZeed< e	e
 ed< e	e
 ed< 				
						d%dedeeee f deeee f ded dee dededeedf ded deddf fdd Zde
de
ddfd!d"Zde
fd#d$Z  ZS )&*MultiScaleStructuralSimilarityIndexMeasurea{
  Computes `MultiScaleSSIM`_, Multi-scale Structural Similarity Index Measure, which is a generalization of
    Structural Similarity Index Measure by incorporating image details at different resolution scores.

    As input to ``forward`` and ``update`` the metric accepts the following input

    - ``preds`` (:class:`~torch.Tensor`): Predictions from model
    - ``target`` (:class:`~torch.Tensor`): Ground truth values

    As output of `forward` and `compute` the metric returns the following output

    - ``msssim`` (: :class:`~torch.Tensor`): if ``reduction!='none'`` returns float scalar tensor with average MSSSIM
      value over sample else returns tensor of shape ``(N,)`` with SSIM values per sample

    Args:
        gaussian_kernel: If ``True`` (default), a gaussian kernel is used, if false a uniform kernel is used
        kernel_size: size of the gaussian kernel
        sigma: Standard deviation of the gaussian kernel
        reduction: a method to reduce metric score over labels.

            - ``'elementwise_mean'``: takes the mean
            - ``'sum'``: takes the sum
            - ``'none'`` or ``None``: no reduction will be applied

        data_range: Range of the image. If ``None``, it is determined from the image (max - min)
        k1: Parameter of structural similarity index measure.
        k2: Parameter of structural similarity index measure.
        betas: Exponent parameters for individual similarities and contrastive sensitivies returned by different image
            resolutions.
        normalize: When MultiScaleStructuralSimilarityIndexMeasure loss is used for training, it is desirable to use
            normalizes to improve the training stability. This `normalize` argument is out of scope of the original
            implementation [1], and it is adapted from https://github.com/jorge-pessoa/pytorch-msssim instead.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Return:
        Tensor with Multi-Scale SSIM score

    Raises:
        ValueError:
            If ``kernel_size`` is not an int or a Sequence of ints with size 2 or 3.
        ValueError:
            If ``betas`` is not a tuple of floats with lengt 2.
        ValueError:
            If ``normalize`` is neither `None`, `ReLU` nor `simple`.

    Example:
        >>> from torchmetrics import MultiScaleStructuralSimilarityIndexMeasure
        >>> import torch
        >>> preds = torch.rand([3, 3, 256, 256], generator=torch.manual_seed(42))
        >>> target = preds * 0.75
        >>> ms_ssim = MultiScaleStructuralSimilarityIndexMeasure(data_range=1.0)
        >>> ms_ssim(preds, target)
        tensor(0.9627)
    Tr   r   Fr   r   r   r   r   r   Nr   r   gǺ?g48EG?ga4?g??g9EGr?relur   r   r   r   r   r!   r"   r#   betas.	normalize)rS   simpleNr&   r'   c
                    sN  t  jdi |
 d}||vrtd| d| |dv r)| jdtddd n| jdg d	d | jd
tddd t|ttfsJtd| t|tret	|dvs^t
dd |D setd| || _|| _|| _|| _|| _|| _|| _t|tstdt|trt
dd |D std|| _|	r|	dvrtd|	| _d S )Nr   r(   r)   r*   r+   r,   r   r-   r0   r1   zRArgument `kernel_size` expected to be an sequence or an int, or a single int. Got )      c                 s       | ]}t |tV  qd S N)r@   rO   ).0ksr3   r3   r>   	<genexpr>      zFMultiScaleStructuralSimilarityIndexMeasure.__init__.<locals>.<genexpr>ztArgument `kernel_size` expected to be an sequence of size 2 or 3 where each element is an int, or a single int. Got z3Argument `betas` is expected to be of a type tuple.c                 s   rY   rZ   )r@   rN   )r[   betar3   r3   r>   r]     r^   z5Argument `betas` is expected to be a tuple of floats.)rS   rV   zNArgument `normalize` to be expected either `None` or one of 'relu' or 'simple'r3   )r4   r5   r6   r7   r8   r9   r@   r   rO   lenallr   r   r   r   r!   r"   r#   rA   rT   rU   )r:   r   r   r   r   r!   r"   r#   rT   rU   r&   r;   r<   r3   r>   r5      sD   


z3MultiScaleStructuralSimilarityIndexMeasure.__init__c                 C   sz   t ||\}}t||| j| j| j| j| j| j| j| j	
}| j
dv r(| j| n	|  j| 7  _|  j|jd 7  _dS )r?   r    Nr   N)r   r
   r   r   r   r!   r"   r#   rT   rU   r   r+   rB   r   r1   rC   )r:   r   r   r+   r3   r3   r>   rF     s"   
z1MultiScaleStructuralSimilarityIndexMeasure.updatec                 C   s0   | j dv r
t| jS | j dkr| jS | j| j S )zComputes MS-SSIM over state.rb   r   )r   r   r+   r1   )r:   r3   r3   r>   rG   /  s
   


z2MultiScaleStructuralSimilarityIndexMeasure.compute)	Tr   r   r   Nr   r   rR   rS   )rH   rI   rJ   rK   r   rL   rM   r   r   r   r   r   rO   r   rN   r	   r   r   r   r5   rF   rG   rP   r3   r3   r<   r>   rQ      sR   
 6
	
6rQ   )typingr   r   r   r   r   r   r8   r   typing_extensionsr	   "torchmetrics.functional.image.ssimr
   r   r   torchmetrics.metricr   torchmetrics.utilities.datar   r   rQ   r3   r3   r3   r>   <module>   s     