Ë
    þÍ:j$  ã                   óö   — 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sdgZererdd„Zer ee«      s	ddgZnddgZ G d„ de«      Zy)é    )Ú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_TYPEzARNIQA.plotc                  ó   — t        d¬«       y )NÚkoniq10k©Úregressor_dataset)r	   © ó    ún/home/mcse/projects/srt_converter/srt-converter-venv/lib/python3.12/site-packages/torchmetrics/image/arniqa.pyÚ_download_arniqar   &   s
   € Ü *Ö-r   ÚARNIQAc                   ó  ‡ — 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„Zdeddfd„Zdefd„Z	 ddeeeee   f      dee   defd„Zˆ x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   Ú	reduction)ÚsumÚmeanÚnoneÚ	normalizeÚautocastÚkwargsÚreturnNc                 óº  •— t        ‰| �  di |¤Ž t        st        d«      ‚t        st        d«      ‚t        |¬«      | _        d}||vrt        d|› d|› �«      ‚|| _	        t        |t        «      st        d|› �«      ‚|| _        || _        | j                  dt        j                   d	«      d
¬«       | j                  dt        j                   d	«      d
¬«       y )Nz'ARNIQA metric requires PyTorch >= 2.2.0z‡ARNIQA 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/   r0   Úvalid_reductionÚ	__class__s          €r   r5   zARNIQA.__init__„   sÛ   ø€ ô 	‰ÑÑ"˜6Ò"å'ÜÐHÓIÐIå%Ü%ðeóð ô
 $Ð6GÔHˆŒ
à1ˆØ˜OÑ+ÜÐCÀOÐCTÐT^Ð_hÐ^iÐjÓkÐkØ"ˆŒä˜)¤TÔ*ÜÐMÈiÈ[ÐYÓZÐZØ"ˆŒØ ˆŒà�‰�|¤U§\¡\°#Ó%6ÀuˆÔMØ�‰�|¤U§\¡\°#Ó%6ÀuˆÕMr   Úimgc                 óÔ   — t        || j                  | j                  | j                  ¬«      \  }}| xj                  |j                  «       z  c_        | xj                  |z  c_        y)z)Update internal states with arniqa score.)r(   r.   r/   N)r   r(   r.   r/   r&   r+   r'   )r>   rA   Úlossr'   s       r   ÚupdatezARNIQA.update¦   sH   € ä)¨#°T·Z±ZÈ4Ï>É>Ðdh×dqÑdqÔrÑˆˆjØ�Š˜4Ÿ8™8›:Ñ%�Ø�Š˜:Ñ%Žr   c                 óX   — t        | j                  | j                  | j                  «      S )zCompute final arniqa metric.)r   r&   r'   r*   )r>   s    r   ÚcomputezARNIQA.compute¬   s   € ä˜tŸ™°·±ÀÇÁÓPÐPr   ÚvalÚaxc                 ó&   — | j                  ||«      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>   rG   rH   s      r   ÚplotzARNIQA.plot°   s   € ðP �z‰z˜#˜rÓ"Ð"r   )r   r,   TF)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r    r:   Ú__annotations__r!   r"   r$   Úfloatr%   r   r)   Ústrr
   r   r   r5   rD   rF   r   r   r   r   r   rK   Ú__classcell__)r@   s   @r   r   r   /   s  ø… ñHðT #Ð�tÓ"Ø!Ð�dÓ!Ø#Ð�tÓ#Ø!Ð�eÓ!Ø!Ð�eÓ!àÓØÓØ"€O�SÓ"ð 6@Ø4:ØØñ Nà2ð Nð Ð0Ñ1ð Nð ð	 Nð
 ð Nð ð Nð 
õ NðD&˜&ð & Tó &ðQ˜ó Qð
 _cñ(#Ø˜E &¨(°6Ñ*:Ð":Ñ;Ñ<ð(#ØIQÐRZÑI[ð(#à	÷(#r   )r1   N)Úcollections.abcr   Útypingr   r   r   r<   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   ú<module>r]      s|   ðõ %ß 'Ñ 'ã Ý Ý %÷õ õ 'ß Wß rÑ rß @áØ%�ÐáÑ 6ó.ñ Ñ";Ð<LÔ"MØ$ mÐ4Ñà  -Ð0Ðôi#ˆVõ i#r   