o
    e5                     @   s   d Z ddlmZmZmZ ddlZddlZddl	m
Z
mZmZmZmZ ddl	mZ ddl	mZ G d	d
 d
e
jZG dd de
jZG dd de
jZG dd deZG dd de
jZG dd de
jZG dd deZG dd de
jZdS )a  
Augmenters that create weather effects.

List of augmenters:

    * :class:`FastSnowyLandscape`
    * :class:`CloudLayer`
    * :class:`Clouds`
    * :class:`Fog`
    * :class:`SnowflakesLayer`
    * :class:`Snowflakes`
    * :class:`RainLayer`
    * :class:`Rain`

    )print_functiondivisionabsolute_importN   )meta
arithmeticblurcontrastcolor   )
parameters)dtypesc                       sJ   e Zd ZdZddejddddf fdd	Zdd	 Zd
d Zdd Z	  Z
S )FastSnowyLandscapea  Convert non-snowy landscapes to snowy ones.

    This augmenter expects to get an image that roughly shows a landscape.

    This augmenter is based on the method proposed in
    https://medium.freecodecamp.org/image-augmentation-make-it-rain-make-it-snow-how-to-modify-a-photo-with-machine-learning-163c0cb3843f?gi=bca4a13e634c

    **Supported dtypes**:

        * ``uint8``: yes; fully tested
        * ``uint16``: no (1)
        * ``uint32``: no (1)
        * ``uint64``: no (1)
        * ``int8``: no (1)
        * ``int16``: no (1)
        * ``int32``: no (1)
        * ``int64``: no (1)
        * ``float16``: no (1)
        * ``float32``: no (1)
        * ``float64``: no (1)
        * ``float128``: no (1)
        * ``bool``: no (1)

        - (1) This augmenter is based on a colorspace conversion to HLS.
              Hence, only RGB ``uint8`` inputs are sensible.

    Parameters
    ----------
    lightness_threshold : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        All pixels with lightness in HLS colorspace that is below this value
        will have their lightness increased by `lightness_multiplier`.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the discrete interval ``[a..b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    lightness_multiplier : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Multiplier for pixel's lightness value in HLS colorspace.
        Affects all pixels selected via `lightness_threshold`.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the discrete interval ``[a..b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    from_colorspace : str, optional
        The source colorspace of the input images.
        See :func:`~imgaug.augmenters.color.ChangeColorspace.__init__`.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.FastSnowyLandscape(
    >>>     lightness_threshold=140,
    >>>     lightness_multiplier=2.5
    >>> )

    Search for all pixels in the image with a lightness value in HLS
    colorspace of less than ``140`` and increase their lightness by a factor
    of ``2.5``.

    >>> aug = iaa.FastSnowyLandscape(
    >>>     lightness_threshold=[128, 200],
    >>>     lightness_multiplier=(1.5, 3.5)
    >>> )

    Search for all pixels in the image with a lightness value in HLS
    colorspace of less than ``128`` or less than ``200`` (one of these
    values is picked per image) and multiply their lightness by a factor
    of ``x`` with ``x`` being sampled from ``uniform(1.5, 3.5)`` (once per
    image).

    >>> aug = iaa.FastSnowyLandscape(
    >>>     lightness_threshold=(100, 255),
    >>>     lightness_multiplier=(1.0, 4.0)
    >>> )

    Similar to the previous example, but the lightness threshold is sampled
    from ``uniform(100, 255)`` (per image) and the multiplier
    from ``uniform(1.0, 4.0)`` (per image). This seems to produce good and
    varied results.

    )d      )      ?g      @N
deprecatedc                    sN   t t| j||||d tj|ddddd| _tj|ddddd| _|| _d S )Nseednamerandom_statedeterministiclightness_threshold)r   r   T)value_rangeZtuple_to_uniformZlist_to_choicelightness_multiplier)r   N)superr   __init__iaphandle_continuous_paramr   r   from_colorspace)selfr   r   r   r   r   r   r   	__class__ ID:\Projects\ConvertPro\env\Lib\site-packages\imgaug/augmenters/weather.pyr      s   

zFastSnowyLandscape.__init__c                 C   sB   t |}|d}| j|f|d }| j|f|d }||fS )Nr   r   r   )len	duplicater   draw_samplesr   )r    Zaugmentablesr   Znb_augmentablesrssthresh_sampleslmul_samplesr#   r#   r$   _draw_samples   s   


z FastSnowyLandscape._draw_samplesc                 C   s   |j d u r|S |j }| ||\}}tt|||}|D ];\}	\}
}}t|
tj| j}|j}|	t
j}|d }|||k   |9  < t||}t|| jtj}||j |	< q|S )N).r   )imagesr+   	enumeratezipcolorlibZchange_colorspace_Z
CSPACE_HLSr   dtypeastypenpfloat64iadtZrestore_dtypes_)r    batchr   parentshooksr,   r)   r*   geniimageZthreshZlmulZ	image_hlsZ	cvt_dtypeZ	lightnessZ	image_rgbr#   r#   r$   _augment_batch_   s&   


z"FastSnowyLandscape._augment_batch_c                 C   s   | j | jgS z=See :func:`~imgaug.augmenters.meta.Augmenter.get_parameters`.)r   r   r    r#   r#   r$   get_parameters   s   z!FastSnowyLandscape.get_parameters)__name__
__module____qualname____doc__r/   Z
CSPACE_RGBr   r+   r;   r>   __classcell__r#   r#   r!   r$   r      s    l
r   c                       sj   e Zd ZdZ		d fdd	Zdd Zdd	 Zd
d Zdd Ze	dd Z
e	dd Ze	dd Z  ZS )
CloudLayera  Add a single layer of clouds to an image.

    **Supported dtypes**:

        * ``uint8``: yes; indirectly tested (1)
        * ``uint16``: no
        * ``uint32``: no
        * ``uint64``: no
        * ``int8``: no
        * ``int16``: no
        * ``int32``: no
        * ``int64``: no
        * ``float16``: yes; not tested
        * ``float32``: yes; not tested
        * ``float64``: yes; not tested
        * ``float128``: yes; not tested (2)
        * ``bool``: no

        - (1) Indirectly tested via tests for :class:`Clouds`` and :class:`Fog`
        - (2) Note that random values are usually sampled as ``int64`` or
              ``float64``, which ``float128`` images would exceed. Note also
              that random values might have to upscaled, which is done
              via :func:`~imgaug.imgaug.imresize_many_images` and has its own
              limited dtype support (includes however floats up to ``64bit``).

    Parameters
    ----------
    intensity_mean : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Mean intensity of the clouds (i.e. mean color).
        Recommended to be in the interval ``[190, 255]``.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly
              sampled per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    intensity_freq_exponent : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Exponent of the frequency noise used to add fine intensity to the
        mean intensity.
        Recommended to be in the interval ``[-2.5, -1.5]``.
        See :func:`~imgaug.parameters.FrequencyNoise.__init__` for details.

    intensity_coarse_scale : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Standard deviation of the gaussian distribution used to add more
        localized intensity to the mean intensity. Sampled in low resolution
        space, i.e. affects final intensity on a coarse level.
        Recommended to be in the interval ``(0, 10]``.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    alpha_min : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Minimum alpha when blending cloud noise with the image.
        High values will lead to clouds being "everywhere".
        Recommended to usually be at around ``0.0`` for clouds and ``>0`` for
        fog.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    alpha_multiplier : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Multiplier for the sampled alpha values. High values will lead to
        denser clouds wherever they are visible.
        Recommended to be in the interval ``[0.3, 1.0]``.
        Note that this parameter currently overlaps with `density_multiplier`,
        which is applied a bit later to the alpha mask.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    alpha_size_px_max : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Controls the image size at which the alpha mask is sampled.
        Lower values will lead to coarser alpha masks and hence larger
        clouds (and empty areas).
        See :func:`~imgaug.parameters.FrequencyNoise.__init__` for details.

    alpha_freq_exponent : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Exponent of the frequency noise used to sample the alpha mask.
        Similarly to `alpha_size_max_px`, lower values will lead to coarser
        alpha patterns.
        Recommended to be in the interval ``[-4.0, -1.5]``.
        See :func:`~imgaug.parameters.FrequencyNoise.__init__` for details.

    sparsity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Exponent applied late to the alpha mask. Lower values will lead to
        coarser cloud patterns, higher values to finer patterns.
        Recommended to be somewhere around ``1.0``.
        Do not deviate far from that value, otherwise the alpha mask might
        get weird patterns with sudden fall-offs to zero that look very
        unnatural.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    density_multiplier : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Late multiplier for the alpha mask, similar to `alpha_multiplier`.
        Set this higher to get "denser" clouds wherever they are visible.
        Recommended to be around ``[0.5, 1.5]``.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Nr   c                    sz   t t| j|
|||d t|d| _|| _|| _t|d| _t|d| _	|| _
|| _t|d| _t|	d| _d S )Nr   intensity_mean	alpha_minalpha_multipliersparsitydensity_multiplier)r   rD   r   r   r   rE   intensity_freq_exponentintensity_coarse_scalerF   rG   alpha_size_px_maxalpha_freq_exponentrH   rI   )r    rE   rJ   rK   rF   rG   rL   rM   rH   rI   r   r   r   r   r!   r#   r$   r   [  s&   

zCloudLayer.__init__c           
      C   T   |j d u r|S |j }|t|}tt||D ]\}\}}	| ||	|j |< q|S Nr,   r&   r%   r-   r.   draw_on_image
r    r5   r   r6   r7   r,   r(   r9   r:   rsr#   r#   r$   r;   r     
zCloudLayer._augment_batch_c              	   C   (   | j | j| j| j| j| j| j| j| jg	S r<   )	rE   rF   rG   rL   rM   rJ   rH   rI   rK   r=   r#   r#   r$   r>   }     zCloudLayer.get_parametersc                 C   s   t j|g dg dd | ||\}}|dtjf }|dtjf }|jjdkr8||j}d| | ||  S t|dd}td| ||j |||j  ddtj	S )	N)uint8Zfloat16float32r3   Zfloat96Zfloat128Zfloat256)boolZuint16Zuint32Zuint64Zuint128Zuint256Zint8Zint16Zint32Zint64Zint128Zint256)allowedZ
disallowed.fr   r   r   )
r4   Zgate_dtypesgenerate_mapsr2   newaxisr0   kindr1   cliprW   )r    r:   r   alpha	intensityr#   r#   r$   rQ     s(   
zCloudLayer.draw_on_imagec                 C   s   | j |}| j|}| j|}| j}| j}| j}| j|}	| j|}
|j	dd \}}|
d\}}| |||tjd| jd|}| |||||}|| }| |||||||	|
|	}||fS )Nr   r   )scale)rE   draw_samplerF   rG   rL   rJ   rM   rH   rI   shaper&   _generate_intensity_map_coarser   ZNormalrK   _generate_intensity_map_fine_generate_alpha_mask)r    r:   r   Zintensity_mean_sampleZalpha_min_sampleZalpha_multiplier_samplerL   rJ   rM   Zsparsity_sampleZdensity_multiplier_sampleheightwidthZ	rss_alphaZrss_intensityZintensity_coarseZintensity_finera   r`   r#   r#   r$   r\     s8   

zCloudLayer.generate_mapsc           	      C   s4   d\}}|| ||f| }tj|||fdd}|S )N   rk   cubicinterpolation)r'   iaimresize_single_image)	clsrh   ri   rE   Zintensity_local_offsetr   Zheight_intensityZwidth_intensityra   r#   r#   r$   re     s   
z)CloudLayer._generate_intensity_map_coarsec                 C   s<   t j|t||ddd}|||f|}|d| d d  S )Nr   rl   exponentZsize_px_maxZupscale_methodr   r   g      @)r   FrequencyNoisemaxr'   )rq   rh   ri   rE   rs   r   Zintensity_details_generatorZintensity_detailsr#   r#   r$   rf     s   
z'CloudLayer._generate_intensity_map_finec
                 C   sJ   t j||dd}
|
||f|	}|||  }|| | }t|dd}|S )Nrl   rr           r   )r   rt   r'   r2   r_   )rq   rh   ri   rF   rG   rs   rL   rH   rI   r   Zalpha_generatorZalpha_localr`   r#   r#   r$   rg     s   zCloudLayer._generate_alpha_maskNNr   r   )r?   r@   rA   rB   r   r;   r>   rQ   r\   classmethodre   rf   rg   rC   r#   r#   r!   r$   rD      s       

rD   c                       &   e Zd ZdZ		d fdd	Z  ZS )Cloudsa  
    Add clouds to images.

    This is a wrapper around :class:`~imgaug.augmenters.weather.CloudLayer`.
    It executes 1 to 2 layers per image, leading to varying densities and
    frequency patterns of clouds.

    This augmenter seems to be fairly robust w.r.t. the image size. Tested
    with ``96x128``, ``192x256`` and ``960x1280``.

    **Supported dtypes**:

        * ``uint8``: yes; tested
        * ``uint16``: no (1)
        * ``uint32``: no (1)
        * ``uint64``: no (1)
        * ``int8``: no (1)
        * ``int16``: no (1)
        * ``int32``: no (1)
        * ``int64``: no (1)
        * ``float16``: no (1)
        * ``float32``: no (1)
        * ``float64``: no (1)
        * ``float128``: no (1)
        * ``bool``: no (1)

        - (1) Parameters of this augmenter are optimized for the value range
              of ``uint8``. While other dtypes may be accepted, they will lead
              to images augmented in ways inappropriate for the respective
              dtype.

    Parameters
    ----------
    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.Clouds()

    Create an augmenter that adds clouds to images.

    Nr   c                    sb   t ddddddddd|||d	t dd
ddddd
dd|||d	g}tt| jd|d||||d d S )N)   r   )g             
   r   )g      ?g      ?r   rk   皙?r   )      ?r   )rE   rJ   rK   rF   rG   rL   rM   rH   rI   r   r   r   )r|   g      )@      )r   gffffff?)r   g      ?)r   r   FchildrenZrandom_orderr   r   r   r   )rD   r   rz   r   )r    r   r   r   r   Zlayersr!   r#   r$   r   0  sH   

zClouds.__init__rw   r?   r@   rA   rB   r   rC   r#   r#   r!   r$   rz     s
    <rz   c                       ry   )Foga  Add fog to images.

    This is a wrapper around :class:`~imgaug.augmenters.weather.CloudLayer`.
    It executes a single layer per image with a configuration leading to
    fairly dense clouds with low-frequency patterns.

    This augmenter seems to be fairly robust w.r.t. the image size. Tested
    with ``96x128``, ``192x256`` and ``960x1280``.

    **Supported dtypes**:

        * ``uint8``: yes; tested
        * ``uint16``: no (1)
        * ``uint32``: no (1)
        * ``uint64``: no (1)
        * ``int8``: no (1)
        * ``int16``: no (1)
        * ``int32``: no (1)
        * ``int64``: no (1)
        * ``float16``: no (1)
        * ``float32``: no (1)
        * ``float64``: no (1)
        * ``float128``: no (1)
        * ``bool``: no (1)

        - (1) Parameters of this augmenter are optimized for the value range
              of ``uint8``. While other dtypes may be accepted, they will lead
              to images augmented in ways inappropriate for the respective
              dtype.

    Parameters
    ----------
    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.Fog()

    Create an augmenter that adds fog to images.

    Nr   c                    s.   t t| jddddddddd	||||d
 d S )N)   r   )r|   g      r   )ffffff??333333?r~   )g      r|   r   )皙?r   )rE   rJ   rK   rF   rG   rL   rM   rH   rI   r   r   r   r   )r   r   r   )r    r   r   r   r   r!   r#   r$   r     s   

zFog.__init__rw   r   r#   r#   r!   r$   r   \  s
    ;r   c                       s   e Zd ZdZ			d fdd	Zdd Zd	d
 Zdd Zedd Z	edd Z
edd Zedd Zedd Zedd Zedd Zedd Z  ZS )SnowflakesLayeraH  Add a single layer of falling snowflakes to images.

    **Supported dtypes**:

        * ``uint8``: yes; indirectly tested (1)
        * ``uint16``: no
        * ``uint32``: no
        * ``uint64``: no
        * ``int8``: no
        * ``int16``: no
        * ``int32``: no
        * ``int64``: no
        * ``float16``: no
        * ``float32``: no
        * ``float64``: no
        * ``float128``: no
        * ``bool``: no

        - (1) indirectly tested via tests for :class:`Snowflakes`

    Parameters
    ----------
    density : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Density of the snowflake layer, as a probability of each pixel in
        low resolution space to be a snowflake.
        Valid values are in the interval ``[0.0, 1.0]``.
        Recommended to be in the interval ``[0.01, 0.075]``.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    density_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Size uniformity of the snowflakes. Higher values denote more
        similarly sized snowflakes.
        Valid values are in the interval ``[0.0, 1.0]``.
        Recommended to be around ``0.5``.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    flake_size : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Size of the snowflakes. This parameter controls the resolution at
        which snowflakes are sampled. Higher values mean that the resolution
        is closer to the input image's resolution and hence each sampled
        snowflake will be smaller (because of the smaller pixel size).

        Valid values are in the interval ``(0.0, 1.0]``.
        Recommended values:

            * On 96x128 a value of ``(0.1, 0.4)`` worked well.
            * On 192x256 a value of ``(0.2, 0.7)`` worked well.
            * On 960x1280 a value of ``(0.7, 0.95)`` worked well.

        Datatype behaviour:

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    flake_size_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Controls the size uniformity of the snowflakes. Higher values mean
        that the snowflakes are more similarly sized.
        Valid values are in the interval ``[0.0, 1.0]``.
        Recommended to be around ``0.5``.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    angle : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Angle in degrees of motion blur applied to the snowflakes, where
        ``0.0`` is motion blur that points straight upwards.
        Recommended to be in the interval ``[-30, 30]``.
        See also :func:`~imgaug.augmenters.blur.MotionBlur.__init__`.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    speed : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Perceived falling speed of the snowflakes. This parameter controls the
        motion blur's kernel size. It follows roughly the form
        ``kernel_size = image_size * speed``. Hence, values around ``1.0``
        denote that the motion blur should "stretch" each snowflake over the
        whole image.

        Valid values are in the interval ``[0.0, 1.0]``.
        Recommended values:

            * On 96x128 a value of ``(0.01, 0.05)`` worked well.
            * On 192x256 a value of ``(0.007, 0.03)`` worked well.
            * On 960x1280 a value of ``(0.001, 0.03)`` worked well.

        Datatype behaviour:

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    blur_sigma_fraction : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Standard deviation (as a fraction of the image size) of gaussian blur
        applied to the snowflakes.
        Valid values are in the interval ``[0.0, 1.0]``.
        Recommended to be in the interval ``[0.0001, 0.001]``. May still
        require tinkering based on image size.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    blur_sigma_limits : tuple of float, optional
        Controls allowed min and max values of `blur_sigma_fraction`
        after(!) multiplication with the image size. First value is the
        minimum, second value is the maximum. Values outside of that range
        will be clipped to be within that range. This prevents extreme
        values for very small or large images.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    r   g      @Nr   c                    s   t t| j|	|
||d || _tj|ddd| _tj|ddd| _tj|ddd| _t|d| _	tj|d	dd| _
tj|d
dd| _|| _d| _d S )Nr   density_uniformity)rv   r   )r   
flake_size)-C6?r   flake_size_uniformityanglespeedblur_sigma_fractionrj   )r   r   r   densityr   r   r   r   r   r   r   r   blur_sigma_limitsgate_noise_size)r    r   r   r   r   r   r   r   r   r   r   r   r   r!   r#   r$   r   R  s0   

zSnowflakesLayer.__init__c           
      C   rN   rO   rP   rR   r#   r#   r$   r;   o  rT   zSnowflakesLayer._augment_batch_c              	   C   rU   r<   )	r   r   r   r   r   r   r   r   r   r=   r#   r#   r$   r>   z  rV   zSnowflakesLayer.get_parametersc                 C   s|  |j dksJ d|j f |jd dv s J d|jd |jf |d}| j|}| j|}| j|}| j|}| j|}|j\}	}
}t	
d| dd}tdt|	| }tdt|
| }| ||| j|d	 }tdd| j }| ||| j|d }tj||	|
fd
d}t|	|
| }t	
|| jd	 | jd }| ||}| j||||d}| |||}| |||S )N   z@Expected input image to be three-dimensional, got %d dimensions.r   r   r   zLExpected to get image with a channel axis of size 1 or 3, got %d (shape: %s)r   MbP?r   r   rl   rm   )r   r   r   )ndimrd   r&   r   rc   r   r   r   r   r2   r_   ru   int_generate_noiser   r   Betar   _gater   ro   rp   r   _blur_motion_blur_postprocess_noise_blend)r    r:   r   r(   Zflake_size_sampleflake_size_uniformity_sampleZangle_samplespeed_sampleZblur_sigma_fraction_samplerh   ri   nb_channelsZdownscale_factorZheight_downZ
width_downnoise
gate_noisesigmanoise_small_blurnoise_small_blur_rgbr#   r#   r$   rQ     sb   

zSnowflakesLayer.draw_on_imagec                 C   s(   t j||d}|tj||ftjdS )N)pr   )r0   )r   ZSaltaugment_imager2   ZzerosrW   )rq   rh   ri   r   r   r   r#   r#   r$   r     s   zSnowflakesLayer._generate_noisec                 C   sV   | ||}tj||jdd dd}t|dd}t|tj| ddtjS )Nr   r   rl   rm   rv   r   r   )	r'   ro   rp   rd   r2   r_   r1   rX   rW   )rq   r   r   Z	gate_sizer   Zgate_noise_upr#   r#   r$   r     s   zSnowflakesLayer._gatec                 C   s   t j||dS )N)r   )r   Zblur_gaussian_rq   r   r   r#   r#   r$   r     s   zSnowflakesLayer._blurc                 C   sL   t |jdd }t|| }|dkr|S tjt |d|d|d}||S )Nr   r   r   r   r   )kr   	directionr   )ru   rd   r   r   Z
MotionBlurr   )rq   r   r   r   r   sizer   Zblurerr#   r#   r$   r     s   
zSnowflakesLayer._motion_blurc                 C   s`   ddd|   }ddd|   }t ||}|tj| }t|dtjf dd|f}|S )Nr   r   r      .)r	   ZGammaContrastr   r1   r2   rX   tiler]   )rq   r   r   r   ZgainZgain_adjr   r#   r#   r$   r     s   
z"SnowflakesLayer._postprocess_noisec                 C   s@   | tj}| |dd|  | }| |dd|  | }|S )Ng?   r   )r1   r2   rX   _blend_by_sum_blend_by_max)rq   r:   r   r   	image_f32r#   r#   r$   r     s   zSnowflakesLayer._blendc                 C   s   || }t |ddt jS Nr   r   )r2   r_   r1   rW   rq   r   r   r#   r#   r$   r     s   zSnowflakesLayer._blend_by_sumc                 C   s"   t ||}t |ddt jS r   )r2   maximumr_   r1   rW   r   r#   r#   r$   r     s   zSnowflakesLayer._blend_by_maxr   NNr   r   )r?   r@   rA   rB   r   r;   r>   rQ   rx   r   r   r   r   r   r   r   r   rC   r#   r#   r!   r$   r     s4     )5






r   c                       s,   e Zd ZdZ						d fd
d	Z  ZS )
Snowflakesa  Add falling snowflakes to images.

    This is a wrapper around
    :class:`~imgaug.augmenters.weather.SnowflakesLayer`. It executes 1 to 3
    layers per image.

    **Supported dtypes**:

        * ``uint8``: yes; tested
        * ``uint16``: no (1)
        * ``uint32``: no (1)
        * ``uint64``: no (1)
        * ``int8``: no (1)
        * ``int16``: no (1)
        * ``int32``: no (1)
        * ``int64``: no (1)
        * ``float16``: no (1)
        * ``float32``: no (1)
        * ``float64``: no (1)
        * ``float128``: no (1)
        * ``bool``: no (1)

        - (1) Parameters of this augmenter are optimized for the value range
              of ``uint8``. While other dtypes may be accepted, they will lead
              to images augmented in ways inappropriate for the respective
              dtype.

    Parameters
    ----------
    density : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Density of the snowflake layer, as a probability of each pixel in
        low resolution space to be a snowflake.
        Valid values are in the interval ``[0.0, 1.0]``.
        Recommended to be in the interval ``[0.01, 0.075]``.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    density_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Size uniformity of the snowflakes. Higher values denote more
        similarly sized snowflakes.
        Valid values are in the interval ``[0.0, 1.0]``.
        Recommended to be around ``0.5``.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    flake_size : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Size of the snowflakes. This parameter controls the resolution at
        which snowflakes are sampled. Higher values mean that the resolution
        is closer to the input image's resolution and hence each sampled
        snowflake will be smaller (because of the smaller pixel size).

        Valid values are in the interval ``(0.0, 1.0]``.
        Recommended values:

            * On ``96x128`` a value of ``(0.1, 0.4)`` worked well.
            * On ``192x256`` a value of ``(0.2, 0.7)`` worked well.
            * On ``960x1280`` a value of ``(0.7, 0.95)`` worked well.

        Datatype behaviour:

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    flake_size_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Controls the size uniformity of the snowflakes. Higher values mean
        that the snowflakes are more similarly sized.
        Valid values are in the interval ``[0.0, 1.0]``.
        Recommended to be around ``0.5``.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    angle : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Angle in degrees of motion blur applied to the snowflakes, where
        ``0.0`` is motion blur that points straight upwards.
        Recommended to be in the interval ``[-30, 30]``.
        See also :func:`~imgaug.augmenters.blur.MotionBlur.__init__`.

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    speed : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Perceived falling speed of the snowflakes. This parameter controls the
        motion blur's kernel size. It follows roughly the form
        ``kernel_size = image_size * speed``. Hence, values around ``1.0``
        denote that the motion blur should "stretch" each snowflake over
        the whole image.

        Valid values are in the interval ``[0.0, 1.0]``.
        Recommended values:

            * On ``96x128`` a value of ``(0.01, 0.05)`` worked well.
            * On ``192x256`` a value of ``(0.007, 0.03)`` worked well.
            * On ``960x1280`` a value of ``(0.001, 0.03)`` worked well.

        Datatype behaviour:

            * If a ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
              per image from the interval ``[a, b]``.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then a value will be sampled
              per image from that parameter.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.Snowflakes(flake_size=(0.1, 0.4), speed=(0.01, 0.05))

    Add snowflakes to small images (around ``96x128``).

    >>> aug = iaa.Snowflakes(flake_size=(0.2, 0.7), speed=(0.007, 0.03))

    Add snowflakes to medium-sized images (around ``192x256``).

    >>> aug = iaa.Snowflakes(flake_size=(0.7, 0.95), speed=(0.001, 0.03))

    Add snowflakes to large images (around ``960x1280``).

    g{Gzt?g333333?r   r   皙?r   r   r   i   gy&1|?Q?Nr   c                    sP   t ||||||d||	|
d
 tt| jd fddtdD d|||	|
d d S )	N)r   r   )
r   r   r   r   r   r   r   r   r   r   r   c                       g | ]}   qS r#   deepcopy.0_layerr#   r$   
<listcomp>      z'Snowflakes.__init__.<locals>.<listcomp>r   Fr   )r   r   r   r   range)r    r   r   r   r   r   r   r   r   r   r   r!   r   r$   r     &   

zSnowflakes.__init__)
r   r   r   r   r   r   NNr   r   r   r#   r#   r!   r$   r     s     'r   c                       sL   e Zd ZdZ			d fdd	Zedd Zed	d
 Zedd Z  Z	S )	RainLayera  Add a single layer of falling raindrops to images.

    Added in 0.4.0.

    **Supported dtypes**:

        * ``uint8``: yes; indirectly tested (1)
        * ``uint16``: no
        * ``uint32``: no
        * ``uint64``: no
        * ``int8``: no
        * ``int16``: no
        * ``int32``: no
        * ``int64``: no
        * ``float16``: no
        * ``float32``: no
        * ``float64``: no
        * ``float128``: no
        * ``bool``: no

        - (1) indirectly tested via tests for :class:`Rain`

    Parameters
    ----------
    density : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.

    density_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.

    drop_size : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Same as `flake_size` in
        :class:`~imgaug.augmenters.weather.SnowflakesLayer`.

    drop_size_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Same as `flake_size_uniformity` in
        :class:`~imgaug.augmenters.weather.SnowflakesLayer`.

    angle : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.

    speed : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.

    blur_sigma_fraction : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.

    blur_sigma_limits : tuple of float, optional
        Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    r   Nr   c                    s,   t t| j|||||||||	|
||d d S )N)r   r   r   r   r   )r   r   r   )r    r   r   	drop_sizedrop_size_uniformityr   r   r   r   r   r   r   r   r!   r#   r$   r     s   

zRainLayer.__init__c                 C   s   |S rO   r#   r   r#   r#   r$   r     s   zRainLayer._blurc                 C   s    t |dt jf dd|f}|S )N.r   )r2   r   r]   )rq   r   r   r   r   r#   r#   r$   r   "  s   zRainLayer._postprocess_noisec                 C   s   t |jdd }|dkr|nd}dd|  }|d }t d| dd}|t j}d| | ||  }t |dd	t jS )
Nr   i  r   n      g     o@g?r   r   )r2   sumZflatr_   r1   rX   rW   )rq   r:   r   r   Z	noise_sumZdrop_mean_colorr   r#   r#   r$   r   *  s   
zRainLayer._blendr   )
r?   r@   rA   rB   r   rx   r   r   r   rC   r#   r#   r!   r$   r     s    H

r   c                       s,   e Zd ZdZ					d	 fdd	Z  ZS )
Raina
  Add falling snowflakes to images.

    This is a wrapper around
    :class:`~imgaug.augmenters.weather.RainLayer`. It executes 1 to 3
    layers per image.

    .. note::

        This augmenter currently seems to work best for medium-sized images
        around ``192x256``. For smaller images, you may want to increase the
        `speed` value to e.g. ``(0.1, 0.3)``, otherwise the drops tend to
        look like snowflakes. For larger images, you may want to increase
        the `drop_size` to e.g. ``(0.10, 0.20)``.

    Added in 0.4.0.

    **Supported dtypes**:

        * ``uint8``: yes; tested
        * ``uint16``: no (1)
        * ``uint32``: no (1)
        * ``uint64``: no (1)
        * ``int8``: no (1)
        * ``int16``: no (1)
        * ``int32``: no (1)
        * ``int64``: no (1)
        * ``float16``: no (1)
        * ``float32``: no (1)
        * ``float64``: no (1)
        * ``float128``: no (1)
        * ``bool``: no (1)

        - (1) Parameters of this augmenter are optimized for the value range
              of ``uint8``. While other dtypes may be accepted, they will lead
              to images augmented in ways inappropriate for the respective
              dtype.

    Parameters
    ----------
    drop_size : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        See :class:`~imgaug.augmenters.weather.RainLayer`.

    speed : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        See :class:`~imgaug.augmenters.weather.RainLayer`.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.Rain(speed=(0.1, 0.3))

    Add rain to small images (around ``96x128``).

    >>> aug = iaa.Rain()

    Add rain to medium sized images (around ``192x256``).

    >>> aug = iaa.Rain(drop_size=(0.10, 0.20))

    Add rain to large images (around ``960x1280``).

    r   g{Gz?g{Gz?g{Gz?r   Nr   c                    sP   t dd|dd|d|||d
 tt| j| fddtd	D d
||||d d S )N)r   gQ?r   )r   r   )i   )r   r   )
r   r   r   r   r   r   r   r   r   r   c                    r   r#   r   r   r   r#   r$   r     r   z!Rain.__init__.<locals>.<listcomp>r   Fr   )r   r   r   r   r   )r    Znb_iterationsr   r   r   r   r   r   r!   r   r$   r     r   zRain.__init__)r   r   r   NNr   r   r   r#   r#   r!   r$   r   >  s    Pr   )rB   
__future__r   r   r   numpyr2   Zimgaugro    r   r   r   r	   r
   r/   r   r   r   r4   Z	Augmenterr   rD   ZSomeOfrz   r   r   r   r   r   r#   r#   r#   r$   <module>   s*     ,  1hO  _ Bu