Ë
    ýÿæi%  ã                   ó”   — d dl mZ d dlmZmZmZ d dlZd dlmZmZ d dl	m
Z
mZ d dlmZ d dlmZ d dlmZmZ esd	gZ G d
„ de«      Zy)é    )ÚSequence)ÚAnyÚOptionalÚUnionN)ÚTensorÚtensor)Ú_psnrb_computeÚ_psnrb_update)ÚMetric)Ú_MATPLOTLIB_AVAILABLE)Ú_AX_TYPEÚ_PLOT_OUT_TYPEz*PeakSignalNoiseRatioWithBlockedEffect.plotc            	       óô   ‡ — e Zd ZU dZdZeed<   dZeed<   dZeed<   e	ed<   e	ed<   e	ed	<   e	ed
<   	 dd
e
eeeef   f   dededdfˆ fd„Zde	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 )Ú%PeakSignalNoiseRatioWithBlockedEffecta  Computes `Peak Signal to Noise Ratio With Blocked Effect`_ (PSNRB).

    .. math::
        \text{PSNRB}(I, J) = 10 * \log_{10} \left(\frac{\max(I)^2}{\text{MSE}(I, J)-\text{B}(I, J)}\right)

    Where :math:`\text{MSE}` denotes the `mean-squared-error`_ function. This metric is a modified version of PSNR that
    better supports evaluation of images with blocked artifacts, that oftens occur in compressed images.

    .. attention::
        Metric only supports grayscale images. If you have RGB images, please convert them to grayscale first.

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

    - ``preds`` (:class:`~torch.Tensor`): Predictions from model of shape ``(N,1,H,W)``
    - ``target`` (:class:`~torch.Tensor`): Ground truth values of shape ``(N,1,H,W)``

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

    - ``psnrb`` (:class:`~torch.Tensor`): float scalar tensor with aggregated PSNRB value

    Args:
        data_range: the range of the data. If a tuple is provided then the range is calculated as the difference and
            input is clamped between the values.
        block_size: integer indication the block size
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Example:
        >>> from torch import rand
        >>> metric = PeakSignalNoiseRatioWithBlockedEffect(data_range=1.0)
        >>> preds = rand(2, 1, 10, 10)
        >>> target = rand(2, 1, 10, 10)
        >>> metric(preds, target)
        tensor(7.2893)

    TÚis_differentiableÚhigher_is_betterFÚfull_state_updateÚsum_squared_errorÚtotalÚbefÚ
data_rangeÚ
block_sizeÚkwargsÚreturnNc                 óþ  •‡— t        ‰| �  di |¤Ž t        |t        «      s|dk  rt	        d«      ‚|| _        | j                  dt        d«      d¬«       | j                  dt        d«      d¬«       | j                  d	t        d«      d¬«       t        ‰t        «      r1| j                  d
t        ‰d   ‰d   z
  «      d¬«       ˆfd„| _	        y | j                  d
t        t        ‰«      «      d¬«       d | _	        y )Né   z4Argument ``block_size`` should be a positive integerr   g        Úsum)ÚdefaultÚdist_reduce_fxr   r   r   r   Úmeanc                 ó@   •— t        j                  | ‰d   ‰d   ¬«      S )Nr   r   )ÚminÚmax)ÚtorchÚclamp)Úxr   s    €úm/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/image/psnrb.pyÚ<lambda>z@PeakSignalNoiseRatioWithBlockedEffect.__init__.<locals>.<lambda>\   s   ø€ ¬¯©°Q¸JÀq¹MÈzÐZ[É}Õ)]ó    © )ÚsuperÚ__init__Ú
isinstanceÚintÚ
ValueErrorr   Ú	add_stater   ÚtupleÚclamping_fnÚfloat)Úselfr   r   r   Ú	__class__s    `  €r'   r,   z.PeakSignalNoiseRatioWithBlockedEffect.__init__K   sÙ   ù€ ô 	‰ÑÑ"˜6Ò"Ü˜*¤cÔ*¨z¸Aª~ÜÐSÓTÐTØ$ˆŒà�‰Ð*´F¸3³KÐPUˆÔVØ�‰�w¬¨q«	À%ˆÔHØ�‰�u¤f¨S£kÀ%ˆÔHä�j¤%Ô(Ø�N‰N˜<´¸
À1¹È
ÐSTÉÑ8UÓ1VÐgmˆNÔnÛ]ˆDÕà�N‰N˜<´¼¸jÓ8IÓ1JÐ[aˆNÔbØ#ˆDÕr)   ÚpredsÚtargetc                 ó  — | j                   �"| j                  |«      }| j                  |«      }t        ||| j                  ¬«      \  }}}| xj                  |z  c_        | xj                  |z  c_        | xj
                  |z  c_        y)z*Update state with predictions and targets.N)r   )r2   r
   r   r   r   r   )r4   r6   r7   r   r   Únum_obss         r'   Úupdatez,PeakSignalNoiseRatioWithBlockedEffect.updatea   sx   € à×ÑÐ'Ø×$Ñ$ UÓ+ˆEØ×%Ñ% fÓ-ˆFä*7¸¸vÐRV×RaÑRaÔ*bÑ'Ð˜3 Ø×ÒÐ"3Ñ3ÕØ�Š�C‰�Ø�
Š
�gÑŽ
r)   c                 ón   — t        | j                  | j                  | j                  | j                  «      S )z.Compute peak signal-to-noise ratio over state.)r	   r   r   r   r   )r4   s    r'   Úcomputez-PeakSignalNoiseRatioWithBlockedEffect.computel   s%   € ä˜d×4Ñ4°d·h±hÀÇ
Á
ÈDÏOÉOÓ\Ð\r)   Ú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 import PeakSignalNoiseRatioWithBlockedEffect
            >>> metric = PeakSignalNoiseRatioWithBlockedEffect(data_range=1.0)
            >>> metric.update(torch.rand(2, 1, 10, 10), torch.rand(2, 1, 10, 10))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> import torch
            >>> from torchmetrics.image import PeakSignalNoiseRatioWithBlockedEffect
            >>> metric = PeakSignalNoiseRatioWithBlockedEffect(data_range=1.0)
            >>> values = [ ]
            >>> for _ in range(10):
            ...     values.append(metric(torch.rand(2, 1, 10, 10), torch.rand(2, 1, 10, 10)))
            >>> fig_, ax_ = metric.plot(values)

        )Ú_plot)r4   r=   r>   s      r'   Úplotz*PeakSignalNoiseRatioWithBlockedEffect.plotp   s   € ðP �z‰z˜#˜rÓ"Ð"r)   )é   )NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚboolÚ__annotations__r   r   r   r   r3   r1   r.   r   r,   r:   r<   r   r   r   r   rA   Ú__classcell__)r5   s   @r'   r   r      së   ø… ñ"ðH #Ð�tÓ"Ø!Ð�dÓ!Ø#Ð�tÓ#àÓØƒMØ	ƒKØÓð
 ñ$à˜%  u¨e |Ñ!4Ð4Ñ5ð$ð ð$ð ð	$ð
 
õ$ð,	˜Fð 	¨Fð 	°tó 	ð]˜ó ]ð
 _cñ(#Ø˜E &¨(°6Ñ*:Ð":Ñ;Ñ<ð(#ØIQÐRZÑI[ð(#à	÷(#r)   r   )Úcollections.abcr   Útypingr   r   r   r$   r   r   Ú#torchmetrics.functional.image.psnrbr	   r
   Útorchmetrics.metricr   Útorchmetrics.utilities.importsr   Útorchmetrics.utilities.plotr   r   Ú__doctest_skip__r   r*   r)   r'   Ú<module>rQ      s<   ðõ %ß 'Ñ 'ã ß  ç MÝ &Ý @ß @áØDÐEÐô{#¨Fõ {#r)   