o
    .wi$                     @   s   d dl mZ d dl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mZmZ d dlmZ d dlmZmZ d d	lmZmZmZ d d
lmZmZ esSdgZergergdddZerfeesfddgZnddgZG dd deZdS )    )Sequence)AnyOptionalUnionN)Tensor)Literal)_ARNIQA_TYPE_REGRESSOR_DATASET_arniqa_compute_arniqa_update_NoTrainArniqa)Metric)_SKIP_SLOW_DOCTEST_try_proceed_with_timeout)_MATPLOTLIB_AVAILABLE_TORCH_GREATER_EQUAL_2_2_TORCHVISION_AVAILABLE)_AX_TYPE_PLOT_OUT_TYPEARNIQA.plotreturnc                   C   s   t dd d S )Nkoniq10kregressor_dataset)r    r   r   V/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/image/arniqa.py_download_arniqa&   s   r   ARNIQAc                       s   e Zd ZU dZdZeed< dZeed< dZeed< dZ	e
ed< d	Ze
ed
< eed< eed< dZeed< 				d$deded dedededdf fddZ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  ARNIQA: leArning distoRtion maNifold for Image Quality Assessment metric.

    `ARNIQA`_ is a No-Reference Image Quality Assessment metric that predicts the technical quality of an image with
    a high correlation with human opinions. ARNIQA consists of an encoder and a regressor. The encoder is a ResNet-50
    model trained in a self-supervised way to model the image distortion manifold to generate similar representation for
    images with similar distortions, regardless of the image content. The regressor is a linear model trained on IQA
    datasets using the ground-truth quality scores. ARNIQA extracts the features from the full- and half-scale versions
    of the input image and then outputs a quality score in the [0, 1] range, where higher is better.

    The input image is expected to have shape ``(N, 3, H, W)``. The image should be in the [0, 1] range if `normalize`
    is set to ``True``, otherwise it should be normalized with the ImageNet mean and standard deviation.

    .. note::
        Using this metric requires you to have ``torchvision`` package installed. Either install as
        ``pip install torchmetrics[image]`` or ``pip install torchvision``.

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

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

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

    - ``arniqa`` (:class:`~torch.Tensor`): tensor with ARNIQA score. If `reduction` is set to ``none``, the output will
      have shape ``(N,)``, otherwise it will be a scalar tensor. Tensor values are in the [0, 1] range, where higher
      is better.

    Args:
        img: the input image
        regressor_dataset: dataset used for training the regressor. Choose between [``koniq10k``, ``kadid10k``].
            ``koniq10k`` corresponds to the `KonIQ-10k`_ dataset, which consists of real-world images with authentic
            distortions. ``kadid10k`` corresponds to the `KADID-10k`_ dataset, which consists of images with
            synthetically generated distortions.
        reduction: indicates how to reduce over the batch dimension. Choose between [``sum``, ``mean``, ``none``].
        normalize: by default this is ``True`` meaning that the input is expected to be in the [0, 1] range. If set
            to ``False`` will instead expect input to be already normalized with the ImageNet mean and standard
            deviation.
        autocast: if ``True``, metric will convert model to mixed precision before running forward pass.
        kwargs: additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Raises:
        ModuleNotFoundError:
            If ``torchvision`` package is not installed
        ValueError:
            If ``regressor_dataset`` is not in [``"kadid10k"``, ``"koniq10k"``]
        ValueError:
            If ``reduction`` is not in [``"sum"``, ``"mean"``, ``"none"``]
        ValueError:
            If ``normalize`` is not a bool
        ValueError:
            If the input image is not a valid image tensor with shape [N, 3, H, W].
        ValueError:
            If the input image values are not in the [0, 1] range when ``normalize`` is set to ``True``

    Examples:
        >>> from torch import rand
        >>> from torchmetrics.image.arniqa import ARNIQA
        >>> img = rand(8, 3, 224, 224)
        >>> # Non-normalized input
        >>> metric = ARNIQA(regressor_dataset='koniq10k', normalize=True)
        >>> metric(img)
        tensor(0.5308)

        >>> from torch import rand
        >>> from torchmetrics.image.arniqa import ARNIQA
        >>> from torchvision.transforms import Normalize
        >>> img = rand(8, 3, 224, 224)
        >>> img = Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])(img)
        >>> # Normalized input
        >>> metric = ARNIQA(regressor_dataset='koniq10k', normalize=False)
        >>> metric(img)
        tensor(0.5065)

    Tis_differentiablehigher_is_betterFfull_state_update        plot_lower_boundg      ?plot_upper_bound
sum_scores
num_scoresmodelfeature_networkr   meanr   	reduction)sumr(   none	normalizeautocastkwargsr   Nc                    s   t  jdi | tstdtstdt|d| _d}||vr+td| d| || _	t
|ts:td| || _|| _| jdtd	d
d | jdtd	d
d d S )Nz'ARNIQA metric requires PyTorch >= 2.2.0zARNIQA metric requires that torchvision is installed. Either install as `pip install torchmetrics[image]` or `pip install torchvision`.r   )r(   r*   r+   z$Argument `reduction` must be one of z
, but got z.Argument `normalize` should be a bool but got r$   r!   r*   )dist_reduce_fxr%   r   )super__init__r   RuntimeErrorr   ModuleNotFoundErrorr   r&   
ValueErrorr)   
isinstanceboolr,   r-   	add_statetorchtensor)selfr   r)   r,   r-   r.   valid_reduction	__class__r   r   r1      s$   
zARNIQA.__init__imgc                 C   s>   t || j| j| jd\}}|  j| 7  _|  j|7  _dS )z)Update internal states with arniqa score.)r&   r,   r-   N)r   r&   r,   r-   r$   r*   r%   )r:   r>   lossr%   r   r   r   update   s   zARNIQA.updatec                 C   s   t | j| j| jS )zCompute final arniqa metric.)r
   r$   r%   r)   )r:   r   r   r   compute   s   zARNIQA.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.arniqa import ARNIQA
            >>> metric = ARNIQA(regressor_dataset='koniq10k')
            >>> metric.update(torch.rand(8, 3, 224, 224))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> import torch
            >>> from torchmetrics.image.arniqa import ARNIQA
            >>> metric = ARNIQA(regressor_dataset='koniq10k')
            >>> values = [ ]
            >>> for _ in range(3):
            ...     values.append(metric(torch.rand(8, 3, 224, 224)))
            >>> fig_, ax_ = metric.plot(values)

        )_plot)r:   rB   rC   r   r   r   plot   s   (r   )r   r(   TF)NN)__name__
__module____qualname____doc__r   r6   __annotations__r   r    r"   floatr#   r   r'   strr	   r   r   r1   r@   rA   r   r   r   r   r   rE   __classcell__r   r   r<   r   r   /   sJ   
 J")r   N)collections.abcr   typingr   r   r   r8   r   typing_extensionsr   $torchmetrics.functional.image.arniqar   r	   r
   r   r   torchmetrics.metricr   torchmetrics.utilities.checksr   r   torchmetrics.utilities.importsr   r   r   torchmetrics.utilities.plotr   r   __doctest_skip__r   r   r   r   r   r   <module>   s&   
