augmentations.h
Go to the documentation of this file.
1 /*
2 * ECVL - European Computer Vision Library
3 * Version: 0.3.4
4 * copyright (c) 2021, Università degli Studi di Modena e Reggio Emilia (UNIMORE), AImageLab
5 * Authors:
6 * Costantino Grana (costantino.grana@unimore.it)
7 * Federico Bolelli (federico.bolelli@unimore.it)
8 * Michele Cancilla (michele.cancilla@unimore.it)
9 * Laura Canalini (laura.canalini@unimore.it)
10 * Stefano Allegretti (stefano.allegretti@unimore.it)
11 * All rights reserved.
12 */
13 
14 #ifndef AUGMENTATIONS_H_
15 #define AUGMENTATIONS_H_
16 
17 #include "ecvl/core/arithmetic.h"
18 #include "ecvl/core/imgproc.h"
19 #include <array>
20 #include <map>
21 #include <memory>
22 #include <random>
23 #include <iostream>
24 #include <algorithm>
25 #include <iterator>
26 #include <unordered_map>
27 #include <vector>
28 
29 namespace ecvl
30 {
31 #define ECVL_ERROR_AUGMENTATION_NAME throw std::runtime_error(ECVL_ERROR_MSG "Cannot load augmentation name");
32 #define ECVL_ERROR_AUGMENTATION_FORMAT throw std::runtime_error(ECVL_ERROR_MSG "Format error while loading augmentation parameters");
33 
34 class param_list;
35 
36 class param
37 {
38  static std::istream& read_until(std::istream& is, std::string& s, const std::string& list)
39  {
40  s.clear();
41  while (is.peek() && is && list.find(is.peek()) == list.npos) {
42  s += is.get();
43  }
44  return is;
45  }
46 
47  void read_vals(std::istream& is, char closing_char)
48  {
49  double val;
50  char next_char;
51  do {
52  is >> val;
53  if (!is) {
54  break;
55  }
56  vals_.push_back(val);
57  is >> next_char;
58  } while (next_char == ',');
59  if (!is || next_char != closing_char) {
60  std::cerr << "Error while reading values of parameter " << name_ << "\n"; // TODO: standardize
61  throw std::runtime_error("Cannot read parameter value"); // TODO: standardize
62  }
63  }
64 
65 public:
66  enum class type { range, vector, number, string };
67 
68  static const char* to_string(type t)
69  {
70  switch (t) {
71  case type::range: return "range";
72  case type::vector: return "vector";
73  case type::number: return "number";
74  case type::string: return "string";
75  default:
77  }
78  }
79 
80  std::string name_;
82  std::vector<double> vals_;
83  std::string str_;
84 
85  param() {}
86  param(std::istream& is)
87  {
88  is >> std::ws;
89  read_until(is, name_, " =");
90  char next_char;
91  is >> std::ws >> next_char;
92  if (next_char != '=') {
93  throw std::runtime_error("Cannot read parameter name"); // TODO: standardize
94  }
95  is >> std::ws;
96  next_char = is.peek();
97  if (next_char == '[') { // range
98  is.ignore();
100  read_vals(is, ']');
101  }
102  else if (next_char == '(') { // vector
103  is.ignore();
105  read_vals(is, ')');
106  }
107  else if (next_char == '"') { // string
108  is.ignore();
110  std::getline(is, str_, '"');
111  }
112  else {
114  vals_.resize(1);
115  is >> vals_[0];
116  }
117  if (!is) {
118  std::cerr << "Error while reading value of parameter " << name_ << "\n"; // TODO: standardize
119  throw std::runtime_error("Cannot read parameter value"); // TODO: standardize
120  }
121  }
122 
123  friend class param_list;
124  static param_list read(std::istream& is, std::string fn_name_);
125 };
126 
128 {
129  std::unordered_map<std::string, param> m_;
130  const std::string fn_name_;
131 public:
132  param_list(std::string fn_name) : fn_name_(move(fn_name)) {}
133 
134  auto& operator[](const std::string& s)
135  {
136  return m_[s];
137  }
138 
139  bool Get(const std::string& name, param::type type, bool required, param& value)
140  {
141  auto it = m_.find(name);
142  if (it != end(m_)) {
143  auto& p = it->second;
144  if (p.type_ != type) {
145  throw std::runtime_error(fn_name_ + ": " + name + " parameter must be a " + param::to_string(type));
146  }
147  value = p;
148  return true;
149  }
150  if (required) {
151  throw std::runtime_error(fn_name_ + ": " + name + " is a required parameter");
152  }
153  return false;
154  }
155 
156  bool GenericGet(const std::string& name, bool required, param& value)
157  {
158  auto it = m_.find(name);
159  if (it != end(m_)) {
160  auto& p = it->second;
161  value = p;
162  return true;
163  }
164  if (required) {
165  throw std::runtime_error(fn_name_ + ": " + name + " is a required parameter");
166  }
167  return false;
168  }
169 };
170 
178 {
179 public:
180  double min_, max_, value_;
181 
182  AugmentationParam() = default;
183  AugmentationParam(const double min, const double max) : min_(min), max_(max) {}
184 
188  {
189  value_ = std::uniform_real_distribution<>(min_, max_)(re_);
190  }
191  static std::default_random_engine re_;
192 
193  static constexpr unsigned seed_min = std::numeric_limits<unsigned>::min();
194  static constexpr unsigned seed_max = std::numeric_limits<unsigned>::max();
195 
199  static void SetSeed(unsigned seed)
200  {
201  re_.seed(seed);
202  }
203 };
204 
210 {
211 public:
212  std::unordered_map<std::string, AugmentationParam> params_;
213 
218  void Apply(ecvl::Image& img, const ecvl::Image& gt = Image())
219  {
220  for (auto& x : params_) {
221  x.second.GenerateValue();
222  }
223  RealApply(img, gt);
224  }
225  virtual ~Augmentation() = default;
226 
227 private:
228  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) = 0;
229 };
230 
232 {
233  static std::shared_ptr<Augmentation> create(std::istream& is)
234  {
235  std::string name;
236  is >> name;
237  if (!is) {
239  }
240  return create(name, is);
241  }
242 
243  static std::shared_ptr<Augmentation> create(const std::string& name, std::istream& is);
244 };
245 
253 {
259  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
260  {
261  for (auto& x : augs_) {
262  x->Apply(img, gt);
263  }
264  }
265  std::vector<std::shared_ptr<Augmentation>> augs_;
266 public:
267  template<typename ...Ts>
268  SequentialAugmentationContainer(Ts&&... t) : augs_({ std::make_shared<Ts>(std::forward<Ts>(t))... }) {}
269 
270  SequentialAugmentationContainer(std::vector<std::shared_ptr<Augmentation>> augs) : augs_(augs) {}
271 
273  {
274  while (true) {
275  std::string name;
276  is >> name;
277  if (!is) {
279  }
280  if (name == "end") {
281  break;
282  }
283  augs_.emplace_back(AugmentationFactory::create(name, is));
284  }
285  }
286 };
287 
296 {
302  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
303  {
304  int index = std::uniform_int_distribution<>(0, vsize(augs_) - 1)(AugmentationParam::re_);
305  if (params_["p"].value_ <= p_) {
306  augs_[index]->Apply(img, gt);
307  }
308  }
309  std::vector<std::shared_ptr<Augmentation>> augs_;
310  double p_;
311 public:
312  template<typename ...Ts>
313  OneOfAugmentationContainer(double p, Ts&&... t) : p_(p), augs_({ std::make_shared<Ts>(std::forward<Ts>(t))... })
314  {
315  params_["p"] = AugmentationParam(0, 1);
316  }
317 
318  OneOfAugmentationContainer(double p, std::vector<std::shared_ptr<Augmentation>> augs) : p_(p), augs_(augs)
319  {
320  params_["p"] = AugmentationParam(0, 1);
321  }
322 
323  OneOfAugmentationContainer(std::istream& is)
324  {
325  param p;
326  try {
327  auto m = param::read(is, "OneOfAugmentationContainer");
328  if (m.Get("p", param::type::number, true, p)) {
329  p_ = p.vals_[0];
330  }
331  } catch (std::runtime_error&) {
332  std::cout << ECVL_ERROR_MSG "The first parameter in OneOfAugmentationContainer must be the probability p" << std::endl;
334  }
335 
336  while (true) {
337  std::string name;
338  is >> name;
339  if (!is) {
341  }
342  if (name == "end") {
343  break;
344  }
345  augs_.emplace_back(AugmentationFactory::create(name, is));
346  }
347  }
348 };
349 
350 InterpolationType StrToInterpolationType(const std::string& interp, const std::string& aug_name);
351 
353 // Augmentations
355 
360 class AugRotate : public Augmentation
361 {
362  std::vector<double> center_;
363  double scale_;
364  InterpolationType interp_, gt_interp_;
365 
366  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
367  {
368  Rotate2D(img, img, params_["angle"].value_, center_, scale_, interp_);
369  if (!gt.IsEmpty()) {
370  Rotate2D(gt, const_cast<Image&>(gt), params_["angle"].value_, center_, scale_, interp_);
371  }
372  }
373 public:
383  AugRotate(const std::array<double, 2>& angle,
384  const std::vector<double>& center = {},
385  const double& scale = 1.,
388  : center_(center), scale_(scale), interp_(interp), gt_interp_(gt_interp)
389  {
390  params_["angle"] = AugmentationParam(angle[0], angle[1]);
391  }
392 
393  AugRotate(std::istream& is)
394  {
395  auto m = param::read(is, "AugRotate");
396  param p;
397 
398  m.Get("angle", param::type::range, true, p);
399  params_["angle"] = AugmentationParam(p.vals_[0], p.vals_[1]);
400 
401  if (m.Get("center", param::type::vector, false, p)) {
402  center_ = p.vals_;
403  }
404 
405  scale_ = 1.;
406  if (m.Get("scale", param::type::number, false, p)) {
407  scale_ = p.vals_[0];
408  }
409 
410  interp_ = InterpolationType::linear;
411  gt_interp_ = InterpolationType::nearest;
412 
413  if (m.Get("interp", param::type::string, false, p)) {
414  interp_ = StrToInterpolationType(p.str_, "AugRotate");
415  }
416  if (m.Get("gt_interp", param::type::string, false, p)) {
417  gt_interp_ = StrToInterpolationType(p.str_, "AugRotate");
418  }
419  }
420 };
421 
427 {
428  std::vector<int> dims_;
429  InterpolationType interp_, gt_interp_;
430 
431  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
432  {
433  ResizeDim(img, img, dims_, interp_);
434  if (!gt.IsEmpty()) {
435  ResizeDim(gt, const_cast<Image&>(gt), dims_, gt_interp_);
436  }
437  }
438 public:
445  AugResizeDim(const std::vector<int>& dims,
448  : dims_{ dims }, interp_(interp), gt_interp_(gt_interp) {}
449 
450  AugResizeDim(std::istream& is)
451  {
452  auto m = param::read(is, "AugResizeDim");
453  param p;
454 
455  m.Get("dims", param::type::vector, true, p);
456  for (const auto& x : p.vals_) {
457  dims_.emplace_back(static_cast<int>(x));
458  }
459 
460  interp_ = InterpolationType::linear;
461  gt_interp_ = InterpolationType::nearest;
462 
463  if (m.Get("interp", param::type::string, false, p)) {
464  interp_ = StrToInterpolationType(p.str_, "");
465  }
466  if (m.Get("gt_interp", param::type::string, false, p)) {
467  gt_interp_ = StrToInterpolationType(p.str_, "AugResizeDim");
468  }
469  }
470 };
471 
477 {
478  std::vector<double> scale_;
479  InterpolationType interp_, gt_interp_;
480 
481  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
482  {
483  ResizeScale(img, img, scale_, interp_);
484  if (!gt.IsEmpty()) {
485  ResizeScale(gt, const_cast<Image&>(gt), scale_, interp_);
486  }
487  }
488 public:
495  AugResizeScale(const std::vector<double>& scale,
498  ) : scale_{ scale }, interp_(interp), gt_interp_(gt_interp){}
499 
500  AugResizeScale(std::istream& is)
501  {
502  auto m = param::read(is, "AugResizeScale");
503  param p;
504 
505  m.Get("scale", param::type::vector, true, p);
506  scale_ = p.vals_;
507 
508  interp_ = InterpolationType::linear;
509  gt_interp_ = InterpolationType::nearest;
510 
511  if (m.Get("interp", param::type::string, false, p)) {
512  interp_ = StrToInterpolationType(p.str_, "AugResizeScale");
513  }
514  if (m.Get("gt_interp", param::type::string, false, p)) {
515  gt_interp_ = StrToInterpolationType(p.str_, "AugResizeScale");
516  }
517  }
518 };
519 
524 class AugFlip : public Augmentation
525 {
526  double p_;
527 
528  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
529  {
530  if (params_["p"].value_ <= p_) {
531  Flip2D(img, img);
532  if (!gt.IsEmpty()) {
533  Flip2D(gt, const_cast<Image&>(gt));
534  }
535  }
536  }
537 public:
542  AugFlip(double p = 0.5) : p_{ p }
543  {
544  params_["p"] = AugmentationParam(0, 1);
545  }
546 
547  AugFlip(std::istream& is) : AugFlip()
548  {
549  auto m = param::read(is, "AugFlip");
550  param p;
551 
552  if (m.Get("p", param::type::number, false, p)) {
553  p_ = p.vals_[0];
554  }
555  }
556 };
557 
562 class AugMirror : public Augmentation
563 {
564  double p_;
565 
566  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
567  {
568  if (params_["p"].value_ <= p_) {
569  Mirror2D(img, img);
570  if (!gt.IsEmpty()) {
571  Mirror2D(gt, const_cast<Image&>(gt));
572  }
573  }
574  }
575 public:
580  AugMirror(double p = 0.5) : p_{ p }
581  {
582  params_["p"] = AugmentationParam(0, 1);
583  }
584 
585  AugMirror(std::istream& is) : AugMirror()
586  {
587  auto m = param::read(is, "AugMirror");
588  param p;
589 
590  if (m.Get("p", param::type::number, false, p)) {
591  p_ = p.vals_[0];
592  }
593  }
594 };
595 
601 {
602  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
603  {
604  GaussianBlur(img, img, params_["sigma"].value_);
605  }
606 public:
611  AugGaussianBlur(const std::array<double, 2>& sigma)
612  {
613  params_["sigma"] = AugmentationParam(sigma[0], sigma[1]);
614  }
615 
616  AugGaussianBlur(std::istream& is)
617  {
618  auto m = param::read(is, "AugGaussianBlur");
619  param p;
620 
621  m.Get("sigma", param::type::range, true, p);
622  params_["sigma"] = AugmentationParam(p.vals_[0], p.vals_[1]);
623  }
624 };
625 
631 {
632  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
633  {
634  AdditiveLaplaceNoise(img, img, params_["std_dev"].value_);
635  }
636 public:
642  AugAdditiveLaplaceNoise(const std::array<double, 2>& std_dev)
643  {
644  params_["std_dev"] = AugmentationParam(std_dev[0], std_dev[1]);
645  }
646 
647  AugAdditiveLaplaceNoise(std::istream& is)
648  {
649  auto m = param::read(is, "AugAdditiveLaplaceNoise");
650  param p;
651 
652  m.Get("std_dev", param::type::range, true, p);
653  params_["std_dev"] = AugmentationParam(p.vals_[0], p.vals_[1]);
654  }
655 };
656 
662 {
663  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
664  {
665  AdditivePoissonNoise(img, img, params_["lambda"].value_);
666  }
667 public:
673  AugAdditivePoissonNoise(const std::array<double, 2>& lambda)
674  {
675  params_["lambda"] = AugmentationParam(lambda[0], lambda[1]);
676  }
677 
678  AugAdditivePoissonNoise(std::istream& is)
679  {
680  auto m = param::read(is, "AugAdditivePoissonNoise");
681  param p;
682 
683  m.Get("lambda", param::type::range, true, p);
684  params_["lambda"] = AugmentationParam(p.vals_[0], p.vals_[1]);
685  }
686 };
687 
693 {
694  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
695  {
696  GammaContrast(img, img, params_["gamma"].value_);
697  }
698 public:
704  AugGammaContrast(const std::array<double, 2>& gamma)
705  {
706  params_["gamma"] = AugmentationParam(gamma[0], gamma[1]);
707  }
708 
709  AugGammaContrast(std::istream& is)
710  {
711  auto m = param::read(is, "AugGammaContrast");
712  param p;
713 
714  m.Get("gamma", param::type::range, true, p);
715  params_["gamma"] = AugmentationParam(p.vals_[0], p.vals_[1]);
716  }
717 };
718 
724 {
725  double per_channel_;
726 
727  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
728  {
729  bool per_channel = params_["per_channel"].value_ <= per_channel_ ? true : false;
730  CoarseDropout(img, img, params_["p"].value_, params_["drop_size"].value_, per_channel);
731  }
732 public:
739  AugCoarseDropout(const std::array<double, 2>& p, const std::array<double, 2>& drop_size, const double& per_channel) : per_channel_(per_channel)
740  {
741  assert(per_channel >= 0 && per_channel <= 1);
742  params_["p"] = AugmentationParam(p[0], p[1]);
743  params_["drop_size"] = AugmentationParam(drop_size[0], drop_size[1]);
744  params_["per_channel"] = AugmentationParam(0, 1);
745  }
746  AugCoarseDropout(std::istream& is)
747  {
748  auto m = param::read(is, "AugCoarseDropout");
749  param p;
750 
751  m.Get("p", param::type::range, true, p);
752  params_["p"] = AugmentationParam(p.vals_[0], p.vals_[1]);
753 
754  m.Get("drop_size", param::type::range, true, p);
755  params_["drop_size"] = AugmentationParam(p.vals_[0], p.vals_[1]);
756 
757  m.Get("per_channel", param::type::number, true, p);
758  params_["per_channel"] = AugmentationParam(0, 1);
759  per_channel_ = p.vals_[0];
760  }
761 };
762 
768 {
769  double p_;
770 
771  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
772  {
773  if (params_["p"].value_ <= p_) {
774  Transpose(img, img);
775  if (!gt.IsEmpty()) {
776  Transpose(gt, const_cast<Image&>(gt));
777  }
778  }
779  }
780 public:
785  AugTranspose(double p = 0.5) : p_{ p }
786  {
787  params_["p"] = AugmentationParam(0, 1);
788  }
789 
790  AugTranspose(std::istream& is) : AugTranspose()
791  {
792  auto m = param::read(is, "AugTranspose");
793  param p;
794 
795  if (m.Get("p", param::type::number, false, p)) {
796  p_ = p.vals_[0];
797  }
798  }
799 };
800 
806 {
807  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
808  {
809  Add(img, params_["beta"].value_, img);
810  }
811 public:
817  AugBrightness(const std::array<double, 2>& beta)
818  {
819  params_["beta"] = AugmentationParam(beta[0], beta[1]);
820  }
821 
822  AugBrightness(std::istream& is)
823  {
824  auto m = param::read(is, "AugBrightness");
825 
826  param p;
827 
828  m.Get("beta", param::type::range, true, p);
829  params_["beta"] = AugmentationParam(p.vals_[0], p.vals_[1]);
830  }
831 };
832 
838 {
839  std::array<float, 2> distort_limit_;
840  InterpolationType interp_;
841  BorderType border_type_;
842  int border_value_;
843 
844  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
845  {
846  GridDistortion(img, img, static_cast<int>(params_["num_steps"].value_), distort_limit_, interp_, border_type_,
847  border_value_, static_cast<unsigned>(params_["seed"].value_));
848  if (!gt.IsEmpty()) {
849  GridDistortion(gt, const_cast<Image&>(gt), static_cast<int>(params_["num_steps"].value_), distort_limit_,
850  interp_, border_type_, border_value_, static_cast<unsigned>(params_["seed"].value_));
851  }
852  }
853 public:
862  AugGridDistortion(const std::array<int, 2>& num_steps,
863  const std::array<float, 2>& distort_limit,
865  const BorderType& border_type = BorderType::BORDER_REFLECT_101,
866  const int& border_value = 0)
867  : distort_limit_(distort_limit), interp_(interp), border_type_(border_type), border_value_(border_value)
868  {
869  params_["num_steps"] = AugmentationParam(num_steps[0], num_steps[1]);
871  }
872 
873  AugGridDistortion(std::istream& is)
874  {
875  auto m = param::read(is, "AugGridDistortion");
876 
877  param p;
878 
879  m.Get("num_steps", param::type::range, true, p);
880  params_["num_steps"] = AugmentationParam(p.vals_[0], p.vals_[1]);
881 
882  // seed is managed by AugmentationParam
884 
885  m.Get("distort_limit", param::type::range, true, p);
886  distort_limit_ = { static_cast<float>(p.vals_[0]), static_cast<float>(p.vals_[1]) };
887 
888  interp_ = InterpolationType::linear;
889  if (m.Get("interp", param::type::string, false, p)) {
890  interp_ = StrToInterpolationType(p.str_, "AugGridDistortion");
891  }
892 
893  border_type_ = BorderType::BORDER_REFLECT_101;
894  if (m.Get("border_type", param::type::string, false, p)) {
895  if (p.str_ == "constant") {
896  border_type_ = BorderType::BORDER_CONSTANT;
897  }
898  else if (p.str_ == "replicate") {
899  border_type_ = BorderType::BORDER_REPLICATE;
900  }
901  else if (p.str_ == "reflect") {
902  border_type_ = BorderType::BORDER_REFLECT;
903  }
904  else if (p.str_ == "wrap") {
905  border_type_ = BorderType::BORDER_WRAP;
906  }
907  else if (p.str_ == "reflect_101") {
908  border_type_ = BorderType::BORDER_REFLECT_101;
909  }
910  else if (p.str_ == "transparent") {
911  border_type_ = BorderType::BORDER_TRANSPARENT;
912  }
913  else {
914  throw std::runtime_error("AugGridDistortion: invalid border type"); // TODO: standardize
915  }
916  }
917 
918  border_value_ = 0;
919  m.Get("border_value", param::type::number, false, p);
920  border_value_ = static_cast<int>(p.vals_[0]);
921  }
922 };
923 
929 {
930  InterpolationType interp_;
931  BorderType border_type_;
932  int border_value_;
933 
934  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
935  {
936  ElasticTransform(img, img, params_["alpha"].value_, params_["sigma"].value_, interp_, border_type_,
937  border_value_, static_cast<unsigned>(params_["seed"].value_));
938  if (!gt.IsEmpty()) {
939  ElasticTransform(gt, const_cast<Image&>(gt), params_["alpha"].value_, params_["sigma"].value_, interp_,
940  border_type_, border_value_, static_cast<unsigned>(params_["seed"].value_));
941  }
942  }
943 public:
952  AugElasticTransform(const std::array<double, 2>& alpha,
953  const std::array<double, 2>& sigma,
955  const BorderType& border_type = BorderType::BORDER_REFLECT_101,
956  const int& border_value = 0)
957  : interp_(interp), border_type_(border_type), border_value_(border_value)
958  {
959  params_["alpha"] = AugmentationParam(alpha[0], alpha[1]);
960  params_["sigma"] = AugmentationParam(sigma[0], sigma[1]);
962  }
963 
964  AugElasticTransform(std::istream& is)
965  {
966  auto m = param::read(is, "AugElasticTransform");
967 
968  param p;
969 
970  m.Get("alpha", param::type::range, true, p);
971  params_["alpha"] = AugmentationParam(p.vals_[0], p.vals_[1]);
972 
973  m.Get("sigma", param::type::range, true, p);
974  params_["sigma"] = AugmentationParam(p.vals_[0], p.vals_[1]);
975 
976  // seed is managed by AugmentationParam
978 
979  interp_ = InterpolationType::linear;
980  if (m.Get("interp", param::type::string, false, p)) {
981  interp_ = StrToInterpolationType(p.str_, "AugElasticTransform");
982  }
983 
984  border_type_ = BorderType::BORDER_REFLECT_101;
985  if (m.Get("border_type", param::type::string, false, p)) {
986  if (p.str_ == "constant") {
987  border_type_ = BorderType::BORDER_CONSTANT;
988  }
989  else if (p.str_ == "replicate") {
990  border_type_ = BorderType::BORDER_REPLICATE;
991  }
992  else if (p.str_ == "reflect") {
993  border_type_ = BorderType::BORDER_REFLECT;
994  }
995  else if (p.str_ == "wrap") {
996  border_type_ = BorderType::BORDER_WRAP;
997  }
998  else if (p.str_ == "reflect_101") {
999  border_type_ = BorderType::BORDER_REFLECT_101;
1000  }
1001  else if (p.str_ == "transparent") {
1002  border_type_ = BorderType::BORDER_TRANSPARENT;
1003  }
1004  else {
1005  throw std::runtime_error("AugGridDistortion: invalid border type"); // TODO: standardize
1006  }
1007  }
1008 
1009  border_value_ = 0;
1010  m.Get("border_value", param::type::number, false, p);
1011  border_value_ = static_cast<int>(p.vals_[0]);
1012  }
1013 };
1014 
1020 {
1021  std::array<float, 2> distort_limit_;
1022  std::array<float, 2> shift_limit_;
1023  InterpolationType interp_;
1024  BorderType border_type_;
1025  int border_value_;
1026 
1027  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
1028  {
1029  OpticalDistortion(img, img, distort_limit_, shift_limit_, interp_, border_type_,
1030  border_value_, static_cast<unsigned>(params_["seed"].value_));
1031  if (!gt.IsEmpty()) {
1032  OpticalDistortion(gt, const_cast<Image&>(gt), distort_limit_, shift_limit_, interp_, border_type_,
1033  border_value_, static_cast<unsigned>(params_["seed"].value_));
1034  }
1035  }
1036 public:
1045  AugOpticalDistortion(const std::array<float, 2>& distort_limit,
1046  const std::array<float, 2>& shift_limit,
1048  const BorderType& border_type = BorderType::BORDER_REFLECT_101,
1049  const int& border_value = 0)
1050  : distort_limit_(distort_limit), shift_limit_(shift_limit), interp_(interp), border_type_(border_type), border_value_(border_value)
1051  {
1053  }
1054 
1055  AugOpticalDistortion(std::istream& is)
1056  {
1057  auto m = param::read(is, "AugOpticalDistortion");
1058 
1059  param p;
1060 
1061  // seed is managed by AugmentationParam
1063 
1064  m.Get("distort_limit", param::type::range, true, p);
1065  distort_limit_ = { static_cast<float>(p.vals_[0]), static_cast<float>(p.vals_[1]) };
1066 
1067  m.Get("shift_limit", param::type::range, true, p);
1068  shift_limit_ = { static_cast<float>(p.vals_[0]), static_cast<float>(p.vals_[1]) };
1069 
1070  interp_ = InterpolationType::linear;
1071  if (m.Get("interp", param::type::string, false, p)) {
1072  interp_ = StrToInterpolationType(p.str_, "AugOpticalDistortion");
1073  }
1074 
1075  border_type_ = BorderType::BORDER_REFLECT_101;
1076  if (m.Get("border_type", param::type::string, false, p)) {
1077  if (p.str_ == "constant") {
1078  border_type_ = BorderType::BORDER_CONSTANT;
1079  }
1080  else if (p.str_ == "replicate") {
1081  border_type_ = BorderType::BORDER_REPLICATE;
1082  }
1083  else if (p.str_ == "reflect") {
1084  border_type_ = BorderType::BORDER_REFLECT;
1085  }
1086  else if (p.str_ == "wrap") {
1087  border_type_ = BorderType::BORDER_WRAP;
1088  }
1089  else if (p.str_ == "reflect_101") {
1090  border_type_ = BorderType::BORDER_REFLECT_101;
1091  }
1092  else if (p.str_ == "transparent") {
1093  border_type_ = BorderType::BORDER_TRANSPARENT;
1094  }
1095  else {
1096  throw std::runtime_error("AugGridDistortion: invalid border type"); // TODO: standardize
1097  }
1098  }
1099 
1100  border_value_ = 0;
1101  m.Get("border_value", param::type::number, false, p);
1102  border_value_ = static_cast<int>(p.vals_[0]);
1103  }
1104 };
1105 
1110 class AugSalt : public Augmentation
1111 {
1112  double per_channel_;
1113 
1114  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
1115  {
1116  bool per_channel = params_["per_channel"].value_ <= per_channel_ ? true : false;
1117  Salt(img, img, params_["p"].value_, per_channel, static_cast<unsigned>(params_["seed"].value_));
1118  }
1119 public:
1125  AugSalt(const std::array<double, 2>& p, const double& per_channel) : per_channel_(per_channel)
1126  {
1127  assert(per_channel >= 0 && per_channel <= 1);
1128  params_["p"] = AugmentationParam(p[0], p[1]);
1129  params_["per_channel"] = AugmentationParam(0, 1);
1131  }
1132  AugSalt(std::istream& is)
1133  {
1134  auto m = param::read(is, "AugSalt");
1135  param p;
1136 
1137  // seed is managed by AugmentationParam
1139 
1140  m.Get("p", param::type::range, true, p);
1141  params_["p"] = AugmentationParam(p.vals_[0], p.vals_[1]);
1142 
1143  m.Get("per_channel", param::type::number, true, p);
1144  params_["per_channel"] = AugmentationParam(0, 1);
1145  per_channel_ = p.vals_[0];
1146  }
1147 };
1148 
1153 class AugPepper : public Augmentation
1154 {
1155  double per_channel_;
1156 
1157  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
1158  {
1159  bool per_channel = params_["per_channel"].value_ <= per_channel_ ? true : false;
1160  Pepper(img, img, params_["p"].value_, per_channel, static_cast<unsigned>(params_["seed"].value_));
1161  }
1162 public:
1168  AugPepper(const std::array<double, 2>& p, const double& per_channel) : per_channel_(per_channel)
1169  {
1170  assert(per_channel >= 0 && per_channel <= 1);
1171  params_["p"] = AugmentationParam(p[0], p[1]);
1172  params_["per_channel"] = AugmentationParam(0, 1);
1174  }
1175  AugPepper(std::istream& is)
1176  {
1177  auto m = param::read(is, "AugPepper");
1178  param p;
1179 
1180  // seed is managed by AugmentationParam
1182 
1183  m.Get("p", param::type::range, true, p);
1184  params_["p"] = AugmentationParam(p.vals_[0], p.vals_[1]);
1185 
1186  m.Get("per_channel", param::type::number, true, p);
1187  params_["per_channel"] = AugmentationParam(0, 1);
1188  per_channel_ = p.vals_[0];
1189  }
1190 };
1191 
1197 {
1198  double per_channel_;
1199 
1200  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
1201  {
1202  bool per_channel = params_["per_channel"].value_ <= per_channel_ ? true : false;
1203  SaltAndPepper(img, img, params_["p"].value_, per_channel, static_cast<unsigned>(params_["seed"].value_));
1204  }
1205 public:
1211  AugSaltAndPepper(const std::array<double, 2>& p, const double& per_channel) : per_channel_(per_channel)
1212  {
1213  assert(per_channel >= 0 && per_channel <= 1);
1214  params_["p"] = AugmentationParam(p[0], p[1]);
1215  params_["per_channel"] = AugmentationParam(0, 1);
1217  }
1218  AugSaltAndPepper(std::istream& is)
1219  {
1220  auto m = param::read(is, "AugSaltAndPepper");
1221  param p;
1222 
1223  // seed is managed by AugmentationParam
1225 
1226  m.Get("p", param::type::range, true, p);
1227  params_["p"] = AugmentationParam(p.vals_[0], p.vals_[1]);
1228 
1229  m.Get("per_channel", param::type::number, true, p);
1230  params_["per_channel"] = AugmentationParam(0, 1);
1231  per_channel_ = p.vals_[0];
1232  }
1233 };
1234 
1240 {
1241  double mean_ = 0., std_ = 1.;
1242 
1243  std::vector<double> ch_mean_;
1244  std::vector<double> ch_std_;
1245 
1246  bool per_channel_;
1247 
1248  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
1249  {
1250  if (per_channel_) {
1251  Normalize(img, img, ch_mean_, ch_std_);
1252  }
1253  else {
1254  Normalize(img, img, mean_, std_);
1255  }
1256  }
1257 public:
1263  AugNormalize(const double& mean, const double& std) : mean_(mean), std_(std), per_channel_(false) {}
1264 
1270  AugNormalize(const std::vector<double>& mean, const std::vector<double>& std) : ch_mean_(mean), ch_std_(std), per_channel_(true) {}
1271 
1272  AugNormalize(std::istream& is)
1273  {
1274  auto m = param::read(is, "AugNormalize");
1275  param p;
1276 
1277  m.GenericGet("mean", true, p);
1278  if (p.type_ == param::type::number) {
1279  mean_ = p.vals_[0];
1280  per_channel_ = false;
1281  }
1282  else if (p.type_ == param::type::vector) {
1283  ch_mean_ = p.vals_;
1284  per_channel_ = true;
1285  }
1286  else {
1287  throw std::runtime_error("AugNormalize: invalid mean type");
1288  }
1289 
1290  if (per_channel_ == false) {
1291  m.Get("std", param::type::number, true, p);
1292  std_ = p.vals_[0];
1293  }
1294  else {
1295  m.Get("std", param::type::vector, true, p);
1296  ch_std_ = p.vals_;
1297  }
1298  }
1299 };
1300 
1306 {
1307  std::vector<int> size_;
1308 
1309  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
1310  {
1311  CenterCrop(img, img, size_);
1312  if (!gt.IsEmpty()) {
1313  CenterCrop(gt, const_cast<Image&>(gt), size_);
1314  }
1315  }
1316 public:
1321  AugCenterCrop(const std::vector<int>& size) : size_{ size } {}
1322 
1323  AugCenterCrop(std::istream& is)
1324  {
1325  auto m = param::read(is, "AugCenterCrop");
1326  param p;
1327 
1328  m.Get("size", param::type::vector, true, p);
1329  for (const auto& x : p.vals_) {
1330  size_.emplace_back(static_cast<int>(x));
1331  }
1332  }
1333 };
1334 
1342 {
1343  double divisor_, divisor_gt_;
1344 
1345  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
1346  {
1348  img.Div(divisor_);
1349 
1350  if (!gt.IsEmpty()) {
1351  const_cast<Image&>(gt).ConvertTo(DataType::float32);
1352  const_cast<Image&>(gt).Div(divisor_gt_);
1353  }
1354  }
1355 public:
1361  AugToFloat32(const double& divisor = 1., const double& divisor_gt = 1.) : divisor_{ divisor }, divisor_gt_{ divisor_gt } {}
1362  AugToFloat32(std::istream& is)
1363  {
1364  auto m = param::read(is, "AugToFloat32");
1365  param p;
1366 
1367  m.Get("divisor", param::type::number, false, p);
1368  divisor_ = p.vals_[0];
1369  m.Get("divisor_gt", param::type::number, false, p);
1370  divisor_gt_ = p.vals_[0];
1371  }
1372 };
1373 
1381 {
1382  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
1383  {
1384  img.Div(255);
1385 
1386  if (!gt.IsEmpty()) {
1387  const_cast<Image&>(gt).Div(255);
1388  }
1389  }
1390 public:
1393  AugDivBy255(std::istream& is) {}
1394 };
1395 
1400 class AugScaleTo : public Augmentation
1401 {
1402  double new_min_, new_max_;
1403 
1404  virtual void RealApply(ecvl::Image& img, const ecvl::Image& gt = Image()) override
1405  {
1406  ScaleTo(img, img, new_min_, new_max_);
1407  }
1408 public:
1414  AugScaleTo(const double& new_min, const double& new_max) : new_min_{ new_min }, new_max_{ new_max } {}
1415  AugScaleTo(std::istream& is)
1416  {
1417  auto m = param::read(is, "AugScaleTo");
1418  param p;
1419 
1420  m.Get("new_min", param::type::number, true, p);
1421  new_min_ = p.vals_[0];
1422 
1423  m.Get("new_max", param::type::number, true, p);
1424  new_max_ = p.vals_[0];
1425  }
1426 };
1427 } // namespace ecvl
1428 
1429 #endif // AUGMENTATIONS_H_
AugCenterCrop(const std::vector< int > &size)
AugCenterCrop constructor.
Augmentation wrapper for ecvl::Flip2D.
Augmentation wrapper for ecvl::Normalize.
AugmentationParam(const double min, const double max)
void ResizeDim(const ecvl::Image &src, ecvl::Image &dst, const std::vector< int > &newdims, InterpolationType interp=InterpolationType::linear)
Resizes an Image to the specified dimensions.
Image class.
Definition: image.h:72
AugMirror(double p=0.5)
AugMirror constructor.
AugAdditiveLaplaceNoise(const std::array< double, 2 > &std_dev)
AugAdditiveLaplaceNoise constructor.
void CoarseDropout(const Image &src, Image &dst, double p, double drop_size, bool per_channel)
Sets rectangular areas within an Image to zero.
void GridDistortion(const Image &src, Image &dst, int num_steps=5, const std::array< float, 2 > &distort_limit={ -0.3f, 0.3f }, InterpolationType interp=InterpolationType::linear, BorderType border_type=BorderType::BORDER_REFLECT_101, const int &border_value=0, const unsigned seed=std::default_random_engine::default_seed)
Randomly stretch or reduce each cell of the grid in which the input Image is divided into....
void ScaleTo(const Image &src, Image &dst, const double &new_min, const double &new_max)
Linearly scale an Image into a new range.
AugBrightness(const std::array< double, 2 > &beta)
AugBrightness constructor.
OneOfAugmentationContainer(double p, std::vector< std::shared_ptr< Augmentation >> augs)
Augmentation wrapper for ecvl::ElasticTransform.
AugBrightness(std::istream &is)
AugRotate(std::istream &is)
aaaaaa|abcdefgh|hhhhhhh
Augmentation wrapper for ecvl::GridDistortion.
OneOfAugmentationContainer.
bool GenericGet(const std::string &name, bool required, param &value)
AugResizeScale(std::istream &is)
AugDivBy255(std::istream &is)
int vsize(const std::vector< T > &v)
Definition: image.h:34
param(std::istream &is)
Definition: augmentations.h:86
void CenterCrop(const ecvl::Image &src, ecvl::Image &dst, const std::vector< int > &size)
Crops the given image at the center.
bool Get(const std::string &name, param::type type, bool required, param &value)
SequentialAugmentationContainer(std::vector< std::shared_ptr< Augmentation >> augs)
AugMirror(std::istream &is)
AugToFloat32(std::istream &is)
AugElasticTransform(std::istream &is)
SequentialAugmentationContainer.
AugFlip(double p=0.5)
AugFlip constructor.
std::unordered_map< std::string, AugmentationParam > params_
AugFlip(std::istream &is)
AugResizeDim(const std::vector< int > &dims, const InterpolationType &interp=InterpolationType::linear, const InterpolationType &gt_interp=InterpolationType::nearest)
AugResizeDim constructor.
InterpolationType
Enum class representing the ECVL interpolation types.
Definition: imgproc.h:37
void AdditiveLaplaceNoise(const Image &src, Image &dst, double std_dev)
Adds Laplace distributed noise to an Image.
Augmentation ToFloat32.
void Add(const Image &src1, const Image &src2, Image &dst, DataType dst_type=DataType::none, bool saturate=true)
Adds two source Images storing the result into a destination Image.
Definition: arithmetic.h:69
AugNormalize(const double &mean, const double &std)
AugNormalize constructor.
AugTranspose(std::istream &is)
void Transpose(const Image &src, Image &dst)
Swap rows and columns of an Image.
AugAdditivePoissonNoise(std::istream &is)
Augmentation wrapper for ecvl::Mirror2D.
AugRotate(const std::array< double, 2 > &angle, const std::vector< double > &center={}, const double &scale=1., const InterpolationType &interp=InterpolationType::linear, const InterpolationType &gt_interp=InterpolationType::nearest)
AugRotate constructor.
static void SetSeed(unsigned seed)
Set a fixed seed for the random generated values. Useful to reproduce experiments with same augmentat...
AugGridDistortion(const std::array< int, 2 > &num_steps, const std::array< float, 2 > &distort_limit, const InterpolationType &interp=InterpolationType::linear, const BorderType &border_type=BorderType::BORDER_REFLECT_101, const int &border_value=0)
AugGridDistortion constructor.
iiiiii|abcdefgh|iiiiiii with some specified i
void Salt(const Image &src, Image &dst, double p, bool per_channel=false, const unsigned seed=std::default_random_engine::default_seed)
Adds salt noise (white pixels) to an Image.
void ResizeScale(const ecvl::Image &src, ecvl::Image &dst, const std::vector< double > &scales, InterpolationType interp=InterpolationType::linear)
Resizes an Image by scaling the dimensions to a given scale factor.
AugGridDistortion(std::istream &is)
cdefgh|abcdefgh|abcdefg
Augmentation CenterCrop wrapper for ecvl::CenterCrop.
AugCoarseDropout(const std::array< double, 2 > &p, const std::array< double, 2 > &drop_size, const double &per_channel)
AugCoarseDropout constructor.
static std::shared_ptr< Augmentation > create(std::istream &is)
void GaussianBlur(const Image &src, Image &dst, int sizeX, int sizeY, double sigmaX, double sigmaY=0)
Blurs an Image using a Gaussian kernel.
Augmentation wrapper for ecvl::AdditivePoissonNoise.
std::string name_
Definition: augmentations.h:80
void Normalize(const Image &src, Image &dst, const double &mean, const double &std)
Normalize Image image with mean and standard deviation.
fedcba|abcdefgh|hgfedcb
void ConvertTo(DataType dtype, bool saturate=true)
Convert Image to another DataType.
Definition: image.h:557
AugToFloat32(const double &divisor=1., const double &divisor_gt=1.)
AugToFloat32 constructor.
static std::default_random_engine re_
BorderType
Enum class representing the ECVL border types.
Definition: imgproc.h:362
void SaltAndPepper(const Image &src, Image &dst, double p, bool per_channel=false, const unsigned seed=std::default_random_engine::default_seed)
Adds salt and pepper noise (white and black pixels) to an Image. White and black pixels are equally l...
AugCoarseDropout(std::istream &is)
Augmentations parameters.
AugAdditivePoissonNoise(const std::array< double, 2 > &lambda)
AugAdditivePoissonNoise constructor.
Augmentation wrapper for ecvl::Transpose.
AugNormalize(const std::vector< double > &mean, const std::vector< double > &std)
AugNormalize constructor with separate statistics for each channel.
static param_list read(std::istream &is, std::string fn_name_)
param_list(std::string fn_name)
InterpolationType StrToInterpolationType(const std::string &interp, const std::string &aug_name)
#define ECVL_ERROR_NOT_REACHABLE_CODE
AugGaussianBlur(std::istream &is)
void AdditivePoissonNoise(const Image &src, Image &dst, double lambda)
Adds Poisson distributed noise to an Image.
void Rotate2D(const ecvl::Image &src, ecvl::Image &dst, double angle, const std::vector< double > &center={}, double scale=1.0, InterpolationType interp=InterpolationType::linear)
Rotates an Image.
auto & operator[](const std::string &s)
static constexpr unsigned seed_min
Augmentation wrapper for ecvl::GaussianBlur.
void Div(const T &rhs, bool saturate=true)
In-place division.
Definition: image.h:544
Augmentation wrapper for ecvl::AdditiveLaplaceNoise.
AugResizeScale(const std::vector< double > &scale, const InterpolationType &interp=InterpolationType::linear, const InterpolationType &gt_interp=InterpolationType::nearest)
AugResizeScale constructor.
Augmentation wrapper for ecvl::Pepper.
#define ECVL_ERROR_MSG
void OpticalDistortion(const Image &src, Image &dst, const std::array< float, 2 > &distort_limit={ -0.3f, 0.3f }, const std::array< float, 2 > &shift_limit={ -0.1f, 0.1f }, InterpolationType interp=InterpolationType::linear, BorderType border_type=BorderType::BORDER_REFLECT_101, const int &border_value=0, const unsigned seed=std::default_random_engine::default_seed)
Barrel / pincushion distortion. Based on https://github.com/albumentations-team/albumentations/blob/m...
AugAdditiveLaplaceNoise(std::istream &is)
std::string str_
Definition: augmentations.h:83
Augmentation wrapper for ecvl::CoarseDropout.
AugCenterCrop(std::istream &is)
AugSalt(std::istream &is)
OneOfAugmentationContainer(double p, Ts &&... t)
void Apply(ecvl::Image &img, const ecvl::Image &gt=Image())
Generate the random value for each parameter and call the specialized augmentation functions.
AugTranspose(double p=0.5)
AugTranspose constructor.
OneOfAugmentationContainer(std::istream &is)
Augmentation wrapper for ecvl::Rotate2D.
AugPepper(const std::array< double, 2 > &p, const double &per_channel)
AugPepper constructor.
Augmentation wrapper for ecvl::ResizeDim.
AugGammaContrast(std::istream &is)
Abstract class which represent a generic Augmentation function.
AugSaltAndPepper(std::istream &is)
SequentialAugmentationContainer(std::istream &is)
void GammaContrast(const Image &src, Image &dst, double gamma)
Adjust contrast by scaling each pixel value X to 255 * ((X/255) ** gamma).
AugResizeDim(std::istream &is)
AugDivBy255()
AugDivBy255 constructor.
Augmentation wrapper for brightness adjustment.
static constexpr unsigned seed_max
AugSalt(const std::array< double, 2 > &p, const double &per_channel)
AugSalt constructor.
static const char * to_string(type t)
Definition: augmentations.h:68
AugSaltAndPepper(const std::array< double, 2 > &p, const double &per_channel)
AugSaltAndPepper constructor.
void Flip2D(const ecvl::Image &src, ecvl::Image &dst)
Flips an Image.
virtual ~Augmentation()=default
AugNormalize(std::istream &is)
Augmentation wrapper for ecvl::SaltAndPepper.
Augmentation DivBy255.
AugOpticalDistortion(std::istream &is)
AugElasticTransform(const std::array< double, 2 > &alpha, const std::array< double, 2 > &sigma, const InterpolationType &interp=InterpolationType::linear, const BorderType &border_type=BorderType::BORDER_REFLECT_101, const int &border_value=0)
AugElasticTransform constructor.
std::vector< double > vals_
Definition: augmentations.h:82
#define ECVL_ERROR_AUGMENTATION_NAME
Definition: augmentations.h:31
Augmentation wrapper for ecvl::AugScaleTo.
void Pepper(const Image &src, Image &dst, double p, bool per_channel=false, const unsigned seed=std::default_random_engine::default_seed)
Adds pepper noise (black pixels) to an Image.
void GenerateValue()
Generate the random value between min_ and max_.
AugPepper(std::istream &is)
Augmentation wrapper for ecvl::GammaContrast.
void ElasticTransform(const Image &src, Image &dst, double alpha=34., double sigma=4., InterpolationType interp=InterpolationType::linear, BorderType border_type=BorderType::BORDER_REFLECT_101, const int &border_value=0, const unsigned seed=std::default_random_engine::default_seed)
Elastic deformation of input Image. Based on https://github.com/albumentations-team/albumentations/bl...
Augmentation wrapper for ecvl::OpticalDistortion.
void Mirror2D(const ecvl::Image &src, ecvl::Image &dst)
Mirrors an Image.
AugOpticalDistortion(const std::array< float, 2 > &distort_limit, const std::array< float, 2 > &shift_limit, const InterpolationType &interp=InterpolationType::linear, const BorderType &border_type=BorderType::BORDER_REFLECT_101, const int &border_value=0)
AugOpticalDistortion constructor.
AugScaleTo(const double &new_min, const double &new_max)
AugScaleTo constructor.
Augmentation wrapper for ecvl::Salt.
AugGaussianBlur(const std::array< double, 2 > &sigma)
AugGaussianBlur constructor.
#define ECVL_ERROR_AUGMENTATION_FORMAT
Definition: augmentations.h:32
AugGammaContrast(const std::array< double, 2 > &gamma)
AugGammaContrast constructor.
Augmentation wrapper for ecvl::ResizeScale.
AugScaleTo(std::istream &is)