o
    oi+                     @   s   d Z ddlmZmZmZ ddlZddlmZ ddlm	Z	 g dZ
G dd deZd	e	d
e	de	de	fddZG dd deZd	e	d
ee	ef dee	ef de	fddZdde	dededede	f
ddZdS )z:Module containing functionals for intensity normalisation.    )ListTupleUnionN)ImageModule)Tensor)Denormalize	Normalizedenormalize	normalizenormalize_min_maxc                       sv   e Zd ZdZdeeee ee ef deeee ee ef ddf fddZ	dedefd	d
Z
defddZ  ZS )r   ad  Normalize a tensor image with mean and standard deviation.

    .. math::
        \text{input[channel] = (input[channel] - mean[channel]) / std[channel]}

    Where `mean` is :math:`(M_1, ..., M_n)` and `std` :math:`(S_1, ..., S_n)` for `n` channels,

    Args:
        mean: Mean for each channel.
        std: Standard deviations for each channel.

    Shape:
        - Input: Image tensor of size :math:`(*, C, ...)`.
        - Output: Normalised tensor with same size as input :math:`(*, C, ...)`.

    Examples:
        >>> x = torch.rand(1, 4, 3, 3)
        >>> out = Normalize(0.0, 255.)(x)
        >>> out.shape
        torch.Size([1, 4, 3, 3])

        >>> x = torch.rand(1, 4, 3, 3)
        >>> mean = torch.zeros(4)
        >>> std = 255. * torch.ones(4)
        >>> out = Normalize(mean, std)(x)
        >>> out.shape
        torch.Size([1, 4, 3, 3])

    meanstdreturnNc                    s   t    t|ttfrt|g}t|ttfrt|g}t|ttfr-t|d  }t|ttfr;t|d  }|| _	|| _
d S N)super__init__
isinstanceintfloattorchtensortuplelistr   r   selfr   r   	__class__ L/home/ubuntu/.local/lib/python3.10/site-packages/kornia/enhance/normalize.pyr   =   s   

zNormalize.__init__inputc                 C      t || j| jS r   )r
   r   r   r   r   r   r   r   forwardS      zNormalize.forwardc                 C   "   d| j  d| j d}| jj| S Nz(mean=z, std=)r   r   r   __name__r   reprr   r   r   __repr__V      zNormalize.__repr__)r(   
__module____qualname____doc__r   r   r   r   r   r   r"   strr+   __classcell__r   r   r   r   r      s    r   datar   r   r   c                 C   s  | j }tj r2t|trt|tstd|j d dks$|j d dkr1td|j  d|j  dnt|trFtj|g|d  | j	| j
d}t|trZtj|g|d  | j	| j
d}|j r|j d dkr|j d | j d kr|j dd	 | j dd	 krtd
|j  d| j  d|j r|j d dkr|j d | j d kr|j dd	 | j dd	 krtd|j  d| j  dtj|| j	| j
d}tj|| j	| j
d}|d }|d }| |d |d d| | }||S )a{  Normalize an image/video tensor with mean and standard deviation.

    .. math::
        \text{input[channel] = (input[channel] - mean[channel]) / std[channel]}

    Where `mean` is :math:`(M_1, ..., M_n)` and `std` :math:`(S_1, ..., S_n)` for `n` channels,

    Args:
        data: Image tensor of size :math:`(B, C, *)`.
        mean: Mean for each channel.
        std: Standard deviations for each channel.

    Return:
        Normalised tensor with same size as input :math:`(B, C, *)`.

    Examples:
        >>> x = torch.rand(1, 4, 3, 3)
        >>> out = normalize(x, torch.tensor([0.0]), torch.tensor([255.]))
        >>> out.shape
        torch.Size([1, 4, 3, 3])

        >>> x = torch.rand(1, 4, 3, 3)
        >>> mean = torch.zeros(4)
        >>> std = 255. * torch.ones(4)
        >>> out = normalize(x, mean, std)
        >>> out.shape
        torch.Size([1, 4, 3, 3])

    0Only tensor is accepted when converting to ONNX.r      zqBatch dimension must be one for broadcasting when converting to ONNX.Try changing mean shape and std shape from (z, z) to (1, C) or (1, C, 1, 1).devicedtypeN   5mean length and number of channels do not match. Got  and .4std length and number of channels do not match. Got ).N)shaper   onnxis_in_onnx_exportr   r   
ValueErrorr   r   r6   r7   	as_tensorview)r2   r   r   r>   outr   r   r   r
   [   s:   


00
r
   c                       s^   e Zd ZdZdeeef deeef ddf fddZdedefd	d
Zde	fddZ
  ZS )r   ax  Denormalize a tensor image with mean and standard deviation.

    .. math::
        \text{input[channel] = (input[channel] * std[channel]) + mean[channel]}

    Where `mean` is :math:`(M_1, ..., M_n)` and `std` :math:`(S_1, ..., S_n)` for `n` channels,

    Args:
        mean: Mean for each channel.
        std: Standard deviations for each channel.

    Shape:
        - Input: Image tensor of size :math:`(*, C, ...)`.
        - Output: Denormalised tensor with same size as input :math:`(*, C, ...)`.

    Examples:
        >>> x = torch.rand(1, 4, 3, 3)
        >>> out = Denormalize(0.0, 255.)(x)
        >>> out.shape
        torch.Size([1, 4, 3, 3])

        >>> x = torch.rand(1, 4, 3, 3, 3)
        >>> mean = torch.zeros(1, 4)
        >>> std = 255. * torch.ones(1, 4)
        >>> out = Denormalize(mean, std)(x)
        >>> out.shape
        torch.Size([1, 4, 3, 3, 3])

    r   r   r   Nc                    s   t    || _|| _d S r   )r   r   r   r   r   r   r   r   r      s   

zDenormalize.__init__r   c                 C   r    r   )r	   r   r   r!   r   r   r   r"      r#   zDenormalize.forwardc                 C   r$   r%   r'   r)   r   r   r   r+      r,   zDenormalize.__repr__)r(   r-   r.   r/   r   r   r   r   r"   r0   r+   r1   r   r   r   r   r      s
    *r   c                 C   sV  | j }tj r)t|trt|tstd|j d dks$|j d dkr(tdnt|tr=tj|g|d  | j	| j
d}t|trQtj|g|d  | j	| j
d}|j r|j d dkr|j d | j d kr|j dd | j dd krtd	|j  d
| j  d|j r|j d dkr|j d | j d kr|j dd | j dd krtd|j  d
| j  dtj|| j	| j
d}tj|| j	| j
d}| dkr|jddgdg|  d  R  }nt|j |  k r|d}t|j |  k s| dkr|jddgdg|  d  R  }nt|j |  k r$|d}t|j |  k st|| |S )ao  Denormalize an image/video tensor with mean and standard deviation.

    .. math::
        \text{input[channel] = (input[channel] * std[channel]) + mean[channel]}

    Where `mean` is :math:`(M_1, ..., M_n)` and `std` :math:`(S_1, ..., S_n)` for `n` channels,

    Args:
        data: Image tensor of size :math:`(B, C, *)`.
        mean: Mean for each channel.
        std: Standard deviations for each channel.

    Return:
        Denormalised tensor with same size as input :math:`(B, C, *)`.

    Examples:
        >>> x = torch.rand(1, 4, 3, 3)
        >>> out = denormalize(x, 0.0, 255.)
        >>> out.shape
        torch.Size([1, 4, 3, 3])

        >>> x = torch.rand(1, 4, 3, 3, 3)
        >>> mean = torch.zeros(1, 4)
        >>> std = 255. * torch.ones(1, 4)
        >>> out = denormalize(x, mean, std)
        >>> out.shape
        torch.Size([1, 4, 3, 3, 3])

    r3   r   r4   zEBatch dimension must be one for broadcasting when converting to ONNX.r5   Nr8   r9   r:   r;   r<   r=   )r>   r   r?   r@   r   r   rA   r   r   r6   r7   rB   dimrC   len	unsqueezeaddcmul)r2   r   r   r>   r   r   r   r	      s<   


00$
$
r	                 ?ư>xmin_valmax_valepsc                 C   s   t | tstdt|  dt |tstdt| dt |ts-tdt| dt| jdk r=td| j d| j}|d |d }}| ||d	}|j	d	d
dd }|j
d	d
dd }	|| ||  |	| |  | }
|
|S )ay  Normalise an image/video tensor by MinMax and re-scales the value between a range.

    The data is normalised using the following formulation:

    .. math::
        y_i = (b - a) * \frac{x_i - \text{min}(x)}{\text{max}(x) - \text{min}(x)} + a

    where :math:`a` is :math:`\text{min_val}` and :math:`b` is :math:`\text{max_val}`.

    Args:
        x: The image tensor to be normalised with shape :math:`(B, C, *)`.
        min_val: The minimum value for the new range.
        max_val: The maximum value for the new range.
        eps: Float number to avoid zero division.

    Returns:
        The normalised image tensor with same shape as input :math:`(B, C, *)`.

    Example:
        >>> x = torch.rand(1, 5, 3, 3)
        >>> x_norm = normalize_min_max(x, min_val=-1., max_val=1.)
        >>> x_norm.min()
        tensor(-1.)
        >>> x_norm.max()
        tensor(1.0000)

    zdata should be a tensor. Got: r;   z"'min_val' should be a float. Got: z'b' should be a float. Got:    z/Input shape must be at least a 3d tensor. Got: r   r4   r=   T)keepdim)r   r   	TypeErrortyper   rG   r>   rA   rC   minmax)rM   rN   rO   rP   r>   BC
x_reshapedx_minx_maxx_outr   r   r   r     s   


 
r   )rJ   rK   rL   )r/   typingr   r   r   r   kornia.corer   Moduler   __all__r   r
   r   r   r	   r   r   r   r   r   <module>   s   =D*-$I