
    3j                       S SK Jr  S SKJr  S SKJrJrJr  S SKrS SK	J
s  Jr  S SKJ
r
  S SKJrJrJr  S SKJrJrJr  S SKJr  S S	KJrJr  S6S
 jrS6S jrS6S jrS6S jrS6S jr S7       S8S jjrS9S:S jjr S6S jr! S9       S:S jjr" S9       S:S jjr#S;S<S jjr$S=S>S jjr%S?S@S jjr&  SA       SBS jjr'\SCS j5       r(\SDS j5       r)SES jr*SFS jr+SGS jr,\SHS j5       r-\SHS j5       r.SISJS jjr/ " S  S!\
R`                  5      r1 " S" S#\
R`                  5      r2 " S$ S%\
R`                  5      r3 " S& S'\
R`                  5      r4 " S( S)\
R`                  5      r5 " S* S+\
R`                  5      r6 " S, S-\
R`                  5      r7 " S. S/\
R`                  5      r8 " S0 S1\
R`                  5      r9 " S2 S3\
R`                  5      r: " S4 S5\
R`                  5      r;g)K    )annotations)pi)ClassVarOptionalUnionN)nn)
hsv_to_rgbrgb_to_grayscale
rgb_to_hsv)KORNIA_CHECKKORNIA_CHECK_IS_COLOR_OR_GRAYKORNIA_CHECK_IS_TENSOR)_torch_histc_cast)perform_keep_shape_imageperform_keep_shape_videoc                   [        U S5        [        [        U[        [        R
                  45      S5        [        U[        5      (       a*  [        R                  " XR                  U R                  S9nOE[        U[        R
                  5      (       a&  UR                  U R                  U R                  5      n[        UR                  5      [        U R                  5      :w  a3  US   n[        UR                  5      [        U R                  5      :w  a  M3  [        R                  " U SSS9u  p#n[        R                  " X1-  SS	S
9n[        R                  " X%U/SS9nU$ )zSAdjust color saturation of an image.

Expecting image to be in hsv format already.
Expected shape (*, H, W)'Factor should be float or torch.Tensor.devicedtype.N   chunksdimr      minmaxr   )r   r   
isinstancefloattorchTensor	as_tensorr   r   tolenshapechunkclampcat)imagefactorhsvs_outouts          O/home/wildlama/miniconda3/lib/python3.13/site-packages/kornia/enhance/adjust.pyadjust_saturation_rawr6   %   s   
 5"<=FUELL$9:<ef&%  EKKP	FELL	)	)5<<5 fll
s5;;/
/	" fll
s5;;/
/ kk%r2GA!  ++ajaQ?E 		1Q-R8CJ    c                   [        U S5        [        [        U[        [        R
                  45      S5        [        U S5        U R                  S   S:X  a  U $ [        U[        5      (       a*  [        R                  " XR                  U R                  S9nOE[        U[        R
                  5      (       a&  UR                  U R                  U R                  5      n[        UR                  5      [        U R                  5      :w  a3  US   n[        UR                  5      [        U R                  5      :w  a  M3  [        U 5      nSU-
  U-  X-  -   n[        R                  " USS	5      nU$ )
a  Adjust color saturation of an image by blending the image with its grayscaled version.

The image is expected to be an RGB image or a gray image in the range of [0, 1].
If it is an RGB image, returns blending of the image with its grayscaled version.
If it is a gray image, returns the image.

.. note::
    this is just a convenience function to have compatibility with Pil

Args:
    image: Image/torch.Tensor to be adjusted in the shape of :math:`(*, 3, H, W)`.
    factor: How much to adjust the saturation. 0 will give a black
      and white image, 1 will give the original image while 2 will enhance the saturation by a factor of 2.

Return:
    Adjusted image in the shape of :math:`(*, 3, H, W)`.

Example:
    >>> x = torch.ones(1, 3, 3, 3)
    >>> adjust_saturation_with_gray_subtraction(x, 2.).shape
    torch.Size([1, 3, 3, 3])

    >>> x = torch.ones(2, 3, 3, 3)
    >>> y = torch.tensor([1., 2.])
    >>> adjust_saturation_with_gray_subtraction(x, y).shape
    torch.Size([2, 3, 3, 3])

r   r   z$Image should be an RGB or gray imager   r   r   r                 ?)r   r   r#   r$   r%   r&   r   r*   r'   r   r   r(   r)   r
   r,   )r.   r/   x_other
x_adjustedr4   s        r5   'adjust_saturation_with_gray_subtractionr=   C   s   : 5"<=FUELL$9:<ef!%)OP{{2!&%  EKKP	FELL	)	)5<<5 fll
s5;;/
/	" fll
s5;;/
/ -U3G !"F
g5FJ JS9CJr7   c                H    [        U 5      n[        X!5      n[        U5      nU$ )a~  Adjust color saturation of an image.

.. image:: _static/img/adjust_saturation.png

The image is expected to be an RGB image in the range of [0, 1].

Args:
    image: Image/torch.Tensor to be adjusted in the shape of :math:`(*, 3, H, W)`.
    factor: How much to adjust the saturation. 0 will give a black
      and white image, 1 will give the original image while 2 will enhance the saturation by a factor of 2.
    saturation_mode: The mode to adjust saturation.

Return:
    Adjusted image in the shape of :math:`(*, 3, H, W)`.

.. note::
   See a working example `here <https://kornia.github.io/tutorials/nbs/image_enhancement.html>`__.

Example:
    >>> x = torch.ones(1, 3, 3, 3)
    >>> adjust_saturation(x, 2.).shape
    torch.Size([1, 3, 3, 3])

    >>> x = torch.ones(2, 3, 3, 3)
    >>> y = torch.tensor([1., 2.])
    >>> adjust_saturation(x, y).shape
    torch.Size([2, 3, 3, 3])

)r   r6   r	   r.   r/   x_hsvr<   r4   s        r5   adjust_saturationrA   |   s+    > %U+E  5UCJ #:.CJr7   c                   [        U S5        [        [        U[        [        R
                  45      S[        U5       35        [        U[        5      (       a  [        R                  " U5      nUR                  U R                  U R                  5      n[        UR                  5      [        U R                  5      :w  a3  US   n[        UR                  5      [        U R                  5      :w  a  M3  [        R                  " U SSS9u  p#nS[        -  n[        R                  " X!-   U5      n[        R                   " XcU/SS9nU$ )	zFAdjust hue of an image.

Expecting image to be in hsv format already.
r   zXThe factor should be a float number or torch.Tensor in the range between [-PI, PI]. Got r   r   r   r      r"   )r   r   r#   r$   r%   r&   typer'   r(   r   r   r)   r*   r+   r   fmodr-   )r.   r/   r0   r1   r2   divisorh_outr4   s           r5   adjust_hue_rawrH      s   
 5"<=6E5<<01
bcghncobpq
 &%  (YYu||U[[1F fll
s5;;/
/	" fll
s5;;/
/ kk%r2GA! VG**QZ9E 		5Q-R8CJr7   c                H    [        U 5      n[        X!5      n[        U5      nU$ )a  Adjust hue of an image.

.. image:: _static/img/adjust_hue.png

The image is expected to be an RGB image in the range of [0, 1].

Args:
    image: Image to be adjusted in the shape of :math:`(*, 3, H, W)`.
    factor: How much to shift the hue channel. Should be in [-PI, PI]. PI
      and -PI give complete reversal of hue channel in HSV space in positive and negative
      direction respectively. 0 means no shift. Therefore, both -PI and PI will give an
      image with complementary colors while 0 gives the original image.

Return:
    Adjusted image in the shape of :math:`(*, 3, H, W)`.

.. note::
   See a working example `here <https://kornia.github.io/tutorials/nbs/image_enhancement.html>`__.

Example:
    >>> x = torch.ones(1, 3, 2, 2)
    >>> adjust_hue(x, 3.141516).shape
    torch.Size([1, 3, 2, 2])

    >>> x = torch.ones(2, 3, 3, 3)
    >>> y = torch.ones(2) * 3.141516
    >>> adjust_hue(x, y).shape
    torch.Size([2, 3, 3, 3])

)r   rH   r	   r?   s        r5   
adjust_huerJ      s,    @ %U+E  .e<J #:.CJr7   c                   [        U [        R                  5      (       d  [        S[	        U 5       35      e[        U[
        [        R                  45      (       d  [        S[	        U5       35      e[        U[
        [        R                  45      (       d  [        S[	        U5       35      e[        U[
        5      (       a  [        R                  " U/5      n[        U[
        5      (       a  [        R                  " U/5      nUR                  U R                  5      R                  U R                  5      nUR                  U R                  5      R                  U R                  5      nUS:  R                  5       (       a  [        SU 35      eUS:  R                  5       (       a  [        SU 35      e[        [        U R                  5      [        UR                  5      -
  5       H  n[        R                  " USS9nM     [        [        U R                  5      [        UR                  5      -
  5       H  n[        R                  " USS9nM     U[        R                  " X5      -  n[        R                   " USS	5      nU$ )
a  Perform gamma correction on an image.

.. image:: _static/img/adjust_contrast.png

The input image is expected to be in the range of [0, 1].

Args:
    input: Image to be adjusted in the shape of :math:`(*, H, W)`.
    gamma: Non negative real number, same as y\gammay in the equation.
        gamma larger than 1 make the shadows darker, while gamma smaller than 1 make
        dark regions lighter.
    gain: The constant multiplier.

Return:
    Adjusted image in the shape of :math:`(*, H, W)`.

.. note::
   See a working example `here <https://kornia.github.io/tutorials/nbs/image_enhancement.html>`__.

Example:
    >>> x = torch.ones(1, 1, 2, 2)
    >>> adjust_gamma(x, 1.0, 2.0)
    tensor([[[[1., 1.],
              [1., 1.]]]])

    >>> x = torch.ones(2, 5, 3, 3)
    >>> y1 = torch.ones(2) * 1.0
    >>> y2 = torch.ones(2) * 2.0
    >>> adjust_gamma(x, y1, y2).shape
    torch.Size([2, 5, 3, 3])

&Input type is not a torch.Tensor. Got z:The gamma should be a positive float or torch.Tensor. Got z9The gain should be a positive float or torch.Tensor. Got r9   z Gamma must be non-negative. Got zGain must be non-negative. Got r"   r:   )r#   r%   r&   	TypeErrorrD   r$   r(   r   r   any
ValueErrorranger)   r*   	unsqueezepowr,   )inputgammagain_x_adjustr4   s         r5   adjust_gammarY      s   F eU\\**@eNOOeeU\\233TUYZ_U`TabccdUELL122STXY]T^S_`aa%eW%$||TF#HHU\\"%%ekk2E775<< ##EKK0D;E7CDDs
:4&ABB3u{{#c%++&6672. 8 3u{{#c$**o56t, 7 "EIIe$;;H Hc37CJr7   c                   [        U S5        [        [        U[        [        R
                  45      S5        [        U[        5      (       a*  [        R                  " XR                  U R                  S9nOE[        U[        R
                  5      (       a&  UR                  U R                  U R                  5      n[        UR                  5      [        U R                  5      :w  a3  US   n[        UR                  5      [        U R                  5      :w  a  M3  [        [        US:  5      S5        X-  nU(       a  UR                  SSS	9nU$ )
a@  Adjust the contrast of an image torch.Tensor.

.. image:: _static/img/adjust_contrast.png

This implementation follows Szeliski's book convention, where contrast is defined as
a `multiplicative` operation directly to raw pixel values. Beware that other frameworks
might use different conventions which can be difficult to reproduce exact results.

The input image and factor is expected to be in the range of [0, 1].

.. tip::
    This is not the preferred way to adjust the contrast of an image. Ideally one must
    implement :func:`kornia.enhance.adjust_gamma`. More details in the following link:
    https://scikit-image.org/docs/dev/auto_examples/color_exposure/plot_log_gamma.html#sphx-glr-auto-examples-color-exposure-plot-log-gamma-py

Args:
    image: Image to be adjusted in the shape of :math:`(*, H, W)`.
    factor: Contrast adjust factor per element
        in the batch. 0 generates a completely black image, 1 does not modify
        the input image while any other non-negative number modify the
        brightness by this factor.
    clip_output: whether to clip the output image with range of [0, 1].

Return:
    Adjusted image in the shape of :math:`(*, H, W)`.

.. note::
   See a working example `here <https://kornia.github.io/tutorials/nbs/image_enhancement.html>`__.

Example:
    >>> import torch
    >>> x = torch.ones(1, 1, 2, 2)
    >>> adjust_contrast(x, 0.5)
    tensor([[[[0.5000, 0.5000],
              [0.5000, 0.5000]]]])

    >>> x = torch.ones(2, 5, 3, 3)
    >>> y = torch.tensor([0.65, 0.50])
    >>> adjust_contrast(x, y).shape
    torch.Size([2, 5, 3, 3])

r   r   r   r   r   z!Contrast factor must be positive.r9   r:   r   )r   r   r#   r$   r%   r&   r'   r   r   r(   r)   r*   rO   r,   r.   r/   clip_output
img_adjusts       r5   adjust_contrastr^   <  s    V 5"<=FUELL$9:<ef&%  EKKP	FELL	)	)5<<5 fll
s5;;/
/	" fll
s5;;/
/ Vq[!#FG  %~J %%#3%7
r7   c                   [        U S5        [        [        U[        [        R
                  45      S5        [        U[        5      (       a*  [        R                  " XR                  U R                  S9nOE[        U[        R
                  5      (       a&  UR                  U R                  U R                  5      n[        UR                  5      [        U R                  5      :w  a3  US   n[        UR                  5      [        U R                  5      :w  a  M3  U R                  S   S:X  a  [        U 5      R                  SS5      nOU R                  5       nX-  US	U-
  -  -   nUR                  S
SS9nU$ )a  Adjust the contrast of an image torch.Tensor by subtracting the mean over channels.

.. note::
    this is just a convenience function to have compatibility with Pil. For exact
    definition of image contrast adjustment consider using :func:`kornia.enhance.adjust_gamma`.

Args:
    image: Image to be adjusted in the shape of :math:`(*, H, W)`.
    factor: Contrast adjust factor per element
        in the batch. 0 generates a completely black image, 1 does not modify
        the input image while any other non-negative number modify the
        brightness by this factor.

Return:
    Adjusted image in the shape of :math:`(*, H, W)`.

Example:
    >>> import torch
    >>> x = torch.ones(1, 1, 2, 2)
    >>> adjust_contrast_with_mean_subtraction(x, 0.5)
    tensor([[[[1., 1.],
              [1., 1.]]]])

    >>> x = torch.ones(2, 5, 3, 3)
    >>> y = torch.tensor([0.65, 0.50])
    >>> adjust_contrast_with_mean_subtraction(x, y).shape
    torch.Size([2, 5, 3, 3])

r   r   r   r   r   r   )rM   Tr   r9   r:   r   )r   r   r#   r$   r%   r&   r'   r   r   r(   r)   r*   r
   meanr,   )r.   r/   img_meanr]   s       r5   %adjust_contrast_with_mean_subtractionrc     s    < 5"<=FUELL$9:<ef&%  EKKP	FELL	)	)5<<5 fll
s5;;/
/	" fll
s5;;/
/
 {{2!#E*//$?::<  %~AJ0GGJ!!cs!3Jr7   c                n   [        U S5        [        [        U[        [        R
                  45      S5        [        U[        5      (       a*  [        R                  " XR                  U R                  S9nOE[        U[        R
                  5      (       a&  UR                  U R                  U R                  5      n[        UR                  5      [        U R                  5      :w  a3  US   n[        UR                  5      [        U R                  5      :w  a  M3  X-   nU(       a  UR                  SSS9nU$ )a  Adjust the brightness of an image torch.Tensor.

.. image:: _static/img/adjust_brightness.png

This implementation follows Szeliski's book convention, where brightness is defined as
an `additive` operation directly to raw pixel and shift its values according the applied
factor and range of the image values. Beware that other framework might use different
conventions which can be difficult to reproduce exact results.

The input image and factor is expected to be in the range of [0, 1].

.. tip::
    By applying a large factor might prouce clipping or loss of image detail. We recommenda to
    apply small factors to avoid the mentioned issues. Ideally one must implement the adjustment
    of image intensity with other techniques suchs as :func:`kornia.enhance.adjust_gamma`. More
    details in the following link:
    https://scikit-image.org/docs/dev/auto_examples/color_exposure/plot_log_gamma.html#sphx-glr-auto-examples-color-exposure-plot-log-gamma-py

Args:
    image: Image to be adjusted in the shape of :math:`(*, H, W)`.
    factor: Brightness adjust factor per element in the batch. It's recommended to
        bound the factor by [0, 1]. 0 does not modify the input image while any other
        number modify the brightness.
    clip_output: Whether to clip output to be in [0,1].

Return:
    Adjusted torch.Tensor in the shape of :math:`(*, H, W)`.

.. note::
   See a working example `here <https://kornia.github.io/tutorials/nbs/image_enhancement.html>`__.

Example:
    >>> x = torch.ones(1, 1, 2, 2)
    >>> adjust_brightness(x, 1.)
    tensor([[[[1., 1.],
              [1., 1.]]]])

    >>> x = torch.ones(2, 5, 3, 3)
    >>> y = torch.tensor([0.25, 0.50])
    >>> adjust_brightness(x, y).shape
    torch.Size([2, 5, 3, 3])

r   r   r   r   r9   r:   r   r   r   r#   r$   r%   r&   r'   r   r   r(   r)   r*   r,   r[   s       r5   adjust_brightnessrf     s    \ 5"<=FUELL$9:<ef &%  EKKP	FELL	)	)5<<5 fll
s5;;/
/	" fll
s5;;/
/  %~J %%#3%7
r7   c                n   [        U S5        [        [        U[        [        R
                  45      S5        [        U[        5      (       a*  [        R                  " XR                  U R                  S9nOE[        U[        R
                  5      (       a&  UR                  U R                  U R                  5      n[        UR                  5      [        U R                  5      :w  a3  US   n[        UR                  5      [        U R                  5      :w  a  M3  X-  nU(       a  UR                  SSS9nU$ )as  Adjust the brightness accumulatively of an image torch.Tensor.

This implementation follows PIL convention.

The input image and factor is expected to be in the range of [0, 1].

Args:
    image: Image to be adjusted in the shape of :math:`(*, H, W)`.
    factor: Brightness adjust factor per element in the batch. It's recommended to
        bound the factor by [0, 1]. 0 does not modify the input image while any other
        number modify the brightness.
    clip_output: Whether to clip output to be in [0,1].

Return:
    Adjusted torch.Tensor in the shape of :math:`(*, H, W)`.

Example:
    >>> x = torch.ones(1, 1, 2, 2)
    >>> adjust_brightness_accumulative(x, 1.)
    tensor([[[[1., 1.],
              [1., 1.]]]])

    >>> x = torch.ones(2, 5, 3, 3)
    >>> y = torch.tensor([0.25, 0.50])
    >>> adjust_brightness_accumulative(x, y).shape
    torch.Size([2, 5, 3, 3])

r   r   r   r   r9   r:   r   re   r[   s       r5   adjust_brightness_accumulativerh      s    > 5"<=FUELL$9:<ef &%  EKKP	FELL	)	)5<<5 fll
s5;;/
/	" fll
s5;;/
/  %~J %%#3%7
r7   c                    [        U S5        U(       a   SSSX!U -
  -  R                  5       -   -  -
  nU$ SSX!U -
  -  R                  5       -   -  nU$ )a  Adjust sigmoid correction on the input image torch.Tensor.

The input image is expected to be in the range of [0, 1].

Reference:
    [1]: Gustav J. Braun, "Image Lightness Rescaling Using Sigmoidal Contrast Enhancement Functions",
         http://markfairchild.org/PDFs/PAP07.pdf

Args:
    image: Image to be adjusted in the shape of :math:`(*, H, W)`.
    cutoff: The cutoff of sigmoid function.
    gain: The multiplier of sigmoid function.
    inv: If is set to True the function will return the inverse sigmoid correction.

Returns:
     Adjusted torch.Tensor in the shape of :math:`(*, H, W)`.

Example:
    >>> x = torch.ones(1, 1, 2, 2)
    >>> adjust_sigmoid(x, gain=0)
    tensor([[[[0.5000, 0.5000],
              [0.5000, 0.5000]]]])

r   r   )r   exp)r.   cutoffrV   invr]   s        r5   adjust_sigmoidrm   7  se    2 5"<=
a4E>#:"?"?"AABB
  !t~6;;==>
r7   c                    [        U S5        U(       a  SU -  S-
  U-  nOSU -   R                  5       U-  nU(       a  UR                  SSS9nU$ )a  Adjust log correction on the input image torch.Tensor.

The input image is expected to be in the range of [0, 1].

Reference:
[1]: http://www.ece.ucsb.edu/Faculty/Manjunath/courses/ece178W03/EnhancePart1.pdf

Args:
    image: Image to be adjusted in the shape of :math:`(*, H, W)`.
    gain: The multiplier of logarithmic function.
    inv:  If is set to True the function will return the inverse logarithmic correction.
    clip_output: Whether to clip the output image with range of [0, 1].

Returns:
    Adjusted torch.Tensor in the shape of :math:`(*, H, W)`.

Example:
    >>> x = torch.zeros(1, 1, 2, 2)
    >>> adjust_log(x, inv=True)
    tensor([[[[0., 0.],
              [0., 0.]]]])

r   rC   r   r9   r:   r   )r   log2r,   )r.   rV   rl   r\   r]   s        r5   
adjust_logrp   Y  s[    0 5"<=
hld*
%i%%'$.
 %%#3%7
r7   c           
     0   [        U [        R                  5      (       d  [        S[	        U 5       35      e[        U[
        [        R                  45      (       d  [        S[	        U5       35      e[        U[        R                  5      (       a  [        UR                  5      S:w  a  U R                  S5      [        U5      :X  a  [        UR                  5      S:X  d   [        SU R                  S5       SU 35      eUR                  U R                  5      R                  U R                  5      n[        R                  " U Vs/ s H  o"R                  " U R                  SS 6 PM      sn5      n[        R                  " X:  U S	U -
  5      $ s  snf )
a  For each pixel in the image, select the pixel if the value is less than the threshold.

Otherwise, subtract 1.0 from the pixel.

Args:
    input: image or batched images to solarize.
    thresholds: solarize thresholds.
        If int or one element torch.Tensor, input will be solarized across the whole batch.
        If 1-d torch.Tensor, input will be solarized element-wise, len(thresholds) == len(input).

Returns:
    Solarized images.

rL   9The factor should be either a float or torch.Tensor. Got r   r   z*thresholds must be a 1-d vector of shape (,). Got r   Nr:   )r#   r%   r&   rN   rD   r$   r)   r*   sizeAssertionErrorr(   r   r   stackexpandwhere)rT   
thresholdsxs      r5   	_solarizer{     s;    eU\\**@eNOOj5%,,"788STXYcTdSefgg*ell++J4D4D0E0J

1Z0S9I9I5Ja5O #MejjYZm_\deodp!qrr]]5<<033EKK@
[[z!Rz!((EKK,<"=z!RS
;;u)5#+>> "Ss   
%Fc           
        [        U [        R                  5      (       d  [        S[	        U 5       35      e[        U[
        [        R                  45      (       d  [        S[	        U5       35      e[        U[
        5      (       a  [        R                  " U5      nUGb  [        U[
        [        R                  45      (       d  [        S[	        U5       35      e[        U[
        5      (       a  [        R                  " U5      n[        R                  " US:  US:  -  5      (       d  [        SU S35      e[        U[        R                  5      (       a  [        UR                  5      S:w  a  U R                  S5      [        U5      :X  a  [        UR                  5      S	:X  d   [        S
U R                  S5       SU 35      eUR                  U R                  5      R                  U R                  5      n[        R                  " U Vs/ s H  o3R                   " U R                  SS 6 PM      sn5      nX-   n U R#                  SS5      n [%        X5      $ s  snf )a  For each pixel in the image less than threshold.

.. image:: _static/img/solarize.png

We add 'addition' amount to it and then clip the pixel value to be between 0 and 1.0.
The value of 'addition' is between -0.5 and 0.5.

Args:
    input: image torch.Tensor with shapes like :math:`(*, C, H, W)` to solarize.
    thresholds: solarize thresholds.
        If int or one element torch.Tensor, input will be solarized across the whole batch.
        If 1-d torch.Tensor, input will be solarized element-wise, len(thresholds) == len(input).
    additions: between -0.5 and 0.5.
        If None, no addition will be performed.
        If int or one element torch.Tensor, same addition will be added across the whole batch.
        If 1-d torch.Tensor, additions will be added element-wisely, len(additions) == len(input).

Returns:
    The solarized images with shape :math:`(*, C, H, W)`.

Example:
    >>> x = torch.rand(1, 4, 3, 3)
    >>> out = solarize(x, thresholds=0.5, additions=0.)
    >>> out.shape
    torch.Size([1, 4, 3, 3])

    >>> x = torch.rand(2, 4, 3, 3)
    >>> thresholds = torch.tensor([0.8, 0.5])
    >>> additions = torch.tensor([-0.25, 0.25])
    >>> solarize(x, thresholds, additions).shape
    torch.Size([2, 4, 3, 3])

rL   rr   N      ?g      z5The value of 'addition' is between -0.5 and 0.5. Got .r   r   z)additions must be a 1-d vector of shape (rs   r   r9   r:   )r#   r%   r&   rN   rD   r$   r'   allru   r)   r*   rt   r(   r   r   rv   rw   r,   r{   )rT   ry   	additionsrz   s       r5   solarizer     s   L eU\\**@eNOOj5%,,"788STXYcTdSefgg*e$$__Z0
)eU\\%:;;WX\]fXgWhijji''	2Iyy)c/i$.>?@@ #XYbXccd!effi..3y3G13LJJqMS^3IOO8LPQ8Q$'PQVQ[Q[\]Q^P__ghqgr%stt!U\\255ekkBI)$T)QXXu{{23/?%@)$TUI!C%U''	 %Us   %I c           
       ^^ [        U [        R                  5      (       d  [        S[	        U 5       35      e[        U[
        [        R                  45      (       d  [        S[	        U5       35      e[        U[
        5      (       a  [        R                  " U5      nSS jmSS jmSUU4S jjn[        UR                  5      S:X  d(  [        UR                  5      S:X  a  [        U5      S:X  a  U" X5      $ / n[        UR                  5      S:X  a  UR                  S   U R                  S   :w  a,  [        SUR                  S    S	U R                  S    S
35      e[        U R                  S   5       H  nUR                  U" X   X   5      5        M!     [        R                  " USS9$ UR                  U R                  S[        UR                  5       :w  a<  [        SUR                   S	U R                  S[        UR                  5        S
35      eU R                  " S/U R                  [        UR                  5      S Q76 nUR                  5       n[        U R                  S   5       H  nUR                  U" XT   Xd   5      5        M!     [        R                  " USS9R                  " U R                  6 $ )a  Reduce the number of bits for each color channel.

.. image:: _static/img/posterize.png

Non-differentiable function, ``torch.uint8`` involved.

Args:
    input: image torch.Tensor with shape :math:`(*, C, H, W)` to posterize.
    bits: number of high bits. Must be in range [0, 8].
        If int or one element torch.Tensor, input will be posterized by this bits.
        If 1-d torch.Tensor, input will be posterized element-wisely, len(bits) == input.shape[-3].
        If n-d torch.Tensor, input will be posterized element-channel-wisely,
        bits.shape == input.shape[:len(bits.shape)]

Returns:
    Image with reduced color channels with shape :math:`(*, C, H, W)`.

Example:
    >>> x = torch.rand(1, 6, 3, 3)
    >>> out = posterize(x, bits=8)
    >>> torch.testing.assert_close(x, out)

    >>> x = torch.rand(2, 6, 3, 3)
    >>> bits = torch.tensor([4, 2])
    >>> posterize(x, bits).shape
    torch.Size([2, 6, 3, 3])

rL   z-bits type is not an int or torch.Tensor. Got c                    U S-  R                  [        R                  5      SU-  -  R                  U R                  5      S-  $ N   rC        o@r(   r%   uint8r   rT   shifts     r5   _left_shiftposterize.<locals>._left_shift  s8      -E:>>u{{KeSSr7   c                    U S-  R                  [        R                  5      SU-  R                  U R                  5      -  S-  $ r   r   r   s     r5   _right_shiftposterize.<locals>._right_shift  s6    ,5}}U[[/IIEQQr7   c                   > US:X  a  [         R                  " U 5      $ US:X  a  U R                  5       $ SU-
  nT" T" X5      U5      $ )Nr      )r%   
zeros_likeclone)rT   bitsr   r   s     r5   _posterize_one!posterize.<locals>._posterize_one  sI    19##E**19;;= 4x<4d;;r7   r   r   z5Batch size must be equal between bits and input. Got z, r~   r"   Nz<Batch and channel must be equal between bits and input. Got rM   )rT   torch.Tensorr   r   returnr   )rT   r   r   r   r   r   )r#   r%   r&   rN   rD   intr'   r)   r*   ru   rQ   appendrv   viewflattenreshape)	rT   r   r   resi_input_bitsr   r   s	          @@r5   	posterizer     sG   < eU\\**@eNOOdS%,,/00GT
|TUU$t$TR< < 4::!DJJ1 4Tae**
C
4::!::a=EKKN* G

STVXY^YdYdefYgXhhij  u{{1~&AJJ~eh89 '{{3A&&zzU[[!23tzz?33::,b->s4::!? @C
 	
 ZZ<U[[TZZ):;<FLLNE5;;q>"

>&)UX67 #;;s"**EKK88r7   c                   [        U[        R                  5      (       d)  [        R                  " XR                  U R
                  S9n[        UR                  5       5      S:w  a^  UR                  [        R                  " U R                  S5      /5      :w  a*  [        SU R                  S5       SUR                   35      e[        R                  " / SQ/ SQ/ SQ/U R
                  U R                  S9R                  SSS	S	5      R                  U R                  S5      SSS5      S
-  n[        R                  R                  R                  XSSU R                  S5      S9n[        R                   " USS5      n[        R"                  " U5      n[$        R&                  " U/ SQ5      n[$        R&                  " U/ SQ5      n[        R(                  " US:H  X`5      n[        UR                  5       5      S:X  a  [+        XpU5      $ [        R,                  " [/        [        U5      5       Vs/ s H  n[+        Xx   X   X   5      PM     sn5      $ s  snf )a  Apply sharpness to the input torch.Tensor.

.. image:: _static/img/sharpness.png

Implemented Sharpness function from PIL using torch ops. This implementation refers to:
https://github.com/tensorflow/tpu/blob/master/models/official/efficientnet/autoaugment.py#L326

Args:
    input: image torch.Tensor with shape :math:`(*, C, H, W)` to sharpen.
    factor: factor of sharpness strength. Must be above 0.
        If float or one element torch.Tensor, input will be sharpened by the same factor across the whole batch.
        If 1-d torch.Tensor, input will be sharpened element-wisely, len(factor) == len(input).

Returns:
    Sharpened image or images with shape :math:`(*, C, H, W)`.

Example:
    >>> x = torch.rand(1, 1, 5, 5)
    >>> sharpness(x, 0.5).shape
    torch.Size([1, 1, 5, 5])

r   r   zYInput batch size shall match with factor size if factor is not a 0-dim torch.Tensor. Got z and )r   r   r   )r      r   )r   r   r   r      N)biasstridegroupsr9   r:   )r   r   r   r   )r#   r%   r&   r'   r   r   r)   rt   r*   Sizeru   r   repeatr   
functionalconv2dr,   	ones_likeFpadrx   
_blend_onerv   rQ   )	rT   r/   kernel
degeneratemaskpadded_maskpadded_degenerateresultr   s	            r5   	sharpnessr   =  s   0 fell++EKKP
6;;=Q6<<5::uzz!}o3N#N::a=/v||n6
 	
 	Iy9UZUaUab	aAq		

1q!Q	'
	  $$++EQW\WaWabcWd+eJZc2J ??:&D%%l+Kj,7[[)+<DF
6;;=Q&00;;ERUV\R]L^_L^q
69eh	BL^_``_s   /Ic                   [        U [        R                  5      (       d  [        SU  S35      e[        U[        R                  5      (       d  [        SU S35      e[        U[        R                  5      (       a,  [	        UR                  5       5      S:w  a  [        SU S35      eUS:X  a  U $ US:X  a  U$ X-
  U-  nX-   nUS:  a  US:  a  U$ [        R                  " USS5      $ )a<  Blend two images into one.

Args:
    input1: image torch.Tensor with shapes like :math:`(H, W)` or :math:`(D, H, W)`.
    input2: image torch.Tensor with shapes like :math:`(H, W)` or :math:`(D, H, W)`.
    factor: factor 0-dim torch.Tensor.

Returns:
    : image torch.Tensor with the batch in the zero position.

z%`input1` must be a torch.Tensor. Got r~   r   z<Factor shall be a float or single element torch.Tensor. Got r9   r:   r   )r#   r%   r&   ru   r)   rt   r,   )input1input2r/   diffr   s        r5   r   r   u  s     fell++DVHANOOfell++DVHANOO&%,,''C,>!,C[\b[ccdeff}}Ov%D
-C|
;;sAq!!r7   c                @   [         R                  " USSS9n[         R                  " [         R                  " U S5      U-   USS9n[         R                  " [         R                  " SUR
                  UR                  S9US S /5      n[         R                  " USS5      $ )	NrC   truncrounding_moder   r   r   rM   r   )r%   divcumsumr-   zerosr   r   r,   )histostep
step_truncluts       r5   
_build_lutr     s{     4':J
))ELL*Z7W
UC
))U[[3::SYYGSbR
SC ;;sAs##r7   c                   U R                  5       nU R                  5       nUR                  5       S:  aV  [        R                  " U[        R
                  " SUR                  S95      (       d  [        SUR                  5        S35      eUR                  5       S:  aV  [        R                  " U[        R
                  " SUR                  S95      (       d  [        SUR                  5        S35      e[        U R                  5      nUS;  a  [        SU S35      eU S	-  n [        U S
SSS9n[        R                  " XDS:g     S/5      n[        R                  " [        R                  " U5      US   -
  SSS9nUS:X  a  U nUS	-  $ [        R                  " [!        XF5      SU R#                  5       R%                  5       5      nUR'                  U 5      nUS	-  $ )zScale the data in the channel to implement equalize.

Args:
    im: image torch.Tensor with shapes like :math:`(H, W)` or :math:`(D, H, W)`.

Returns:
    image torch.Tensor with the batch in the zero position.

r9   )r   zEValues in the input torch.Tensor must greater or equal to 0.0. Found r~   r:   zCValues in the input torch.Tensor must lower or equal to 1.0. Found )rC   r   z6Input torch.Tensor must have 2 or 3 dimensions. Found r      r   r   )binsr    r!   rM   r   r   )r    r!   itemr%   iscloser'   r   rP   r)   r*   rN   r   r   r   sumgatherr   r   long
reshape_as)immin_max_ndimsr   nonzero_histor   r   s           r5   _scale_channelr     s    668D668Dyy{StU__SPTPZPZ5[!\!\`aeajajal`mmnoppyy{StU__SPTPZPZ5[!\!\^_c_h_h_j^kklmnnMEFPQVPWWXYZZ	eBbss;EMM%
"3bT:M99UYY}-b0AA3V]^D qy E> j5q"**,:K:K:MN""2&E>r7   c                   / nU  H_  n[         R                  " [        [        U5      5       Vs/ s H  n[	        X#SS2SS24   5      PM     sn5      nUR                  U5        Ma     [         R                  " U5      $ s  snf )a#  Apply equalize on the input torch.Tensor.

.. image:: _static/img/equalize.png

Implements Equalize function from PIL using PyTorch ops based on uint8 format:
https://github.com/tensorflow/tpu/blob/5f71c12a020403f863434e96982a840578fdd127/models/official/efficientnet/autoaugment.py#L355

Args:
    input: image torch.Tensor to equalize with shape :math:`(*, C, H, W)`.

Returns:
    Equalized image torch.Tensor with shape :math:`(*, C, H, W)`.

Example:
    >>> x = torch.rand(1, 2, 3, 3)
    >>> equalize(x).shape
    torch.Size([1, 2, 3, 3])

Nr%   rv   rQ   r)   r   r   )rT   r   r.   r   scaled_images        r5   equalizer     sp    * C {{ERUV[R\L]#^L]qN5Aq>$BL]#^_

< 	 
 ;;s $_s   A>
c                   / nU  Hb  n[         R                  " [        [        U5      5       Vs/ s H  n[	        X#SS2SS2SS24   5      PM     sn5      nUR                  U5        Md     [         R                  " U5      $ s  snf )a  Equalize the values for a 3D volumetric torch.Tensor.

Implements Equalize function for a sequence of images using PyTorch ops based on uint8 format:
https://github.com/tensorflow/tpu/blob/master/models/official/efficientnet/autoaugment.py#L352

Args:
    input: image torch.Tensor with shape :math:`(*, C, D, H, W)` to equalize.

Returns:
    Equalized volume with shape :math:`(B, C, D, H, W)`.

Nr   )rT   r   volumer   scaled_inputs        r5   
equalize3dr     st     C {{PUVYZ`VaPb#cPb1N6Q1*3E$FPb#cd

< 	  ;;s $ds   !B
c                D   [        U [        R                  5      (       d  [        S[	        [
        5       35      eUc  [        R                  " S/5      nOUn[        U[        R                  5      (       d  [        S[	        U5       35      eUR                  U 5      U -
  $ )a  Invert the values of an input image torch.Tensor by its maximum value.

.. image:: _static/img/invert.png

Args:
    image: The input torch.Tensor to invert with an arbitatry shape.
    max_val: The expected maximum value in the input torch.Tensor. The shape has to
      according to the input torch.Tensor shape, or at least has to work with broadcasting.

Example:
    >>> img = torch.rand(1, 2, 4, 4)
    >>> invert(img).shape
    torch.Size([1, 2, 4, 4])

    >>> img = 255. * torch.rand(1, 2, 3, 4, 4)
    >>> invert(img, torch.as_tensor(255.)).shape
    torch.Size([1, 2, 3, 4, 4])

    >>> img = torch.rand(1, 3, 4, 4)
    >>> invert(img, torch.as_tensor([[[[1.]]]])).shape
    torch.Size([1, 3, 4, 4])

z"Input is not a torch.Tensor. Got: r:   z$max_val is not a torch.Tensor. Got: )r#   r%   r&   ru   rD   rT   tensorr(   )r.   max_val_max_vals      r5   invertr      s    0 eU\\**A$u+OPP<<&h--CDNCSTUU;;u%%r7   c                  `   ^  \ rS rSr% Sr/ SQrS\S'   / SQrS\S'   S
U 4S jjrSS jr	S	r
U =r$ )AdjustSaturationi%  a  Adjust color saturation of an image.

The input image is expected to be an RGB image in the range of [0, 1].

Args:
    saturation_factor: How much to adjust the saturation. 0 will give a black
      and white image, 1 will give the original image while 2 will enhance the saturation by a factor of 2.
    saturation_mode: The mode to adjust saturation.

Shape:
    - Input: Image/torch.Tensor to be adjusted in the shape of :math:`(*, 3, H, W)`.
    - Output: Adjusted image in the shape of :math:`(*, 3, H, W)`.

Example:
    >>> x = torch.ones(1, 3, 3, 3)
    >>> AdjustSaturation(2.)(x)
    tensor([[[[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]],
    <BLANKLINE>
             [[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]],
    <BLANKLINE>
             [[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]]]])

    >>> x = torch.ones(2, 3, 3, 3)
    >>> y = torch.ones(2)
    >>> out = AdjustSaturation(y)(x)
    >>> torch.nn.functional.mse_loss(x, out)
    tensor(0.)

rM   r   rM   rM   ClassVar[list[int]]ONNX_DEFAULT_INPUTSHAPEONNX_DEFAULT_OUTPUTSHAPEc                .   > [         TU ]  5         Xl        g Nsuper__init__saturation_factorselfr   	__class__s     r5   r   AdjustSaturation.__init__M      =Nr7   c                ,    [        XR                  5      $ r   )rA   r   r   rT   s     r5   forwardAdjustSaturation.forwardQ       (>(>??r7   r   r   Union[float, torch.Tensor]r   NonerT   r   r   r   __name__
__module____qualname____firstlineno____doc__r   __annotations__r   r   r   __static_attributes____classcell__r   s   @r5   r   r   %  s6    "H 4C0B4C1CO@ @r7   r   c                  `   ^  \ rS rSr% Sr/ SQrS\S'   / SQrS\S'   S
U 4S jjrSS jr	S	r
U =r$ )#AdjustSaturationWithGraySubtractioniU  a  Adjust color saturation of an image.

This implementation aligns PIL. Hence, the output is close to TorchVision.
The input image is expected to be in the range of [0, 1].

The input image is expected to be an RGB or gray image in the range of [0, 1].

Args:
    saturation_factor: How much to adjust the saturation. 0 will give a black
      and white image, 1 will give the original image while 2 will enhance the saturation by a factor of 2.
    saturation_mode: The mode to adjust saturation.

Shape:
    - Input: Image/torch.Tensor to be adjusted in the shape of :math:`(*, 3, H, W)`.
    - Output: Adjusted image in the shape of :math:`(*, 3, H, W)`.

Example:
    >>> x = torch.ones(1, 3, 3, 3)
    >>> AdjustSaturationWithGraySubtraction(2.)(x)
    tensor([[[[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]],
    <BLANKLINE>
             [[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]],
    <BLANKLINE>
             [[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]]]])

    >>> x = torch.ones(2, 3, 3, 3)
    >>> y = torch.ones(2)
    >>> out = AdjustSaturationWithGraySubtraction(y)(x)
    >>> torch.nn.functional.mse_loss(x, out)
    tensor(0.)

r   r   r   r   c                .   > [         TU ]  5         Xl        g r   r   r   s     r5   r   ,AdjustSaturationWithGraySubtraction.__init__  r   r7   c                ,    [        XR                  5      $ r   )r=   r   r   s     r5   r   +AdjustSaturationWithGraySubtraction.forward  s    6u>T>TUUr7   r   r   r   r   r  s   @r5   r
  r
  U  s6    %N 4C0B4C1COV Vr7   r
  c                  `   ^  \ rS rSr% Sr/ SQrS\S'   / SQrS\S'   S
U 4S jjrSS jr	S	r
U =r$ )	AdjustHuei  a  Adjust hue of an image.

This implementation aligns PIL. Hence, the output is close to TorchVision.
The input image is expected to be in the range of [0, 1].

The input image is expected to be an RGB image in the range of [0, 1].

Args:
    hue_factor: How much to shift the hue channel. Should be in [-PI, PI]. PI
      and -PI give complete reversal of hue channel in HSV space in positive and negative
      direction respectively. 0 means no shift. Therefore, both -PI and PI will give an
      image with complementary colors while 0 gives the original image.

Shape:
    - Input: Image/torch.Tensor to be adjusted in the shape of :math:`(*, 3, H, W)`.
    - Output: Adjusted image in the shape of :math:`(*, 3, H, W)`.

Example:
    >>> x = torch.ones(1, 3, 3, 3)
    >>> AdjustHue(3.141516)(x)
    tensor([[[[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]],
    <BLANKLINE>
             [[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]],
    <BLANKLINE>
             [[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]]]])

    >>> x = torch.ones(2, 3, 3, 3)
    >>> y = torch.ones(2) * 3.141516
    >>> AdjustHue(y)(x).shape
    torch.Size([2, 3, 3, 3])

r   r   r   r   c                .   > [         TU ]  5         Xl        g r   )r   r   
hue_factor)r   r  r   s     r5   r   AdjustHue.__init__  s    6@r7   c                ,    [        XR                  5      $ r   )rJ   r  r   s     r5   r   AdjustHue.forward  s    %11r7   )r  )r  r   r   r   r   r   r  s   @r5   r  r    s4    %N 4C0B4C1CA2 2r7   r  c                  >   ^  \ rS rSrSrSSU 4S jjjrSS jrSrU =r$ )	AdjustGammai  a  Perform gamma correction on an image.

The input image is expected to be in the range of [0, 1].

Args:
    gamma: Non negative real number, same as y\gammay in the equation.
      gamma larger than 1 make the shadows darker, while gamma smaller than 1 make
      dark regions lighter.
    gain: The constant multiplier.

Shape:
    - Input: Image to be adjusted in the shape of :math:`(*, N)`.
    - Output: Adjusted image in the shape of :math:`(*, N)`.

Example:
    >>> x = torch.ones(1, 1, 3, 3)
    >>> AdjustGamma(1.0, 2.0)(x)
    tensor([[[[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]]]])

    >>> x = torch.ones(2, 5, 3, 3)
    >>> y1 = torch.ones(2) * 1.0
    >>> y2 = torch.ones(2) * 2.0
    >>> AdjustGamma(y1, y2)(x).shape
    torch.Size([2, 5, 3, 3])

c                :   > [         TU ]  5         Xl        X l        g r   )r   r   rU   rV   )r   rU   rV   r   s      r5   r   AdjustGamma.__init__  s    16
04	r7   c                B    [        XR                  U R                  5      $ r   )rY   rU   rV   r   s     r5   r   AdjustGamma.forward  s    E::tyy99r7   )rV   rU   r:   )rU   r   rV   r   r   r   r   	r   r  r  r  r  r   r   r  r  r  s   @r5   r  r    s    :5 5
: :r7   r  c                  :   ^  \ rS rSrSrSU 4S jjrSS jrSrU =r$ )AdjustContrasti  at  Adjust Contrast of an image.

This implementation aligns OpenCV, not PIL. Hence, the output differs from TorchVision.
The input image is expected to be in the range of [0, 1].

Args:
    contrast_factor: Contrast adjust factor per element
      in the batch. 0 generates a completely black image, 1 does not modify
      the input image while any other non-negative number modify the
      brightness by this factor.

Shape:
    - Input: Image/Input to be adjusted in the shape of :math:`(*, N)`.
    - Output: Adjusted image in the shape of :math:`(*, N)`.

Example:
    >>> x = torch.ones(1, 1, 3, 3)
    >>> AdjustContrast(0.5)(x)
    tensor([[[[0.5000, 0.5000, 0.5000],
              [0.5000, 0.5000, 0.5000],
              [0.5000, 0.5000, 0.5000]]]])

    >>> x = torch.ones(2, 5, 3, 3)
    >>> y = torch.ones(2)
    >>> AdjustContrast(y)(x).shape
    torch.Size([2, 5, 3, 3])

c                .   > [         TU ]  5         Xl        g r   r   r   contrast_factorr   r"  r   s     r5   r   AdjustContrast.__init__       ;Jr7   c                ,    [        XR                  5      $ r   )r^   r"  r   s     r5   r   AdjustContrast.forward  s    u&:&:;;r7   r"  r"  r   r   r   r   r  r  s   @r5   r  r    s    :K< <r7   r  c                  :   ^  \ rS rSrSrSU 4S jjrSS jrSrU =r$ )!AdjustContrastWithMeanSubtractioni  a  Adjust Contrast of an image.

This implementation aligns PIL. Hence, the output is close to TorchVision.
The input image is expected to be in the range of [0, 1].

Args:
    contrast_factor: Contrast adjust factor per element
      in the batch by subtracting its mean grayscaled version.
      0 generates a completely black image, 1 does not modify
      the input image while any other non-negative number modify the
      brightness by this factor.

Shape:
    - Input: Image/Input to be adjusted in the shape of :math:`(*, N)`.
    - Output: Adjusted image in the shape of :math:`(*, N)`.

Example:
    >>> x = torch.ones(1, 1, 3, 3)
    >>> AdjustContrastWithMeanSubtraction(0.5)(x)
    tensor([[[[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]]]])

    >>> x = torch.ones(2, 5, 3, 3)
    >>> y = torch.ones(2)
    >>> AdjustContrastWithMeanSubtraction(y)(x).shape
    torch.Size([2, 5, 3, 3])

c                .   > [         TU ]  5         Xl        g r   r!  r#  s     r5   r   *AdjustContrastWithMeanSubtraction.__init__'  r%  r7   c                ,    [        XR                  5      $ r   )rc   r"  r   s     r5   r   )AdjustContrastWithMeanSubtraction.forward+  s    4U<P<PQQr7   r(  r)  r   r  r  s   @r5   r+  r+    s    <KR Rr7   r+  c                  :   ^  \ rS rSrSrSU 4S jjrSS jrSrU =r$ )AdjustBrightnessi/  a  Adjust Brightness of an image.

This implementation aligns OpenCV, not PIL. Hence, the output differs from TorchVision.
The input image is expected to be in the range of [0, 1].

Args:
    brightness_factor: Brightness adjust factor per element
      in the batch. 0 does not modify the input image while any other number modify the
      brightness.

Shape:
    - Input: Image/Input to be adjusted in the shape of :math:`(*, N)`.
    - Output: Adjusted image in the shape of :math:`(*, N)`.

Example:
    >>> x = torch.ones(1, 1, 3, 3)
    >>> AdjustBrightness(1.)(x)
    tensor([[[[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]]]])

    >>> x = torch.ones(2, 5, 3, 3)
    >>> y = torch.ones(2)
    >>> AdjustBrightness(y)(x).shape
    torch.Size([2, 5, 3, 3])

c                .   > [         TU ]  5         Xl        g r   r   r   brightness_factorr   r4  r   s     r5   r   AdjustBrightness.__init__L  r   r7   c                ,    [        XR                  5      $ r   )rf   r4  r   s     r5   r   AdjustBrightness.forwardP  r   r7   r4  r4  r   r   r   r   r  r  s   @r5   r1  r1  /  s    8O@ @r7   r1  c                  >   ^  \ rS rSrSrSSU 4S jjjrSS jrSrU =r$ )	AdjustSigmoidiT  a  Adjust the contrast of an image torch.Tensor or performs sigmoid correction on the input image torch.Tensor.

The input image is expected to be in the range of [0, 1].

Reference:
    [1]: Gustav J. Braun, "Image Lightness Rescaling Using Sigmoidal Contrast Enhancement Functions",
         http://markfairchild.org/PDFs/PAP07.pdf

Args:
    image: Image to be adjusted in the shape of :math:`(*, H, W)`.
    cutoff: The cutoff of sigmoid function.
    gain: The multiplier of sigmoid function.
    inv: If is set to True the function will return the negative sigmoid correction.

Example:
    >>> x = torch.ones(1, 1, 2, 2)
    >>> AdjustSigmoid(gain=0)(x)
    tensor([[[[0.5000, 0.5000],
              [0.5000, 0.5000]]]])

c                F   > [         TU ]  5         Xl        X l        X0l        g r   )r   r   rk   rV   rl   )r   rk   rV   rl   r   s       r5   r   AdjustSigmoid.__init__k  s    #	r7   c                T    [        XR                  U R                  U R                  S9$ )Nrk   rV   rl   )rm   rk   rV   rl   r   r.   s     r5   r   AdjustSigmoid.forwardq  s    eKKdiiTXXVVr7   r@  r}   
   F)rk   r$   rV   r$   rl   boolr   r   r.   r   r   r   r  r  s   @r5   r<  r<  T  s    , W Wr7   r<  c                  >   ^  \ rS rSrSrSSU 4S jjjrSS jrSrU =r$ )		AdjustLogiu  an  Adjust log correction on the input image torch.Tensor.

The input image is expected to be in the range of [0, 1].

Reference:
[1]: http://www.ece.ucsb.edu/Faculty/Manjunath/courses/ece178W03/EnhancePart1.pdf

Args:
    image: Image to be adjusted in the shape of :math:`(*, H, W)`.
    gain: The multiplier of logarithmic function.
    inv:  If is set to True the function will return the inverse logarithmic correction.
    clip_output: Whether to clip the output image with range of [0, 1].

Example:
    >>> x = torch.zeros(1, 1, 2, 2)
    >>> AdjustLog(inv=True)(x)
    tensor([[[[0., 0.],
              [0., 0.]]]])

c                F   > [         TU ]  5         Xl        X l        X0l        g r   )r   r   rV   rl   r\   )r   rV   rl   r\   r   s       r5   r   AdjustLog.__init__  s    	!,r7   c                T    [        XR                  U R                  U R                  S9$ )N)rV   rl   r\   )rp   rV   rl   r\   rA  s     r5   r   AdjustLog.forward  s    %iiTXX4K[K[\\r7   )r\   rV   rl   r   FT)rV   r$   rl   rE  r\   rE  r   r   rF  r  r  s   @r5   rH  rH  u  s    *- -] ]r7   rH  c                  :   ^  \ rS rSrSrSU 4S jjrSS jrSrU =r$ )AdjustBrightnessAccumulativei  a+  Adjust Brightness of an image accumulatively.

This implementation aligns PIL. Hence, the output is close to TorchVision.
The input image is expected to be in the range of [0, 1].

Args:
    brightness_factor: Brightness adjust factor per element
      in the batch. 0 does not modify the input image while any other number modify the
      brightness.

Shape:
    - Input: Image/Input to be adjusted in the shape of :math:`(*, N)`.
    - Output: Adjusted image in the shape of :math:`(*, N)`.

Example:
    >>> x = torch.ones(1, 1, 3, 3)
    >>> AdjustBrightnessAccumulative(1.)(x)
    tensor([[[[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]]]])

    >>> x = torch.ones(2, 5, 3, 3)
    >>> y = torch.ones(2)
    >>> AdjustBrightnessAccumulative(y)(x).shape
    torch.Size([2, 5, 3, 3])

c                .   > [         TU ]  5         Xl        g r   r3  r5  s     r5   r   %AdjustBrightnessAccumulative.__init__  r   r7   c                ,    [        XR                  5      $ r   )rh   r4  r   s     r5   r   $AdjustBrightnessAccumulative.forward  s    -e5K5KLLr7   r9  r:  r   r  r  s   @r5   rO  rO    s    8OM Mr7   rO  c                  >   ^  \ rS rSrSrSSU 4S jjjrSS jrSrU =r$ )	Inverti  a  Invert the values of an input torch.Tensor by its maximum value.

Args:
    input: The input torch.Tensor to invert with an arbitatry shape.
    max_val: The expected maximum value in the input torch.Tensor. The shape has to
      according to the input torch.Tensor shape, or at least has to work with broadcasting. Default: 1.0.

Example:
    >>> img = torch.rand(1, 2, 4, 4)
    >>> Invert()(img).shape
    torch.Size([1, 2, 4, 4])

    >>> img = 255. * torch.rand(1, 2, 3, 4, 4)
    >>> Invert(torch.as_tensor(255.))(img).shape
    torch.Size([1, 2, 3, 4, 4])

    >>> img = torch.rand(1, 3, 4, 4)
    >>> Invert(torch.as_tensor([[[[1.]]]]))(img).shape
    torch.Size([1, 3, 4, 4])

c                   > [         TU ]  5         Uc  [        R                  " S5      n[	        U[
        R                  5      (       d  U R                  SU5        g Xl        g )Nr:   r   )	r   r   r%   r   r#   r   	Parameterregister_bufferr   )r   r   r   s     r5   r   Invert.__init__  sG    ?ll3'G'2<<00  G4"Lr7   c                ,    [        XR                  5      $ r   )r   r   r   s     r5   r   Invert.forward  s    e\\**r7   )r   r   )r   Optional[torch.Tensor]r   r   r   r  r  s   @r5   rU  rU    s    ,# #+ +r7   rU  )r.   r   r/   r   r   r   r  )rT   r   rU   r   rV   r   r   r   )T)r.   r   r/   r   r\   rE  r   r   rC  )
r.   r   rk   r$   rV   r$   rl   rE  r   r   rM  )
r.   r   rV   r$   rl   rE  r\   rE  r   r   )r}   )rT   r   ry   r   r   r   )r}   N)rT   r   ry   r   r   z$Optional[Union[float, torch.Tensor]]r   r   )rT   r   r   zUnion[int, torch.Tensor]r   r   )rT   r   r/   r   r   r   )r   r   r   r   r/   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r.   r   r   r\  r   r   )<
__future__r   mathr   typingr   r   r   r%   torch.nn.functionalr   r   r   kornia.colorr	   r
   r   kornia.core.checkr   r   r   kornia.core.utilsr   kornia.image.utilsr   r   r6   r=   rA   rH   rJ   rY   r^   rc   rf   rh   rm   rp   r{   r   r   r   r   r   r   r   r   r   Moduler   r
  r  r  r  r+  r1  r<  rH  rO  rU   r7   r5   <module>rg     so  $ #  , ,     A A 
 0 Q<6r'TB(X `cGG :GB\GGTAH7v RVCC!;CJNCCN RV44!;4JN44nD#L?B .16:B(B(*B( 4B( 	B(J V9 V9r 4a 4an"<	$'T  :  ."&J-@ryy -@`0V")) 0Vf02		 02f$:")) $:N#<RYY #<L$R		 $RN"@ryy "@JWBII WB]		 ]@"M299 "MJ!+RYY !+r7   