weather.py 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. """
  2. Augmenters that create weather effects.
  3. List of augmenters:
  4. * :class:`FastSnowyLandscape`
  5. * :class:`CloudLayer`
  6. * :class:`Clouds`
  7. * :class:`Fog`
  8. * :class:`SnowflakesLayer`
  9. * :class:`Snowflakes`
  10. * :class:`RainLayer`
  11. * :class:`Rain`
  12. """
  13. from __future__ import print_function, division, absolute_import
  14. import numpy as np
  15. import imgaug as ia
  16. from . import meta, arithmetic, blur, contrast, color as colorlib
  17. from .. import parameters as iap
  18. from .. import dtypes as iadt
  19. class FastSnowyLandscape(meta.Augmenter):
  20. """Convert non-snowy landscapes to snowy ones.
  21. This augmenter expects to get an image that roughly shows a landscape.
  22. This augmenter is based on the method proposed in
  23. https://medium.freecodecamp.org/image-augmentation-make-it-rain-make-it-snow-how-to-modify-a-photo-with-machine-learning-163c0cb3843f?gi=bca4a13e634c
  24. **Supported dtypes**:
  25. * ``uint8``: yes; fully tested
  26. * ``uint16``: no (1)
  27. * ``uint32``: no (1)
  28. * ``uint64``: no (1)
  29. * ``int8``: no (1)
  30. * ``int16``: no (1)
  31. * ``int32``: no (1)
  32. * ``int64``: no (1)
  33. * ``float16``: no (1)
  34. * ``float32``: no (1)
  35. * ``float64``: no (1)
  36. * ``float128``: no (1)
  37. * ``bool``: no (1)
  38. - (1) This augmenter is based on a colorspace conversion to HLS.
  39. Hence, only RGB ``uint8`` inputs are sensible.
  40. Parameters
  41. ----------
  42. lightness_threshold : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
  43. All pixels with lightness in HLS colorspace that is below this value
  44. will have their lightness increased by `lightness_multiplier`.
  45. * If a ``number``, then that value will always be used.
  46. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  47. per image from the discrete interval ``[a..b]``.
  48. * If a ``list``, then a random value will be sampled from that
  49. ``list`` per image.
  50. * If a ``StochasticParameter``, then a value will be sampled
  51. per image from that parameter.
  52. lightness_multiplier : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
  53. Multiplier for pixel's lightness value in HLS colorspace.
  54. Affects all pixels selected via `lightness_threshold`.
  55. * If a ``number``, then that value will always be used.
  56. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  57. per image from the discrete interval ``[a..b]``.
  58. * If a ``list``, then a random value will be sampled from that
  59. ``list`` per image.
  60. * If a ``StochasticParameter``, then a value will be sampled
  61. per image from that parameter.
  62. from_colorspace : str, optional
  63. The source colorspace of the input images.
  64. See :func:`~imgaug.augmenters.color.ChangeColorspace.__init__`.
  65. 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
  66. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  67. name : None or str, optional
  68. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  69. 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
  70. Old name for parameter `seed`.
  71. Its usage will not yet cause a deprecation warning,
  72. but it is still recommended to use `seed` now.
  73. Outdated since 0.4.0.
  74. deterministic : bool, optional
  75. Deprecated since 0.4.0.
  76. See method ``to_deterministic()`` for an alternative and for
  77. details about what the "deterministic mode" actually does.
  78. Examples
  79. --------
  80. >>> import imgaug.augmenters as iaa
  81. >>> aug = iaa.FastSnowyLandscape(
  82. >>> lightness_threshold=140,
  83. >>> lightness_multiplier=2.5
  84. >>> )
  85. Search for all pixels in the image with a lightness value in HLS
  86. colorspace of less than ``140`` and increase their lightness by a factor
  87. of ``2.5``.
  88. >>> aug = iaa.FastSnowyLandscape(
  89. >>> lightness_threshold=[128, 200],
  90. >>> lightness_multiplier=(1.5, 3.5)
  91. >>> )
  92. Search for all pixels in the image with a lightness value in HLS
  93. colorspace of less than ``128`` or less than ``200`` (one of these
  94. values is picked per image) and multiply their lightness by a factor
  95. of ``x`` with ``x`` being sampled from ``uniform(1.5, 3.5)`` (once per
  96. image).
  97. >>> aug = iaa.FastSnowyLandscape(
  98. >>> lightness_threshold=(100, 255),
  99. >>> lightness_multiplier=(1.0, 4.0)
  100. >>> )
  101. Similar to the previous example, but the lightness threshold is sampled
  102. from ``uniform(100, 255)`` (per image) and the multiplier
  103. from ``uniform(1.0, 4.0)`` (per image). This seems to produce good and
  104. varied results.
  105. """
  106. def __init__(self, lightness_threshold=(100, 255),
  107. lightness_multiplier=(1.0, 4.0),
  108. from_colorspace=colorlib.CSPACE_RGB,
  109. seed=None, name=None,
  110. random_state="deprecated", deterministic="deprecated"):
  111. super(FastSnowyLandscape, self).__init__(
  112. seed=seed, name=name,
  113. random_state=random_state, deterministic=deterministic)
  114. self.lightness_threshold = iap.handle_continuous_param(
  115. lightness_threshold, "lightness_threshold",
  116. value_range=(0, 255), tuple_to_uniform=True, list_to_choice=True)
  117. self.lightness_multiplier = iap.handle_continuous_param(
  118. lightness_multiplier, "lightness_multiplier",
  119. value_range=(0, None), tuple_to_uniform=True, list_to_choice=True)
  120. self.from_colorspace = from_colorspace
  121. def _draw_samples(self, augmentables, random_state):
  122. nb_augmentables = len(augmentables)
  123. rss = random_state.duplicate(2)
  124. thresh_samples = self.lightness_threshold.draw_samples(
  125. (nb_augmentables,), rss[1])
  126. lmul_samples = self.lightness_multiplier.draw_samples(
  127. (nb_augmentables,), rss[0])
  128. return thresh_samples, lmul_samples
  129. # Added in 0.4.0.
  130. def _augment_batch_(self, batch, random_state, parents, hooks):
  131. if batch.images is None:
  132. return batch
  133. images = batch.images
  134. thresh_samples, lmul_samples = self._draw_samples(images, random_state)
  135. gen = enumerate(zip(images, thresh_samples, lmul_samples))
  136. for i, (image, thresh, lmul) in gen:
  137. image_hls = colorlib.change_colorspace_(
  138. image, colorlib.CSPACE_HLS, self.from_colorspace)
  139. cvt_dtype = image_hls.dtype
  140. image_hls = image_hls.astype(np.float64)
  141. lightness = image_hls[..., 1]
  142. lightness[lightness < thresh] *= lmul
  143. image_hls = iadt.restore_dtypes_(image_hls, cvt_dtype)
  144. image_rgb = colorlib.change_colorspace_(
  145. image_hls, self.from_colorspace, colorlib.CSPACE_HLS)
  146. batch.images[i] = image_rgb
  147. return batch
  148. def get_parameters(self):
  149. """See :func:`~imgaug.augmenters.meta.Augmenter.get_parameters`."""
  150. return [self.lightness_threshold, self.lightness_multiplier]
  151. # TODO add examples and add these to the overview docs
  152. # TODO add perspective transform to each cloud layer to make them look more
  153. # distant?
  154. # TODO alpha_mean and density overlap - remove one of them
  155. class CloudLayer(meta.Augmenter):
  156. """Add a single layer of clouds to an image.
  157. **Supported dtypes**:
  158. * ``uint8``: yes; indirectly tested (1)
  159. * ``uint16``: no
  160. * ``uint32``: no
  161. * ``uint64``: no
  162. * ``int8``: no
  163. * ``int16``: no
  164. * ``int32``: no
  165. * ``int64``: no
  166. * ``float16``: yes; not tested
  167. * ``float32``: yes; not tested
  168. * ``float64``: yes; not tested
  169. * ``float128``: yes; not tested (2)
  170. * ``bool``: no
  171. - (1) Indirectly tested via tests for :class:`Clouds`` and :class:`Fog`
  172. - (2) Note that random values are usually sampled as ``int64`` or
  173. ``float64``, which ``float128`` images would exceed. Note also
  174. that random values might have to upscaled, which is done
  175. via :func:`~imgaug.imgaug.imresize_many_images` and has its own
  176. limited dtype support (includes however floats up to ``64bit``).
  177. Parameters
  178. ----------
  179. intensity_mean : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  180. Mean intensity of the clouds (i.e. mean color).
  181. Recommended to be in the interval ``[190, 255]``.
  182. * If a ``number``, then that value will always be used.
  183. * If a ``tuple`` ``(a, b)``, then a value will be uniformly
  184. sampled per image from the interval ``[a, b]``.
  185. * If a ``list``, then a random value will be sampled from that
  186. ``list`` per image.
  187. * If a ``StochasticParameter``, then a value will be sampled
  188. per image from that parameter.
  189. intensity_freq_exponent : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  190. Exponent of the frequency noise used to add fine intensity to the
  191. mean intensity.
  192. Recommended to be in the interval ``[-2.5, -1.5]``.
  193. See :func:`~imgaug.parameters.FrequencyNoise.__init__` for details.
  194. intensity_coarse_scale : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  195. Standard deviation of the gaussian distribution used to add more
  196. localized intensity to the mean intensity. Sampled in low resolution
  197. space, i.e. affects final intensity on a coarse level.
  198. Recommended to be in the interval ``(0, 10]``.
  199. * If a ``number``, then that value will always be used.
  200. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  201. per image from the interval ``[a, b]``.
  202. * If a ``list``, then a random value will be sampled from that
  203. ``list`` per image.
  204. * If a ``StochasticParameter``, then a value will be sampled
  205. per image from that parameter.
  206. alpha_min : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  207. Minimum alpha when blending cloud noise with the image.
  208. High values will lead to clouds being "everywhere".
  209. Recommended to usually be at around ``0.0`` for clouds and ``>0`` for
  210. fog.
  211. * If a ``number``, then that value will always be used.
  212. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  213. per image from the interval ``[a, b]``.
  214. * If a ``list``, then a random value will be sampled from that
  215. ``list`` per image.
  216. * If a ``StochasticParameter``, then a value will be sampled
  217. per image from that parameter.
  218. alpha_multiplier : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  219. Multiplier for the sampled alpha values. High values will lead to
  220. denser clouds wherever they are visible.
  221. Recommended to be in the interval ``[0.3, 1.0]``.
  222. Note that this parameter currently overlaps with `density_multiplier`,
  223. which is applied a bit later to the alpha mask.
  224. * If a ``number``, then that value will always be used.
  225. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  226. per image from the interval ``[a, b]``.
  227. * If a ``list``, then a random value will be sampled from that
  228. ``list`` per image.
  229. * If a ``StochasticParameter``, then a value will be sampled
  230. per image from that parameter.
  231. alpha_size_px_max : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  232. Controls the image size at which the alpha mask is sampled.
  233. Lower values will lead to coarser alpha masks and hence larger
  234. clouds (and empty areas).
  235. See :func:`~imgaug.parameters.FrequencyNoise.__init__` for details.
  236. alpha_freq_exponent : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  237. Exponent of the frequency noise used to sample the alpha mask.
  238. Similarly to `alpha_size_max_px`, lower values will lead to coarser
  239. alpha patterns.
  240. Recommended to be in the interval ``[-4.0, -1.5]``.
  241. See :func:`~imgaug.parameters.FrequencyNoise.__init__` for details.
  242. sparsity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  243. Exponent applied late to the alpha mask. Lower values will lead to
  244. coarser cloud patterns, higher values to finer patterns.
  245. Recommended to be somewhere around ``1.0``.
  246. Do not deviate far from that value, otherwise the alpha mask might
  247. get weird patterns with sudden fall-offs to zero that look very
  248. unnatural.
  249. * If a ``number``, then that value will always be used.
  250. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  251. per image from the interval ``[a, b]``.
  252. * If a ``list``, then a random value will be sampled from that
  253. ``list`` per image.
  254. * If a ``StochasticParameter``, then a value will be sampled
  255. per image from that parameter.
  256. density_multiplier : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  257. Late multiplier for the alpha mask, similar to `alpha_multiplier`.
  258. Set this higher to get "denser" clouds wherever they are visible.
  259. Recommended to be around ``[0.5, 1.5]``.
  260. * If a ``number``, then that value will always be used.
  261. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  262. per image from the interval ``[a, b]``.
  263. * If a ``list``, then a random value will be sampled from that
  264. ``list`` per image.
  265. * If a ``StochasticParameter``, then a value will be sampled
  266. per image from that parameter.
  267. 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
  268. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  269. name : None or str, optional
  270. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  271. 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
  272. Old name for parameter `seed`.
  273. Its usage will not yet cause a deprecation warning,
  274. but it is still recommended to use `seed` now.
  275. Outdated since 0.4.0.
  276. deterministic : bool, optional
  277. Deprecated since 0.4.0.
  278. See method ``to_deterministic()`` for an alternative and for
  279. details about what the "deterministic mode" actually does.
  280. """
  281. def __init__(self, intensity_mean, intensity_freq_exponent,
  282. intensity_coarse_scale, alpha_min, alpha_multiplier,
  283. alpha_size_px_max, alpha_freq_exponent, sparsity,
  284. density_multiplier,
  285. seed=None, name=None,
  286. random_state="deprecated", deterministic="deprecated"):
  287. super(CloudLayer, self).__init__(
  288. seed=seed, name=name,
  289. random_state=random_state, deterministic=deterministic)
  290. self.intensity_mean = iap.handle_continuous_param(
  291. intensity_mean, "intensity_mean")
  292. self.intensity_freq_exponent = intensity_freq_exponent
  293. self.intensity_coarse_scale = intensity_coarse_scale
  294. self.alpha_min = iap.handle_continuous_param(alpha_min, "alpha_min")
  295. self.alpha_multiplier = iap.handle_continuous_param(
  296. alpha_multiplier, "alpha_multiplier")
  297. self.alpha_size_px_max = alpha_size_px_max
  298. self.alpha_freq_exponent = alpha_freq_exponent
  299. self.sparsity = iap.handle_continuous_param(sparsity, "sparsity")
  300. self.density_multiplier = iap.handle_continuous_param(
  301. density_multiplier, "density_multiplier")
  302. # Added in 0.4.0.
  303. def _augment_batch_(self, batch, random_state, parents, hooks):
  304. if batch.images is None:
  305. return batch
  306. images = batch.images
  307. rss = random_state.duplicate(len(images))
  308. for i, (image, rs) in enumerate(zip(images, rss)):
  309. batch.images[i] = self.draw_on_image(image, rs)
  310. return batch
  311. def get_parameters(self):
  312. """See :func:`~imgaug.augmenters.meta.Augmenter.get_parameters`."""
  313. return [self.intensity_mean,
  314. self.alpha_min,
  315. self.alpha_multiplier,
  316. self.alpha_size_px_max,
  317. self.alpha_freq_exponent,
  318. self.intensity_freq_exponent,
  319. self.sparsity,
  320. self.density_multiplier,
  321. self.intensity_coarse_scale]
  322. def draw_on_image(self, image, random_state):
  323. iadt.gate_dtypes(image,
  324. allowed=["uint8",
  325. "float16", "float32", "float64",
  326. "float96", "float128", "float256"],
  327. disallowed=["bool",
  328. "uint16", "uint32", "uint64", "uint128",
  329. "uint256",
  330. "int8", "int16", "int32", "int64",
  331. "int128", "int256"])
  332. alpha, intensity = self.generate_maps(image, random_state)
  333. alpha = alpha[..., np.newaxis]
  334. intensity = intensity[..., np.newaxis]
  335. if image.dtype.kind == "f":
  336. intensity = intensity.astype(image.dtype)
  337. return (1 - alpha) * image + alpha * intensity
  338. intensity = np.clip(intensity, 0, 255)
  339. # TODO use blend_alpha_() here
  340. return np.clip(
  341. (1 - alpha) * image.astype(alpha.dtype)
  342. + alpha * intensity.astype(alpha.dtype),
  343. 0,
  344. 255
  345. ).astype(np.uint8)
  346. def generate_maps(self, image, random_state):
  347. intensity_mean_sample = self.intensity_mean.draw_sample(random_state)
  348. alpha_min_sample = self.alpha_min.draw_sample(random_state)
  349. alpha_multiplier_sample = \
  350. self.alpha_multiplier.draw_sample(random_state)
  351. alpha_size_px_max = self.alpha_size_px_max
  352. intensity_freq_exponent = self.intensity_freq_exponent
  353. alpha_freq_exponent = self.alpha_freq_exponent
  354. sparsity_sample = self.sparsity.draw_sample(random_state)
  355. density_multiplier_sample = \
  356. self.density_multiplier.draw_sample(random_state)
  357. height, width = image.shape[0:2]
  358. rss_alpha, rss_intensity = random_state.duplicate(2)
  359. intensity_coarse = self._generate_intensity_map_coarse(
  360. height, width, intensity_mean_sample,
  361. iap.Normal(0, scale=self.intensity_coarse_scale),
  362. rss_intensity
  363. )
  364. intensity_fine = self._generate_intensity_map_fine(
  365. height, width, intensity_mean_sample, intensity_freq_exponent,
  366. rss_intensity)
  367. intensity = intensity_coarse + intensity_fine
  368. alpha = self._generate_alpha_mask(
  369. height, width, alpha_min_sample, alpha_multiplier_sample,
  370. alpha_freq_exponent, alpha_size_px_max, sparsity_sample,
  371. density_multiplier_sample, rss_alpha)
  372. return alpha, intensity
  373. @classmethod
  374. def _generate_intensity_map_coarse(cls, height, width, intensity_mean,
  375. intensity_local_offset, random_state):
  376. # TODO (8, 8) might be too simplistic for some image sizes
  377. height_intensity, width_intensity = (8, 8)
  378. intensity = (
  379. intensity_mean
  380. + intensity_local_offset.draw_samples(
  381. (height_intensity, width_intensity), random_state)
  382. )
  383. intensity = ia.imresize_single_image(
  384. intensity, (height, width), interpolation="cubic")
  385. return intensity
  386. @classmethod
  387. def _generate_intensity_map_fine(cls, height, width, intensity_mean,
  388. exponent, random_state):
  389. intensity_details_generator = iap.FrequencyNoise(
  390. exponent=exponent,
  391. size_px_max=max(height, width, 1), # 1 here for case H, W being 0
  392. upscale_method="cubic"
  393. )
  394. intensity_details = intensity_details_generator.draw_samples(
  395. (height, width), random_state)
  396. return intensity_mean * ((2*intensity_details - 1.0)/5.0)
  397. @classmethod
  398. def _generate_alpha_mask(cls, height, width, alpha_min, alpha_multiplier,
  399. exponent, alpha_size_px_max, sparsity,
  400. density_multiplier, random_state):
  401. alpha_generator = iap.FrequencyNoise(
  402. exponent=exponent,
  403. size_px_max=alpha_size_px_max,
  404. upscale_method="cubic"
  405. )
  406. alpha_local = alpha_generator.draw_samples(
  407. (height, width), random_state)
  408. alpha = alpha_min + (alpha_multiplier * alpha_local)
  409. alpha = (alpha ** sparsity) * density_multiplier
  410. alpha = np.clip(alpha, 0.0, 1.0)
  411. return alpha
  412. # TODO add vertical gradient alpha to have clouds only at skylevel/groundlevel
  413. # TODO add configurable parameters
  414. class Clouds(meta.SomeOf):
  415. """
  416. Add clouds to images.
  417. This is a wrapper around :class:`~imgaug.augmenters.weather.CloudLayer`.
  418. It executes 1 to 2 layers per image, leading to varying densities and
  419. frequency patterns of clouds.
  420. This augmenter seems to be fairly robust w.r.t. the image size. Tested
  421. with ``96x128``, ``192x256`` and ``960x1280``.
  422. **Supported dtypes**:
  423. * ``uint8``: yes; tested
  424. * ``uint16``: no (1)
  425. * ``uint32``: no (1)
  426. * ``uint64``: no (1)
  427. * ``int8``: no (1)
  428. * ``int16``: no (1)
  429. * ``int32``: no (1)
  430. * ``int64``: no (1)
  431. * ``float16``: no (1)
  432. * ``float32``: no (1)
  433. * ``float64``: no (1)
  434. * ``float128``: no (1)
  435. * ``bool``: no (1)
  436. - (1) Parameters of this augmenter are optimized for the value range
  437. of ``uint8``. While other dtypes may be accepted, they will lead
  438. to images augmented in ways inappropriate for the respective
  439. dtype.
  440. Parameters
  441. ----------
  442. 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
  443. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  444. name : None or str, optional
  445. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  446. 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
  447. Old name for parameter `seed`.
  448. Its usage will not yet cause a deprecation warning,
  449. but it is still recommended to use `seed` now.
  450. Outdated since 0.4.0.
  451. deterministic : bool, optional
  452. Deprecated since 0.4.0.
  453. See method ``to_deterministic()`` for an alternative and for
  454. details about what the "deterministic mode" actually does.
  455. Examples
  456. --------
  457. >>> import imgaug.augmenters as iaa
  458. >>> aug = iaa.Clouds()
  459. Create an augmenter that adds clouds to images.
  460. """
  461. def __init__(self,
  462. seed=None, name=None,
  463. random_state="deprecated", deterministic="deprecated"):
  464. layers = [
  465. CloudLayer(
  466. intensity_mean=(196, 255),
  467. intensity_freq_exponent=(-2.5, -2.0),
  468. intensity_coarse_scale=10,
  469. alpha_min=0,
  470. alpha_multiplier=(0.25, 0.75),
  471. alpha_size_px_max=(2, 8),
  472. alpha_freq_exponent=(-2.5, -2.0),
  473. sparsity=(0.8, 1.0),
  474. density_multiplier=(0.5, 1.0),
  475. seed=seed,
  476. random_state=random_state,
  477. deterministic=deterministic
  478. ),
  479. CloudLayer(
  480. intensity_mean=(196, 255),
  481. intensity_freq_exponent=(-2.0, -1.0),
  482. intensity_coarse_scale=10,
  483. alpha_min=0,
  484. alpha_multiplier=(0.5, 1.0),
  485. alpha_size_px_max=(64, 128),
  486. alpha_freq_exponent=(-2.0, -1.0),
  487. sparsity=(1.0, 1.4),
  488. density_multiplier=(0.8, 1.5),
  489. seed=seed,
  490. random_state=random_state,
  491. deterministic=deterministic
  492. )
  493. ]
  494. super(Clouds, self).__init__(
  495. (1, 2),
  496. children=layers,
  497. random_order=False,
  498. seed=seed, name=name,
  499. random_state=random_state, deterministic=deterministic)
  500. # TODO add vertical gradient alpha to have fog only at skylevel/groundlevel
  501. # TODO add configurable parameters
  502. class Fog(CloudLayer):
  503. """Add fog to images.
  504. This is a wrapper around :class:`~imgaug.augmenters.weather.CloudLayer`.
  505. It executes a single layer per image with a configuration leading to
  506. fairly dense clouds with low-frequency patterns.
  507. This augmenter seems to be fairly robust w.r.t. the image size. Tested
  508. with ``96x128``, ``192x256`` and ``960x1280``.
  509. **Supported dtypes**:
  510. * ``uint8``: yes; tested
  511. * ``uint16``: no (1)
  512. * ``uint32``: no (1)
  513. * ``uint64``: no (1)
  514. * ``int8``: no (1)
  515. * ``int16``: no (1)
  516. * ``int32``: no (1)
  517. * ``int64``: no (1)
  518. * ``float16``: no (1)
  519. * ``float32``: no (1)
  520. * ``float64``: no (1)
  521. * ``float128``: no (1)
  522. * ``bool``: no (1)
  523. - (1) Parameters of this augmenter are optimized for the value range
  524. of ``uint8``. While other dtypes may be accepted, they will lead
  525. to images augmented in ways inappropriate for the respective
  526. dtype.
  527. Parameters
  528. ----------
  529. 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
  530. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  531. name : None or str, optional
  532. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  533. 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
  534. Old name for parameter `seed`.
  535. Its usage will not yet cause a deprecation warning,
  536. but it is still recommended to use `seed` now.
  537. Outdated since 0.4.0.
  538. deterministic : bool, optional
  539. Deprecated since 0.4.0.
  540. See method ``to_deterministic()`` for an alternative and for
  541. details about what the "deterministic mode" actually does.
  542. Examples
  543. --------
  544. >>> import imgaug.augmenters as iaa
  545. >>> aug = iaa.Fog()
  546. Create an augmenter that adds fog to images.
  547. """
  548. def __init__(self,
  549. seed=None, name=None,
  550. random_state="deprecated", deterministic="deprecated"):
  551. super(Fog, self).__init__(
  552. intensity_mean=(220, 255),
  553. intensity_freq_exponent=(-2.0, -1.5),
  554. intensity_coarse_scale=2,
  555. alpha_min=(0.7, 0.9),
  556. alpha_multiplier=0.3,
  557. alpha_size_px_max=(2, 8),
  558. alpha_freq_exponent=(-4.0, -2.0),
  559. sparsity=0.9,
  560. density_multiplier=(0.4, 0.9),
  561. seed=seed, name=name,
  562. random_state=random_state, deterministic=deterministic)
  563. # TODO add examples and add these to the overview docs
  564. # TODO snowflakes are all almost 100% white, add some grayish tones and
  565. # maybe color to them
  566. class SnowflakesLayer(meta.Augmenter):
  567. """Add a single layer of falling snowflakes to images.
  568. **Supported dtypes**:
  569. * ``uint8``: yes; indirectly tested (1)
  570. * ``uint16``: no
  571. * ``uint32``: no
  572. * ``uint64``: no
  573. * ``int8``: no
  574. * ``int16``: no
  575. * ``int32``: no
  576. * ``int64``: no
  577. * ``float16``: no
  578. * ``float32``: no
  579. * ``float64``: no
  580. * ``float128``: no
  581. * ``bool``: no
  582. - (1) indirectly tested via tests for :class:`Snowflakes`
  583. Parameters
  584. ----------
  585. density : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  586. Density of the snowflake layer, as a probability of each pixel in
  587. low resolution space to be a snowflake.
  588. Valid values are in the interval ``[0.0, 1.0]``.
  589. Recommended to be in the interval ``[0.01, 0.075]``.
  590. * If a ``number``, then that value will always be used.
  591. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  592. per image from the interval ``[a, b]``.
  593. * If a ``list``, then a random value will be sampled from that
  594. ``list`` per image.
  595. * If a ``StochasticParameter``, then a value will be sampled
  596. per image from that parameter.
  597. density_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  598. Size uniformity of the snowflakes. Higher values denote more
  599. similarly sized snowflakes.
  600. Valid values are in the interval ``[0.0, 1.0]``.
  601. Recommended to be around ``0.5``.
  602. * If a ``number``, then that value will always be used.
  603. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  604. per image from the interval ``[a, b]``.
  605. * If a ``list``, then a random value will be sampled from that
  606. ``list`` per image.
  607. * If a ``StochasticParameter``, then a value will be sampled
  608. per image from that parameter.
  609. flake_size : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  610. Size of the snowflakes. This parameter controls the resolution at
  611. which snowflakes are sampled. Higher values mean that the resolution
  612. is closer to the input image's resolution and hence each sampled
  613. snowflake will be smaller (because of the smaller pixel size).
  614. Valid values are in the interval ``(0.0, 1.0]``.
  615. Recommended values:
  616. * On 96x128 a value of ``(0.1, 0.4)`` worked well.
  617. * On 192x256 a value of ``(0.2, 0.7)`` worked well.
  618. * On 960x1280 a value of ``(0.7, 0.95)`` worked well.
  619. Datatype behaviour:
  620. * If a ``number``, then that value will always be used.
  621. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  622. per image from the interval ``[a, b]``.
  623. * If a ``list``, then a random value will be sampled from that
  624. ``list`` per image.
  625. * If a ``StochasticParameter``, then a value will be sampled
  626. per image from that parameter.
  627. flake_size_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  628. Controls the size uniformity of the snowflakes. Higher values mean
  629. that the snowflakes are more similarly sized.
  630. Valid values are in the interval ``[0.0, 1.0]``.
  631. Recommended to be around ``0.5``.
  632. * If a ``number``, then that value will always be used.
  633. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  634. per image from the interval ``[a, b]``.
  635. * If a ``list``, then a random value will be sampled from that
  636. ``list`` per image.
  637. * If a ``StochasticParameter``, then a value will be sampled
  638. per image from that parameter.
  639. angle : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  640. Angle in degrees of motion blur applied to the snowflakes, where
  641. ``0.0`` is motion blur that points straight upwards.
  642. Recommended to be in the interval ``[-30, 30]``.
  643. See also :func:`~imgaug.augmenters.blur.MotionBlur.__init__`.
  644. * If a ``number``, then that value will always be used.
  645. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  646. per image from the interval ``[a, b]``.
  647. * If a ``list``, then a random value will be sampled from that
  648. ``list`` per image.
  649. * If a ``StochasticParameter``, then a value will be sampled
  650. per image from that parameter.
  651. speed : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  652. Perceived falling speed of the snowflakes. This parameter controls the
  653. motion blur's kernel size. It follows roughly the form
  654. ``kernel_size = image_size * speed``. Hence, values around ``1.0``
  655. denote that the motion blur should "stretch" each snowflake over the
  656. whole image.
  657. Valid values are in the interval ``[0.0, 1.0]``.
  658. Recommended values:
  659. * On 96x128 a value of ``(0.01, 0.05)`` worked well.
  660. * On 192x256 a value of ``(0.007, 0.03)`` worked well.
  661. * On 960x1280 a value of ``(0.001, 0.03)`` worked well.
  662. Datatype behaviour:
  663. * If a ``number``, then that value will always be used.
  664. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  665. per image from the interval ``[a, b]``.
  666. * If a ``list``, then a random value will be sampled from that
  667. ``list`` per image.
  668. * If a ``StochasticParameter``, then a value will be sampled
  669. per image from that parameter.
  670. blur_sigma_fraction : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  671. Standard deviation (as a fraction of the image size) of gaussian blur
  672. applied to the snowflakes.
  673. Valid values are in the interval ``[0.0, 1.0]``.
  674. Recommended to be in the interval ``[0.0001, 0.001]``. May still
  675. require tinkering based on image size.
  676. * If a ``number``, then that value will always be used.
  677. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  678. per image from the interval ``[a, b]``.
  679. * If a ``list``, then a random value will be sampled from that
  680. ``list`` per image.
  681. * If a ``StochasticParameter``, then a value will be sampled
  682. per image from that parameter.
  683. blur_sigma_limits : tuple of float, optional
  684. Controls allowed min and max values of `blur_sigma_fraction`
  685. after(!) multiplication with the image size. First value is the
  686. minimum, second value is the maximum. Values outside of that range
  687. will be clipped to be within that range. This prevents extreme
  688. values for very small or large images.
  689. 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
  690. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  691. name : None or str, optional
  692. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  693. 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
  694. Old name for parameter `seed`.
  695. Its usage will not yet cause a deprecation warning,
  696. but it is still recommended to use `seed` now.
  697. Outdated since 0.4.0.
  698. deterministic : bool, optional
  699. Deprecated since 0.4.0.
  700. See method ``to_deterministic()`` for an alternative and for
  701. details about what the "deterministic mode" actually does.
  702. """
  703. def __init__(self, density, density_uniformity, flake_size,
  704. flake_size_uniformity, angle, speed, blur_sigma_fraction,
  705. blur_sigma_limits=(0.5, 3.75),
  706. seed=None, name=None,
  707. random_state="deprecated", deterministic="deprecated"):
  708. super(SnowflakesLayer, self).__init__(
  709. seed=seed, name=name,
  710. random_state=random_state, deterministic=deterministic)
  711. self.density = density
  712. self.density_uniformity = iap.handle_continuous_param(
  713. density_uniformity, "density_uniformity", value_range=(0.0, 1.0))
  714. self.flake_size = iap.handle_continuous_param(
  715. flake_size, "flake_size", value_range=(0.0+1e-4, 1.0))
  716. self.flake_size_uniformity = iap.handle_continuous_param(
  717. flake_size_uniformity, "flake_size_uniformity",
  718. value_range=(0.0, 1.0))
  719. self.angle = iap.handle_continuous_param(angle, "angle")
  720. self.speed = iap.handle_continuous_param(
  721. speed, "speed", value_range=(0.0, 1.0))
  722. self.blur_sigma_fraction = iap.handle_continuous_param(
  723. blur_sigma_fraction, "blur_sigma_fraction", value_range=(0.0, 1.0))
  724. # (min, max), same for all images
  725. self.blur_sigma_limits = blur_sigma_limits
  726. # (height, width), same for all images
  727. self.gate_noise_size = (8, 8)
  728. # Added in 0.4.0.
  729. def _augment_batch_(self, batch, random_state, parents, hooks):
  730. if batch.images is None:
  731. return batch
  732. images = batch.images
  733. rss = random_state.duplicate(len(images))
  734. for i, (image, rs) in enumerate(zip(images, rss)):
  735. batch.images[i] = self.draw_on_image(image, rs)
  736. return batch
  737. def get_parameters(self):
  738. """See :func:`~imgaug.augmenters.meta.Augmenter.get_parameters`."""
  739. return [self.density,
  740. self.density_uniformity,
  741. self.flake_size,
  742. self.flake_size_uniformity,
  743. self.angle,
  744. self.speed,
  745. self.blur_sigma_fraction,
  746. self.blur_sigma_limits,
  747. self.gate_noise_size]
  748. def draw_on_image(self, image, random_state):
  749. assert image.ndim == 3, (
  750. "Expected input image to be three-dimensional, "
  751. "got %d dimensions." % (image.ndim,))
  752. assert image.shape[2] in [1, 3], (
  753. "Expected to get image with a channel axis of size 1 or 3, "
  754. "got %d (shape: %s)" % (image.shape[2], image.shape))
  755. rss = random_state.duplicate(2)
  756. flake_size_sample = self.flake_size.draw_sample(random_state)
  757. flake_size_uniformity_sample = self.flake_size_uniformity.draw_sample(
  758. random_state)
  759. angle_sample = self.angle.draw_sample(random_state)
  760. speed_sample = self.speed.draw_sample(random_state)
  761. blur_sigma_fraction_sample = self.blur_sigma_fraction.draw_sample(
  762. random_state)
  763. height, width, nb_channels = image.shape
  764. downscale_factor = np.clip(1.0 - flake_size_sample, 0.001, 1.0)
  765. height_down = max(1, int(height*downscale_factor))
  766. width_down = max(1, int(width*downscale_factor))
  767. noise = self._generate_noise(
  768. height_down,
  769. width_down,
  770. self.density,
  771. rss[0]
  772. )
  773. # gate the sampled noise via noise in range [0.0, 1.0]
  774. # this leads to less flakes in some areas of the image and more in
  775. # other areas
  776. gate_noise = iap.Beta(1.0, 1.0 - self.density_uniformity)
  777. noise = self._gate(noise, gate_noise, self.gate_noise_size, rss[1])
  778. noise = ia.imresize_single_image(noise, (height, width),
  779. interpolation="cubic")
  780. # apply a bit of gaussian blur and then motion blur according to
  781. # angle and speed
  782. sigma = max(height, width) * blur_sigma_fraction_sample
  783. sigma = np.clip(sigma,
  784. self.blur_sigma_limits[0], self.blur_sigma_limits[1])
  785. noise_small_blur = self._blur(noise, sigma)
  786. noise_small_blur = self._motion_blur(noise_small_blur,
  787. angle=angle_sample,
  788. speed=speed_sample,
  789. random_state=random_state)
  790. noise_small_blur_rgb = self._postprocess_noise(
  791. noise_small_blur, flake_size_uniformity_sample, nb_channels)
  792. return self._blend(image, speed_sample, noise_small_blur_rgb)
  793. @classmethod
  794. def _generate_noise(cls, height, width, density, random_state):
  795. noise = arithmetic.Salt(p=density, random_state=random_state)
  796. return noise.augment_image(np.zeros((height, width), dtype=np.uint8))
  797. @classmethod
  798. def _gate(cls, noise, gate_noise, gate_size, random_state):
  799. # the beta distribution here has most of its weight around 1.0 and
  800. # will only rarely sample values around 0.0 the average of the
  801. # sampled values seems to be at around 0.6-0.75
  802. gate_noise = gate_noise.draw_samples(gate_size, random_state)
  803. gate_noise_up = ia.imresize_single_image(gate_noise, noise.shape[0:2],
  804. interpolation="cubic")
  805. gate_noise_up = np.clip(gate_noise_up, 0.0, 1.0)
  806. return np.clip(
  807. noise.astype(np.float32) * gate_noise_up, 0, 255
  808. ).astype(np.uint8)
  809. @classmethod
  810. def _blur(cls, noise, sigma):
  811. return blur.blur_gaussian_(noise, sigma=sigma)
  812. @classmethod
  813. def _motion_blur(cls, noise, angle, speed, random_state):
  814. size = max(noise.shape[0:2])
  815. k = int(speed * size)
  816. if k <= 1:
  817. return noise
  818. # we use max(k, 3) here because MotionBlur errors for anything less
  819. # than 3
  820. blurer = blur.MotionBlur(
  821. k=max(k, 3), angle=angle, direction=1.0, random_state=random_state)
  822. return blurer.augment_image(noise)
  823. # Added in 0.4.0.
  824. @classmethod
  825. def _postprocess_noise(cls, noise_small_blur,
  826. flake_size_uniformity_sample, nb_channels):
  827. # use contrast adjustment of noise to make the flake size a bit less
  828. # uniform then readjust the noise values to make them more visible
  829. # again
  830. gain = 1.0 + 2*(1 - flake_size_uniformity_sample)
  831. gain_adj = 1.0 + 5*(1 - flake_size_uniformity_sample)
  832. noise_small_blur = contrast.GammaContrast(gain).augment_image(
  833. noise_small_blur)
  834. noise_small_blur = noise_small_blur.astype(np.float32) * gain_adj
  835. noise_small_blur_rgb = np.tile(
  836. noise_small_blur[..., np.newaxis], (1, 1, nb_channels))
  837. return noise_small_blur_rgb
  838. # Added in 0.4.0.
  839. @classmethod
  840. def _blend(cls, image, speed_sample, noise_small_blur_rgb):
  841. # blend:
  842. # sum for a bit of glowy, hardly visible flakes
  843. # max for the main flakes
  844. image_f32 = image.astype(np.float32)
  845. image_f32 = cls._blend_by_sum(
  846. image_f32, (0.1 + 20*speed_sample) * noise_small_blur_rgb)
  847. image_f32 = cls._blend_by_max(
  848. image_f32, (1.0 + 20*speed_sample) * noise_small_blur_rgb)
  849. return image_f32
  850. # TODO replace this by a function from module blend.py
  851. @classmethod
  852. def _blend_by_sum(cls, image_f32, noise_small_blur_rgb):
  853. image_f32 = image_f32 + noise_small_blur_rgb
  854. return np.clip(image_f32, 0, 255).astype(np.uint8)
  855. # TODO replace this by a function from module blend.py
  856. @classmethod
  857. def _blend_by_max(cls, image_f32, noise_small_blur_rgb):
  858. image_f32 = np.maximum(image_f32, noise_small_blur_rgb)
  859. return np.clip(image_f32, 0, 255).astype(np.uint8)
  860. class Snowflakes(meta.SomeOf):
  861. """Add falling snowflakes to images.
  862. This is a wrapper around
  863. :class:`~imgaug.augmenters.weather.SnowflakesLayer`. It executes 1 to 3
  864. layers per image.
  865. **Supported dtypes**:
  866. * ``uint8``: yes; tested
  867. * ``uint16``: no (1)
  868. * ``uint32``: no (1)
  869. * ``uint64``: no (1)
  870. * ``int8``: no (1)
  871. * ``int16``: no (1)
  872. * ``int32``: no (1)
  873. * ``int64``: no (1)
  874. * ``float16``: no (1)
  875. * ``float32``: no (1)
  876. * ``float64``: no (1)
  877. * ``float128``: no (1)
  878. * ``bool``: no (1)
  879. - (1) Parameters of this augmenter are optimized for the value range
  880. of ``uint8``. While other dtypes may be accepted, they will lead
  881. to images augmented in ways inappropriate for the respective
  882. dtype.
  883. Parameters
  884. ----------
  885. density : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  886. Density of the snowflake layer, as a probability of each pixel in
  887. low resolution space to be a snowflake.
  888. Valid values are in the interval ``[0.0, 1.0]``.
  889. Recommended to be in the interval ``[0.01, 0.075]``.
  890. * If a ``number``, then that value will always be used.
  891. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  892. per image from the interval ``[a, b]``.
  893. * If a ``list``, then a random value will be sampled from that
  894. ``list`` per image.
  895. * If a ``StochasticParameter``, then a value will be sampled
  896. per image from that parameter.
  897. density_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  898. Size uniformity of the snowflakes. Higher values denote more
  899. similarly sized snowflakes.
  900. Valid values are in the interval ``[0.0, 1.0]``.
  901. Recommended to be around ``0.5``.
  902. * If a ``number``, then that value will always be used.
  903. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  904. per image from the interval ``[a, b]``.
  905. * If a ``list``, then a random value will be sampled from that
  906. ``list`` per image.
  907. * If a ``StochasticParameter``, then a value will be sampled
  908. per image from that parameter.
  909. flake_size : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  910. Size of the snowflakes. This parameter controls the resolution at
  911. which snowflakes are sampled. Higher values mean that the resolution
  912. is closer to the input image's resolution and hence each sampled
  913. snowflake will be smaller (because of the smaller pixel size).
  914. Valid values are in the interval ``(0.0, 1.0]``.
  915. Recommended values:
  916. * On ``96x128`` a value of ``(0.1, 0.4)`` worked well.
  917. * On ``192x256`` a value of ``(0.2, 0.7)`` worked well.
  918. * On ``960x1280`` a value of ``(0.7, 0.95)`` worked well.
  919. Datatype behaviour:
  920. * If a ``number``, then that value will always be used.
  921. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  922. per image from the interval ``[a, b]``.
  923. * If a ``list``, then a random value will be sampled from that
  924. ``list`` per image.
  925. * If a ``StochasticParameter``, then a value will be sampled
  926. per image from that parameter.
  927. flake_size_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  928. Controls the size uniformity of the snowflakes. Higher values mean
  929. that the snowflakes are more similarly sized.
  930. Valid values are in the interval ``[0.0, 1.0]``.
  931. Recommended to be around ``0.5``.
  932. * If a ``number``, then that value will always be used.
  933. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  934. per image from the interval ``[a, b]``.
  935. * If a ``list``, then a random value will be sampled from that
  936. ``list`` per image.
  937. * If a ``StochasticParameter``, then a value will be sampled
  938. per image from that parameter.
  939. angle : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  940. Angle in degrees of motion blur applied to the snowflakes, where
  941. ``0.0`` is motion blur that points straight upwards.
  942. Recommended to be in the interval ``[-30, 30]``.
  943. See also :func:`~imgaug.augmenters.blur.MotionBlur.__init__`.
  944. * If a ``number``, then that value will always be used.
  945. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  946. per image from the interval ``[a, b]``.
  947. * If a ``list``, then a random value will be sampled from that
  948. ``list`` per image.
  949. * If a ``StochasticParameter``, then a value will be sampled
  950. per image from that parameter.
  951. speed : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  952. Perceived falling speed of the snowflakes. This parameter controls the
  953. motion blur's kernel size. It follows roughly the form
  954. ``kernel_size = image_size * speed``. Hence, values around ``1.0``
  955. denote that the motion blur should "stretch" each snowflake over
  956. the whole image.
  957. Valid values are in the interval ``[0.0, 1.0]``.
  958. Recommended values:
  959. * On ``96x128`` a value of ``(0.01, 0.05)`` worked well.
  960. * On ``192x256`` a value of ``(0.007, 0.03)`` worked well.
  961. * On ``960x1280`` a value of ``(0.001, 0.03)`` worked well.
  962. Datatype behaviour:
  963. * If a ``number``, then that value will always be used.
  964. * If a ``tuple`` ``(a, b)``, then a value will be uniformly sampled
  965. per image from the interval ``[a, b]``.
  966. * If a ``list``, then a random value will be sampled from that
  967. ``list`` per image.
  968. * If a ``StochasticParameter``, then a value will be sampled
  969. per image from that parameter.
  970. 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
  971. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  972. name : None or str, optional
  973. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  974. 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
  975. Old name for parameter `seed`.
  976. Its usage will not yet cause a deprecation warning,
  977. but it is still recommended to use `seed` now.
  978. Outdated since 0.4.0.
  979. deterministic : bool, optional
  980. Deprecated since 0.4.0.
  981. See method ``to_deterministic()`` for an alternative and for
  982. details about what the "deterministic mode" actually does.
  983. Examples
  984. --------
  985. >>> import imgaug.augmenters as iaa
  986. >>> aug = iaa.Snowflakes(flake_size=(0.1, 0.4), speed=(0.01, 0.05))
  987. Add snowflakes to small images (around ``96x128``).
  988. >>> aug = iaa.Snowflakes(flake_size=(0.2, 0.7), speed=(0.007, 0.03))
  989. Add snowflakes to medium-sized images (around ``192x256``).
  990. >>> aug = iaa.Snowflakes(flake_size=(0.7, 0.95), speed=(0.001, 0.03))
  991. Add snowflakes to large images (around ``960x1280``).
  992. """
  993. def __init__(self, density=(0.005, 0.075), density_uniformity=(0.3, 0.9),
  994. flake_size=(0.2, 0.7), flake_size_uniformity=(0.4, 0.8),
  995. angle=(-30, 30), speed=(0.007, 0.03),
  996. seed=None, name=None,
  997. random_state="deprecated", deterministic="deprecated"):
  998. layer = SnowflakesLayer(
  999. density=density,
  1000. density_uniformity=density_uniformity,
  1001. flake_size=flake_size,
  1002. flake_size_uniformity=flake_size_uniformity,
  1003. angle=angle,
  1004. speed=speed,
  1005. blur_sigma_fraction=(0.0001, 0.001),
  1006. seed=seed,
  1007. random_state=random_state,
  1008. deterministic=deterministic
  1009. )
  1010. super(Snowflakes, self).__init__(
  1011. (1, 3),
  1012. children=[layer.deepcopy() for _ in range(3)],
  1013. random_order=False,
  1014. seed=seed, name=name,
  1015. random_state=random_state, deterministic=deterministic)
  1016. class RainLayer(SnowflakesLayer):
  1017. """Add a single layer of falling raindrops to images.
  1018. Added in 0.4.0.
  1019. **Supported dtypes**:
  1020. * ``uint8``: yes; indirectly tested (1)
  1021. * ``uint16``: no
  1022. * ``uint32``: no
  1023. * ``uint64``: no
  1024. * ``int8``: no
  1025. * ``int16``: no
  1026. * ``int32``: no
  1027. * ``int64``: no
  1028. * ``float16``: no
  1029. * ``float32``: no
  1030. * ``float64``: no
  1031. * ``float128``: no
  1032. * ``bool``: no
  1033. - (1) indirectly tested via tests for :class:`Rain`
  1034. Parameters
  1035. ----------
  1036. density : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  1037. Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.
  1038. density_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  1039. Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.
  1040. drop_size : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  1041. Same as `flake_size` in
  1042. :class:`~imgaug.augmenters.weather.SnowflakesLayer`.
  1043. drop_size_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  1044. Same as `flake_size_uniformity` in
  1045. :class:`~imgaug.augmenters.weather.SnowflakesLayer`.
  1046. angle : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  1047. Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.
  1048. speed : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  1049. Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.
  1050. blur_sigma_fraction : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  1051. Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.
  1052. blur_sigma_limits : tuple of float, optional
  1053. Same as in :class:`~imgaug.augmenters.weather.SnowflakesLayer`.
  1054. 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
  1055. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  1056. name : None or str, optional
  1057. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  1058. 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
  1059. Old name for parameter `seed`.
  1060. Its usage will not yet cause a deprecation warning,
  1061. but it is still recommended to use `seed` now.
  1062. Outdated since 0.4.0.
  1063. deterministic : bool, optional
  1064. Deprecated since 0.4.0.
  1065. See method ``to_deterministic()`` for an alternative and for
  1066. details about what the "deterministic mode" actually does.
  1067. """
  1068. # Added in 0.4.0.
  1069. def __init__(self, density, density_uniformity, drop_size,
  1070. drop_size_uniformity, angle, speed, blur_sigma_fraction,
  1071. blur_sigma_limits=(0.5, 3.75),
  1072. seed=None, name=None,
  1073. random_state="deprecated", deterministic="deprecated"):
  1074. super(RainLayer, self).__init__(
  1075. density, density_uniformity, drop_size,
  1076. drop_size_uniformity, angle, speed, blur_sigma_fraction,
  1077. blur_sigma_limits=blur_sigma_limits,
  1078. seed=seed, name=name,
  1079. random_state=random_state, deterministic=deterministic)
  1080. # Added in 0.4.0.
  1081. @classmethod
  1082. def _blur(cls, noise, sigma):
  1083. return noise
  1084. # Added in 0.4.0.
  1085. @classmethod
  1086. def _postprocess_noise(cls, noise_small_blur,
  1087. flake_size_uniformity_sample, nb_channels):
  1088. noise_small_blur_rgb = np.tile(
  1089. noise_small_blur[..., np.newaxis], (1, 1, nb_channels))
  1090. return noise_small_blur_rgb
  1091. # Added in 0.4.0.
  1092. @classmethod
  1093. def _blend(cls, image, speed_sample, noise_small_blur_rgb):
  1094. # We set the mean color based on the noise here. That's a pseudo-random
  1095. # approach that saves us from adding the random state as a parameter.
  1096. # Note that the sum of noise_small_blur_rgb can be 0 when at least one
  1097. # image axis size is 0.
  1098. noise_sum = np.sum(noise_small_blur_rgb.flat[0:1000])
  1099. noise_sum = noise_sum if noise_sum > 0 else 1
  1100. drop_mean_color = 110 + (240 - 110) % noise_sum
  1101. noise_small_blur_rgb = noise_small_blur_rgb / 255.0
  1102. # The 1.3 multiplier increases the visibility of drops a bit.
  1103. noise_small_blur_rgb = np.clip(1.3 * noise_small_blur_rgb, 0, 1.0)
  1104. image_f32 = image.astype(np.float32)
  1105. image_f32 = (
  1106. (1 - noise_small_blur_rgb) * image_f32
  1107. + noise_small_blur_rgb * drop_mean_color
  1108. )
  1109. return np.clip(image_f32, 0, 255).astype(np.uint8)
  1110. class Rain(meta.SomeOf):
  1111. """Add falling snowflakes to images.
  1112. This is a wrapper around
  1113. :class:`~imgaug.augmenters.weather.RainLayer`. It executes 1 to 3
  1114. layers per image.
  1115. .. note::
  1116. This augmenter currently seems to work best for medium-sized images
  1117. around ``192x256``. For smaller images, you may want to increase the
  1118. `speed` value to e.g. ``(0.1, 0.3)``, otherwise the drops tend to
  1119. look like snowflakes. For larger images, you may want to increase
  1120. the `drop_size` to e.g. ``(0.10, 0.20)``.
  1121. Added in 0.4.0.
  1122. **Supported dtypes**:
  1123. * ``uint8``: yes; tested
  1124. * ``uint16``: no (1)
  1125. * ``uint32``: no (1)
  1126. * ``uint64``: no (1)
  1127. * ``int8``: no (1)
  1128. * ``int16``: no (1)
  1129. * ``int32``: no (1)
  1130. * ``int64``: no (1)
  1131. * ``float16``: no (1)
  1132. * ``float32``: no (1)
  1133. * ``float64``: no (1)
  1134. * ``float128``: no (1)
  1135. * ``bool``: no (1)
  1136. - (1) Parameters of this augmenter are optimized for the value range
  1137. of ``uint8``. While other dtypes may be accepted, they will lead
  1138. to images augmented in ways inappropriate for the respective
  1139. dtype.
  1140. Parameters
  1141. ----------
  1142. drop_size : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  1143. See :class:`~imgaug.augmenters.weather.RainLayer`.
  1144. speed : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
  1145. See :class:`~imgaug.augmenters.weather.RainLayer`.
  1146. 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
  1147. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  1148. name : None or str, optional
  1149. See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.
  1150. 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
  1151. Old name for parameter `seed`.
  1152. Its usage will not yet cause a deprecation warning,
  1153. but it is still recommended to use `seed` now.
  1154. Outdated since 0.4.0.
  1155. deterministic : bool, optional
  1156. Deprecated since 0.4.0.
  1157. See method ``to_deterministic()`` for an alternative and for
  1158. details about what the "deterministic mode" actually does.
  1159. Examples
  1160. --------
  1161. >>> import imgaug.augmenters as iaa
  1162. >>> aug = iaa.Rain(speed=(0.1, 0.3))
  1163. Add rain to small images (around ``96x128``).
  1164. >>> aug = iaa.Rain()
  1165. Add rain to medium sized images (around ``192x256``).
  1166. >>> aug = iaa.Rain(drop_size=(0.10, 0.20))
  1167. Add rain to large images (around ``960x1280``).
  1168. """
  1169. # Added in 0.4.0.
  1170. def __init__(self, nb_iterations=(1, 3),
  1171. drop_size=(0.01, 0.02),
  1172. speed=(0.04, 0.20),
  1173. seed=None, name=None,
  1174. random_state="deprecated", deterministic="deprecated"):
  1175. layer = RainLayer(
  1176. density=(0.03, 0.14),
  1177. density_uniformity=(0.8, 1.0),
  1178. drop_size=drop_size,
  1179. drop_size_uniformity=(0.2, 0.5),
  1180. angle=(-15, 15),
  1181. speed=speed,
  1182. blur_sigma_fraction=(0.001, 0.001),
  1183. seed=seed,
  1184. random_state=random_state,
  1185. deterministic=deterministic
  1186. )
  1187. super(Rain, self).__init__(
  1188. nb_iterations,
  1189. children=[layer.deepcopy() for _ in range(3)],
  1190. random_order=False,
  1191. seed=seed, name=name,
  1192. random_state=random_state, deterministic=deterministic)