"""
Augmenters that create weather effects.
List of augmenters:
* :class:`FastSnowyLandscape`
* :class:`CloudLayer`
* :class:`Clouds`
* :class:`Fog`
* :class:`SnowflakesLayer`
* :class:`Snowflakes`
* :class:`RainLayer`
* :class:`Rain`
"""
from __future__ import print_function, division, absolute_import
import numpy as np
import imgaug as ia
from . import meta, arithmetic, blur, contrast, color as colorlib
from .. import parameters as iap
from .. import dtypes as iadt
[docs]class FastSnowyLandscape(meta.Augmenter):
"""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.
"""
def __init__(self, lightness_threshold=(100, 255),
lightness_multiplier=(1.0, 4.0),
from_colorspace=colorlib.CSPACE_RGB,
seed=None, name=None,
random_state="deprecated", deterministic="deprecated"):
super(FastSnowyLandscape, self).__init__(
seed=seed, name=name,
random_state=random_state, deterministic=deterministic)
self.lightness_threshold = iap.handle_continuous_param(
lightness_threshold, "lightness_threshold",
value_range=(0, 255), tuple_to_uniform=True, list_to_choice=True)
self.lightness_multiplier = iap.handle_continuous_param(
lightness_multiplier, "lightness_multiplier",
value_range=(0, None), tuple_to_uniform=True, list_to_choice=True)
self.from_colorspace = from_colorspace
def _draw_samples(self, augmentables, random_state):
nb_augmentables = len(augmentables)
rss = random_state.duplicate(2)
thresh_samples = self.lightness_threshold.draw_samples(
(nb_augmentables,), rss[1])
lmul_samples = self.lightness_multiplier.draw_samples(
(nb_augmentables,), rss[0])
return thresh_samples, lmul_samples
# Added in 0.4.0.
def _augment_batch_(self, batch, random_state, parents, hooks):
if batch.images is None:
return batch
images = batch.images
thresh_samples, lmul_samples = self._draw_samples(images, random_state)
gen = enumerate(zip(images, thresh_samples, lmul_samples))
for i, (image, thresh, lmul) in gen:
image_hls = colorlib.change_colorspace_(
image, colorlib.CSPACE_HLS, self.from_colorspace)
cvt_dtype = image_hls.dtype
image_hls = image_hls.astype(np.float64)
lightness = image_hls[..., 1]
lightness[lightness < thresh] *= lmul
image_hls = iadt.restore_dtypes_(image_hls, cvt_dtype)
image_rgb = colorlib.change_colorspace_(
image_hls, self.from_colorspace, colorlib.CSPACE_HLS)
batch.images[i] = image_rgb
return batch
[docs] def get_parameters(self):
"""See :func:`~imgaug.augmenters.meta.Augmenter.get_parameters`."""
return [self.lightness_threshold, self.lightness_multiplier]
# TODO add examples and add these to the overview docs
# TODO add perspective transform to each cloud layer to make them look more
# distant?
# TODO alpha_mean and density overlap - remove one of them
[docs]class CloudLayer(meta.Augmenter):
"""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.
"""
def __init__(self, intensity_mean, intensity_freq_exponent,
intensity_coarse_scale, alpha_min, alpha_multiplier,
alpha_size_px_max, alpha_freq_exponent, sparsity,
density_multiplier,
seed=None, name=None,
random_state="deprecated", deterministic="deprecated"):
super(CloudLayer, self).__init__(
seed=seed, name=name,
random_state=random_state, deterministic=deterministic)
self.intensity_mean = iap.handle_continuous_param(
intensity_mean, "intensity_mean")
self.intensity_freq_exponent = intensity_freq_exponent
self.intensity_coarse_scale = intensity_coarse_scale
self.alpha_min = iap.handle_continuous_param(alpha_min, "alpha_min")
self.alpha_multiplier = iap.handle_continuous_param(
alpha_multiplier, "alpha_multiplier")
self.alpha_size_px_max = alpha_size_px_max
self.alpha_freq_exponent = alpha_freq_exponent
self.sparsity = iap.handle_continuous_param(sparsity, "sparsity")
self.density_multiplier = iap.handle_continuous_param(
density_multiplier, "density_multiplier")
# Added in 0.4.0.
def _augment_batch_(self, batch, random_state, parents, hooks):
if batch.images is None:
return batch
images = batch.images
rss = random_state.duplicate(len(images))
for i, (image, rs) in enumerate(zip(images, rss)):
batch.images[i] = self.draw_on_image(image, rs)
return batch
[docs] def get_parameters(self):
"""See :func:`~imgaug.augmenters.meta.Augmenter.get_parameters`."""
return [self.intensity_mean,
self.alpha_min,
self.alpha_multiplier,
self.alpha_size_px_max,
self.alpha_freq_exponent,
self.intensity_freq_exponent,
self.sparsity,
self.density_multiplier,
self.intensity_coarse_scale]
[docs] def draw_on_image(self, image, random_state):
iadt.gate_dtypes(image,
allowed=["uint8",
"float16", "float32", "float64",
"float96", "float128", "float256"],
disallowed=["bool",
"uint16", "uint32", "uint64", "uint128",
"uint256",
"int8", "int16", "int32", "int64",
"int128", "int256"])
alpha, intensity = self.generate_maps(image, random_state)
alpha = alpha[..., np.newaxis]
intensity = intensity[..., np.newaxis]
if image.dtype.kind == "f":
intensity = intensity.astype(image.dtype)
return (1 - alpha) * image + alpha * intensity
intensity = np.clip(intensity, 0, 255)
# TODO use blend_alpha_() here
return np.clip(
(1 - alpha) * image.astype(alpha.dtype)
+ alpha * intensity.astype(alpha.dtype),
0,
255
).astype(np.uint8)
[docs] def generate_maps(self, image, random_state):
intensity_mean_sample = self.intensity_mean.draw_sample(random_state)
alpha_min_sample = self.alpha_min.draw_sample(random_state)
alpha_multiplier_sample = \
self.alpha_multiplier.draw_sample(random_state)
alpha_size_px_max = self.alpha_size_px_max
intensity_freq_exponent = self.intensity_freq_exponent
alpha_freq_exponent = self.alpha_freq_exponent
sparsity_sample = self.sparsity.draw_sample(random_state)
density_multiplier_sample = \
self.density_multiplier.draw_sample(random_state)
height, width = image.shape[0:2]
rss_alpha, rss_intensity = random_state.duplicate(2)
intensity_coarse = self._generate_intensity_map_coarse(
height, width, intensity_mean_sample,
iap.Normal(0, scale=self.intensity_coarse_scale),
rss_intensity
)
intensity_fine = self._generate_intensity_map_fine(
height, width, intensity_mean_sample, intensity_freq_exponent,
rss_intensity)
intensity = intensity_coarse + intensity_fine
alpha = self._generate_alpha_mask(
height, width, alpha_min_sample, alpha_multiplier_sample,
alpha_freq_exponent, alpha_size_px_max, sparsity_sample,
density_multiplier_sample, rss_alpha)
return alpha, intensity
@classmethod
def _generate_intensity_map_coarse(cls, height, width, intensity_mean,
intensity_local_offset, random_state):
# TODO (8, 8) might be too simplistic for some image sizes
height_intensity, width_intensity = (8, 8)
intensity = (
intensity_mean
+ intensity_local_offset.draw_samples(
(height_intensity, width_intensity), random_state)
)
intensity = ia.imresize_single_image(
intensity, (height, width), interpolation="cubic")
return intensity
@classmethod
def _generate_intensity_map_fine(cls, height, width, intensity_mean,
exponent, random_state):
intensity_details_generator = iap.FrequencyNoise(
exponent=exponent,
size_px_max=max(height, width, 1), # 1 here for case H, W being 0
upscale_method="cubic"
)
intensity_details = intensity_details_generator.draw_samples(
(height, width), random_state)
return intensity_mean * ((2*intensity_details - 1.0)/5.0)
@classmethod
def _generate_alpha_mask(cls, height, width, alpha_min, alpha_multiplier,
exponent, alpha_size_px_max, sparsity,
density_multiplier, random_state):
alpha_generator = iap.FrequencyNoise(
exponent=exponent,
size_px_max=alpha_size_px_max,
upscale_method="cubic"
)
alpha_local = alpha_generator.draw_samples(
(height, width), random_state)
alpha = alpha_min + (alpha_multiplier * alpha_local)
alpha = (alpha ** sparsity) * density_multiplier
alpha = np.clip(alpha, 0.0, 1.0)
return alpha
# TODO add vertical gradient alpha to have clouds only at skylevel/groundlevel
# TODO add configurable parameters
[docs]class Clouds(meta.SomeOf):
"""
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.
"""
def __init__(self,
seed=None, name=None,
random_state="deprecated", deterministic="deprecated"):
layers = [
CloudLayer(
intensity_mean=(196, 255),
intensity_freq_exponent=(-2.5, -2.0),
intensity_coarse_scale=10,
alpha_min=0,
alpha_multiplier=(0.25, 0.75),
alpha_size_px_max=(2, 8),
alpha_freq_exponent=(-2.5, -2.0),
sparsity=(0.8, 1.0),
density_multiplier=(0.5, 1.0),
seed=seed,
random_state=random_state,
deterministic=deterministic
),
CloudLayer(
intensity_mean=(196, 255),
intensity_freq_exponent=(-2.0, -1.0),
intensity_coarse_scale=10,
alpha_min=0,
alpha_multiplier=(0.5, 1.0),
alpha_size_px_max=(64, 128),
alpha_freq_exponent=(-2.0, -1.0),
sparsity=(1.0, 1.4),
density_multiplier=(0.8, 1.5),
seed=seed,
random_state=random_state,
deterministic=deterministic
)
]
super(Clouds, self).__init__(
(1, 2),
children=layers,
random_order=False,
seed=seed, name=name,
random_state=random_state, deterministic=deterministic)
# TODO add vertical gradient alpha to have fog only at skylevel/groundlevel
# TODO add configurable parameters
[docs]class Fog(CloudLayer):
"""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.
"""
def __init__(self,
seed=None, name=None,
random_state="deprecated", deterministic="deprecated"):
super(Fog, self).__init__(
intensity_mean=(220, 255),
intensity_freq_exponent=(-2.0, -1.5),
intensity_coarse_scale=2,
alpha_min=(0.7, 0.9),
alpha_multiplier=0.3,
alpha_size_px_max=(2, 8),
alpha_freq_exponent=(-4.0, -2.0),
sparsity=0.9,
density_multiplier=(0.4, 0.9),
seed=seed, name=name,
random_state=random_state, deterministic=deterministic)
# TODO add examples and add these to the overview docs
# TODO snowflakes are all almost 100% white, add some grayish tones and
# maybe color to them
[docs]class SnowflakesLayer(meta.Augmenter):
"""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.
"""
def __init__(self, density, density_uniformity, flake_size,
flake_size_uniformity, angle, speed, blur_sigma_fraction,
blur_sigma_limits=(0.5, 3.75),
seed=None, name=None,
random_state="deprecated", deterministic="deprecated"):
super(SnowflakesLayer, self).__init__(
seed=seed, name=name,
random_state=random_state, deterministic=deterministic)
self.density = density
self.density_uniformity = iap.handle_continuous_param(
density_uniformity, "density_uniformity", value_range=(0.0, 1.0))
self.flake_size = iap.handle_continuous_param(
flake_size, "flake_size", value_range=(0.0+1e-4, 1.0))
self.flake_size_uniformity = iap.handle_continuous_param(
flake_size_uniformity, "flake_size_uniformity",
value_range=(0.0, 1.0))
self.angle = iap.handle_continuous_param(angle, "angle")
self.speed = iap.handle_continuous_param(
speed, "speed", value_range=(0.0, 1.0))
self.blur_sigma_fraction = iap.handle_continuous_param(
blur_sigma_fraction, "blur_sigma_fraction", value_range=(0.0, 1.0))
# (min, max), same for all images
self.blur_sigma_limits = blur_sigma_limits
# (height, width), same for all images
self.gate_noise_size = (8, 8)
# Added in 0.4.0.
def _augment_batch_(self, batch, random_state, parents, hooks):
if batch.images is None:
return batch
images = batch.images
rss = random_state.duplicate(len(images))
for i, (image, rs) in enumerate(zip(images, rss)):
batch.images[i] = self.draw_on_image(image, rs)
return batch
[docs] def get_parameters(self):
"""See :func:`~imgaug.augmenters.meta.Augmenter.get_parameters`."""
return [self.density,
self.density_uniformity,
self.flake_size,
self.flake_size_uniformity,
self.angle,
self.speed,
self.blur_sigma_fraction,
self.blur_sigma_limits,
self.gate_noise_size]
[docs] def draw_on_image(self, image, random_state):
assert image.ndim == 3, (
"Expected input image to be three-dimensional, "
"got %d dimensions." % (image.ndim,))
assert image.shape[2] in [1, 3], (
"Expected to get image with a channel axis of size 1 or 3, "
"got %d (shape: %s)" % (image.shape[2], image.shape))
rss = random_state.duplicate(2)
flake_size_sample = self.flake_size.draw_sample(random_state)
flake_size_uniformity_sample = self.flake_size_uniformity.draw_sample(
random_state)
angle_sample = self.angle.draw_sample(random_state)
speed_sample = self.speed.draw_sample(random_state)
blur_sigma_fraction_sample = self.blur_sigma_fraction.draw_sample(
random_state)
height, width, nb_channels = image.shape
downscale_factor = np.clip(1.0 - flake_size_sample, 0.001, 1.0)
height_down = max(1, int(height*downscale_factor))
width_down = max(1, int(width*downscale_factor))
noise = self._generate_noise(
height_down,
width_down,
self.density,
rss[0]
)
# gate the sampled noise via noise in range [0.0, 1.0]
# this leads to less flakes in some areas of the image and more in
# other areas
gate_noise = iap.Beta(1.0, 1.0 - self.density_uniformity)
noise = self._gate(noise, gate_noise, self.gate_noise_size, rss[1])
noise = ia.imresize_single_image(noise, (height, width),
interpolation="cubic")
# apply a bit of gaussian blur and then motion blur according to
# angle and speed
sigma = max(height, width) * blur_sigma_fraction_sample
sigma = np.clip(sigma,
self.blur_sigma_limits[0], self.blur_sigma_limits[1])
noise_small_blur = self._blur(noise, sigma)
noise_small_blur = self._motion_blur(noise_small_blur,
angle=angle_sample,
speed=speed_sample,
random_state=random_state)
noise_small_blur_rgb = self._postprocess_noise(
noise_small_blur, flake_size_uniformity_sample, nb_channels)
return self._blend(image, speed_sample, noise_small_blur_rgb)
@classmethod
def _generate_noise(cls, height, width, density, random_state):
noise = arithmetic.Salt(p=density, random_state=random_state)
return noise.augment_image(np.zeros((height, width), dtype=np.uint8))
@classmethod
def _gate(cls, noise, gate_noise, gate_size, random_state):
# the beta distribution here has most of its weight around 1.0 and
# will only rarely sample values around 0.0 the average of the
# sampled values seems to be at around 0.6-0.75
gate_noise = gate_noise.draw_samples(gate_size, random_state)
gate_noise_up = ia.imresize_single_image(gate_noise, noise.shape[0:2],
interpolation="cubic")
gate_noise_up = np.clip(gate_noise_up, 0.0, 1.0)
return np.clip(
noise.astype(np.float32) * gate_noise_up, 0, 255
).astype(np.uint8)
@classmethod
def _blur(cls, noise, sigma):
return blur.blur_gaussian_(noise, sigma=sigma)
@classmethod
def _motion_blur(cls, noise, angle, speed, random_state):
size = max(noise.shape[0:2])
k = int(speed * size)
if k <= 1:
return noise
# we use max(k, 3) here because MotionBlur errors for anything less
# than 3
blurer = blur.MotionBlur(
k=max(k, 3), angle=angle, direction=1.0, random_state=random_state)
return blurer.augment_image(noise)
# Added in 0.4.0.
@classmethod
def _postprocess_noise(cls, noise_small_blur,
flake_size_uniformity_sample, nb_channels):
# use contrast adjustment of noise to make the flake size a bit less
# uniform then readjust the noise values to make them more visible
# again
gain = 1.0 + 2*(1 - flake_size_uniformity_sample)
gain_adj = 1.0 + 5*(1 - flake_size_uniformity_sample)
noise_small_blur = contrast.GammaContrast(gain).augment_image(
noise_small_blur)
noise_small_blur = noise_small_blur.astype(np.float32) * gain_adj
noise_small_blur_rgb = np.tile(
noise_small_blur[..., np.newaxis], (1, 1, nb_channels))
return noise_small_blur_rgb
# Added in 0.4.0.
@classmethod
def _blend(cls, image, speed_sample, noise_small_blur_rgb):
# blend:
# sum for a bit of glowy, hardly visible flakes
# max for the main flakes
image_f32 = image.astype(np.float32)
image_f32 = cls._blend_by_sum(
image_f32, (0.1 + 20*speed_sample) * noise_small_blur_rgb)
image_f32 = cls._blend_by_max(
image_f32, (1.0 + 20*speed_sample) * noise_small_blur_rgb)
return image_f32
# TODO replace this by a function from module blend.py
@classmethod
def _blend_by_sum(cls, image_f32, noise_small_blur_rgb):
image_f32 = image_f32 + noise_small_blur_rgb
return np.clip(image_f32, 0, 255).astype(np.uint8)
# TODO replace this by a function from module blend.py
@classmethod
def _blend_by_max(cls, image_f32, noise_small_blur_rgb):
image_f32 = np.maximum(image_f32, noise_small_blur_rgb)
return np.clip(image_f32, 0, 255).astype(np.uint8)
[docs]class Snowflakes(meta.SomeOf):
"""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``).
"""
def __init__(self, density=(0.005, 0.075), density_uniformity=(0.3, 0.9),
flake_size=(0.2, 0.7), flake_size_uniformity=(0.4, 0.8),
angle=(-30, 30), speed=(0.007, 0.03),
seed=None, name=None,
random_state="deprecated", deterministic="deprecated"):
layer = SnowflakesLayer(
density=density,
density_uniformity=density_uniformity,
flake_size=flake_size,
flake_size_uniformity=flake_size_uniformity,
angle=angle,
speed=speed,
blur_sigma_fraction=(0.0001, 0.001),
seed=seed,
random_state=random_state,
deterministic=deterministic
)
super(Snowflakes, self).__init__(
(1, 3),
children=[layer.deepcopy() for _ in range(3)],
random_order=False,
seed=seed, name=name,
random_state=random_state, deterministic=deterministic)
[docs]class RainLayer(SnowflakesLayer):
"""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.
"""
# Added in 0.4.0.
def __init__(self, density, density_uniformity, drop_size,
drop_size_uniformity, angle, speed, blur_sigma_fraction,
blur_sigma_limits=(0.5, 3.75),
seed=None, name=None,
random_state="deprecated", deterministic="deprecated"):
super(RainLayer, self).__init__(
density, density_uniformity, drop_size,
drop_size_uniformity, angle, speed, blur_sigma_fraction,
blur_sigma_limits=blur_sigma_limits,
seed=seed, name=name,
random_state=random_state, deterministic=deterministic)
# Added in 0.4.0.
@classmethod
def _blur(cls, noise, sigma):
return noise
# Added in 0.4.0.
@classmethod
def _postprocess_noise(cls, noise_small_blur,
flake_size_uniformity_sample, nb_channels):
noise_small_blur_rgb = np.tile(
noise_small_blur[..., np.newaxis], (1, 1, nb_channels))
return noise_small_blur_rgb
# Added in 0.4.0.
@classmethod
def _blend(cls, image, speed_sample, noise_small_blur_rgb):
# We set the mean color based on the noise here. That's a pseudo-random
# approach that saves us from adding the random state as a parameter.
# Note that the sum of noise_small_blur_rgb can be 0 when at least one
# image axis size is 0.
noise_sum = np.sum(noise_small_blur_rgb.flat[0:1000])
noise_sum = noise_sum if noise_sum > 0 else 1
drop_mean_color = 110 + (240 - 110) % noise_sum
noise_small_blur_rgb = noise_small_blur_rgb / 255.0
# The 1.3 multiplier increases the visibility of drops a bit.
noise_small_blur_rgb = np.clip(1.3 * noise_small_blur_rgb, 0, 1.0)
image_f32 = image.astype(np.float32)
image_f32 = (
(1 - noise_small_blur_rgb) * image_f32
+ noise_small_blur_rgb * drop_mean_color
)
return np.clip(image_f32, 0, 255).astype(np.uint8)
[docs]class Rain(meta.SomeOf):
"""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``).
"""
# Added in 0.4.0.
def __init__(self, nb_iterations=(1, 3),
drop_size=(0.01, 0.02),
speed=(0.04, 0.20),
seed=None, name=None,
random_state="deprecated", deterministic="deprecated"):
layer = RainLayer(
density=(0.03, 0.14),
density_uniformity=(0.8, 1.0),
drop_size=drop_size,
drop_size_uniformity=(0.2, 0.5),
angle=(-15, 15),
speed=speed,
blur_sigma_fraction=(0.001, 0.001),
seed=seed,
random_state=random_state,
deterministic=deterministic
)
super(Rain, self).__init__(
nb_iterations,
children=[layer.deepcopy() for _ in range(3)],
random_order=False,
seed=seed, name=name,
random_state=random_state, deterministic=deterministic)