o
    .wi]                     @   s   d dl 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 d dlmZmZ d dlmZmZ es9dgZes?d	dgZG d
d	 d	eZdS )    )AnyLiteralOptionalSequenceUnionN)Tensor)_dists_update)Metric)_MATPLOTLIB_AVAILABLE_TORCHVISION_AVAILABLE)_AX_TYPE_PLOT_OUT_TYPE+DeepImageStructureAndTextureSimilarity.plot&DeepImageStructureAndTextureSimilarityc                       s   e Zd ZU dZeed< eed< dZeed< dZeed< dZ	eed< d	Z
eed
< dde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	ddeeeee f  dee defddZ  ZS )r   a  Calculates Deep Image Structure and Texture Similarity (DISTS) score.

    The metric is a full-reference image quality assessment (IQA) model that combines sensitivity to structural
    distortions (e.g., artifacts due to noise, blur, or compression) with a tolerance of texture resampling
    (exchanging the content of a texture region with a new sample of the same texture). The metric is based on
    a convolutional neural network (CNN) that transforms the reference and distorted images to a new representation.
    Within this representation, a set of measurements are developed that are sufficient to capture the appearance
    of a variety of different visual distortions.

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

    - ``preds`` (:class:`~torch.Tensor`): tensor with images of shape ``(N, 3, H, W)``
    - ``target`` (:class:`~torch.Tensor`): tensor with images of shape ``(N, 3, H, W)``

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

    - ``lpips`` (:class:`~torch.Tensor`): returns float scalar tensor with average LPIPS value over samples

    Args:
        reduction: specifies the reduction to apply to the output.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Raises:
        ValueError:
            If `reduction` is not one of ["mean", "sum"]

    Example:
        >>> from torch import rand
        >>> from torchmetrics.image.dists import DeepImageStructureAndTextureSimilarity
        >>> metric = DeepImageStructureAndTextureSimilarity()
        >>> preds = rand(10, 3, 100, 100)
        >>> target = rand(10, 3, 100, 100)
        >>> metric(preds, target)
        tensor(0.1882, grad_fn=<CloneBackward0>)

    scoretotalTis_differentiableFhigher_is_betterfull_state_update        plot_lower_boundmean	reductionr   sumkwargsreturnNc                    sh   t  jd	i | d}||vrtd| d| || _| jdtddd | jdtddd d S )
Nr   z+Argument `reduction` expected to be one of z	 but got r   r   r   )defaultdist_reduce_fxr    )super__init__
ValueErrorr   	add_statetorchtensor)selfr   r   allowed_reductions	__class__r   U/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/image/dists.pyr!   M   s   z/DeepImageStructureAndTextureSimilarity.__init__predstargetc                 C   s4   t ||}|  j| 7  _|  j|jd 7  _dS )zUpdate the metric state.r   N)r   r   r   r   shape)r&   r+   r,   scoresr   r   r*   updateV   s   
z-DeepImageStructureAndTextureSimilarity.updatec                 C   s   | j dkr| j| j S | jS )zComputes the DISTS score.r   )r   r   r   )r&   r   r   r*   compute\   s   z.DeepImageStructureAndTextureSimilarity.computevalaxc                 C   s   |  ||S )a  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value
            >>> import torch
            >>> from torchmetrics.image.dists import DeepImageStructureAndTextureSimilarity
            >>> metric = DeepImageStructureAndTextureSimilarity()
            >>> metric.update(torch.rand(10, 3, 100, 100), torch.rand(10, 3, 100, 100))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> import torch
            >>> from torchmetrics.image.dists import DeepImageStructureAndTextureSimilarity
            >>> metric = DeepImageStructureAndTextureSimilarity()
            >>> values = [ ]
            >>> for _ in range(3):
            ...     values.append(metric(torch.rand(10, 3, 100, 100), torch.rand(10, 3, 100, 100)))
            >>> fig_, ax_ = metric.plot(values)

        )_plot)r&   r1   r2   r   r   r*   plot`   s   (r   )r   )NN)__name__
__module____qualname____doc__r   __annotations__r   boolr   r   r   floatr   r   r   r!   r/   r0   r   r   r   r   r4   __classcell__r   r   r(   r*   r      s&   
 %$	)typingr   r   r   r   r   r$   r   #torchmetrics.functional.image.distsr   torchmetrics.metricr	   torchmetrics.utilities.importsr
   r   torchmetrics.utilities.plotr   r   __doctest_skip__r   r   r   r   r*   <module>   s   