14 #ifndef AUGMENTATIONS_H_ 15 #define AUGMENTATIONS_H_ 26 #include <unordered_map> 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"); 38 static std::istream& read_until(std::istream& is, std::string& s,
const std::string& list)
41 while (is.peek() && is && list.find(is.peek()) == list.npos) {
47 void read_vals(std::istream& is,
char closing_char)
58 }
while (next_char ==
',');
59 if (!is || next_char != closing_char) {
60 std::cerr <<
"Error while reading values of parameter " <<
name_ <<
"\n";
61 throw std::runtime_error(
"Cannot read parameter value");
89 read_until(is,
name_,
" =");
91 is >> std::ws >> next_char;
92 if (next_char !=
'=') {
93 throw std::runtime_error(
"Cannot read parameter name");
96 next_char = is.peek();
97 if (next_char ==
'[') {
102 else if (next_char ==
'(') {
107 else if (next_char ==
'"') {
110 std::getline(is,
str_,
'"');
118 std::cerr <<
"Error while reading value of parameter " <<
name_ <<
"\n";
119 throw std::runtime_error(
"Cannot read parameter value");
129 std::unordered_map<std::string, param> m_;
130 const std::string fn_name_;
141 auto it = m_.find(name);
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));
151 throw std::runtime_error(fn_name_ +
": " + name +
" is a required parameter");
158 auto it = m_.find(name);
160 auto& p = it->second;
165 throw std::runtime_error(fn_name_ +
": " + name +
" is a required parameter");
191 static std::default_random_engine
re_;
193 static constexpr
unsigned seed_min = std::numeric_limits<unsigned>::min();
194 static constexpr
unsigned seed_max = std::numeric_limits<unsigned>::max();
212 std::unordered_map<std::string, AugmentationParam>
params_;
221 x.second.GenerateValue();
233 static std::shared_ptr<Augmentation>
create(std::istream& is)
243 static std::shared_ptr<Augmentation>
create(
const std::string& name, std::istream& is);
261 for (
auto& x : augs_) {
265 std::vector<std::shared_ptr<Augmentation>> augs_;
267 template<
typename ...Ts>
305 if (
params_[
"p"].value_ <= p_) {
306 augs_[index]->Apply(img, gt);
309 std::vector<std::shared_ptr<Augmentation>> augs_;
312 template<
typename ...Ts>
327 auto m =
param::read(is,
"OneOfAugmentationContainer");
331 }
catch (std::runtime_error&) {
332 std::cout <<
ECVL_ERROR_MSG "The first parameter in OneOfAugmentationContainer must be the probability p" << std::endl;
362 std::vector<double> center_;
370 Rotate2D(gt, const_cast<Image&>(gt),
params_[
"angle"].value_, center_, scale_, interp_);
384 const std::vector<double>& center = {},
385 const double& scale = 1.,
388 : center_(center), scale_(scale), interp_(interp), gt_interp_(gt_interp)
428 std::vector<int> dims_;
435 ResizeDim(gt, const_cast<Image&>(gt), dims_, gt_interp_);
448 : dims_{ dims }, interp_(interp), gt_interp_(gt_interp) {}
456 for (
const auto& x : p.
vals_) {
457 dims_.emplace_back(static_cast<int>(x));
478 std::vector<double> scale_;
485 ResizeScale(gt, const_cast<Image&>(gt), scale_, interp_);
498 ) : scale_{ scale }, interp_(interp), gt_interp_(gt_interp){}
530 if (
params_[
"p"].value_ <= p_) {
533 Flip2D(gt, const_cast<Image&>(gt));
568 if (
params_[
"p"].value_ <= p_) {
571 Mirror2D(gt, const_cast<Image&>(gt));
649 auto m =
param::read(is,
"AugAdditiveLaplaceNoise");
680 auto m =
param::read(is,
"AugAdditivePoissonNoise");
729 bool per_channel =
params_[
"per_channel"].value_ <= per_channel_ ? true :
false;
739 AugCoarseDropout(
const std::array<double, 2>& p,
const std::array<double, 2>& drop_size,
const double& per_channel) : per_channel_(per_channel)
741 assert(per_channel >= 0 && per_channel <= 1);
759 per_channel_ = p.
vals_[0];
773 if (
params_[
"p"].value_ <= p_) {
839 std::array<float, 2> distort_limit_;
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_));
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_));
863 const std::array<float, 2>& distort_limit,
866 const int& border_value = 0)
867 : distort_limit_(distort_limit), interp_(interp), border_type_(border_type), border_value_(border_value)
886 distort_limit_ = { static_cast<float>(p.
vals_[0]), static_cast<float>(p.
vals_[1]) };
895 if (p.
str_ ==
"constant") {
898 else if (p.
str_ ==
"replicate") {
901 else if (p.
str_ ==
"reflect") {
904 else if (p.
str_ ==
"wrap") {
907 else if (p.
str_ ==
"reflect_101") {
910 else if (p.
str_ ==
"transparent") {
914 throw std::runtime_error(
"AugGridDistortion: invalid border type");
920 border_value_ = static_cast<int>(p.
vals_[0]);
937 border_value_, static_cast<unsigned>(
params_[
"seed"].value_));
940 border_type_, border_value_, static_cast<unsigned>(
params_[
"seed"].value_));
953 const std::array<double, 2>& sigma,
956 const int& border_value = 0)
957 : interp_(interp), border_type_(border_type), border_value_(border_value)
986 if (p.
str_ ==
"constant") {
989 else if (p.
str_ ==
"replicate") {
992 else if (p.
str_ ==
"reflect") {
995 else if (p.
str_ ==
"wrap") {
998 else if (p.
str_ ==
"reflect_101") {
1001 else if (p.
str_ ==
"transparent") {
1005 throw std::runtime_error(
"AugGridDistortion: invalid border type");
1011 border_value_ = static_cast<int>(p.
vals_[0]);
1021 std::array<float, 2> distort_limit_;
1022 std::array<float, 2> shift_limit_;
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_));
1046 const std::array<float, 2>& shift_limit,
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)
1065 distort_limit_ = { static_cast<float>(p.
vals_[0]), static_cast<float>(p.
vals_[1]) };
1068 shift_limit_ = { static_cast<float>(p.
vals_[0]), static_cast<float>(p.
vals_[1]) };
1077 if (p.
str_ ==
"constant") {
1080 else if (p.
str_ ==
"replicate") {
1083 else if (p.
str_ ==
"reflect") {
1086 else if (p.
str_ ==
"wrap") {
1089 else if (p.
str_ ==
"reflect_101") {
1092 else if (p.
str_ ==
"transparent") {
1096 throw std::runtime_error(
"AugGridDistortion: invalid border type");
1102 border_value_ = static_cast<int>(p.
vals_[0]);
1112 double per_channel_;
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_));
1125 AugSalt(
const std::array<double, 2>& p,
const double& per_channel) : per_channel_(per_channel)
1127 assert(per_channel >= 0 && per_channel <= 1);
1145 per_channel_ = p.
vals_[0];
1155 double per_channel_;
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_));
1168 AugPepper(
const std::array<double, 2>& p,
const double& per_channel) : per_channel_(per_channel)
1170 assert(per_channel >= 0 && per_channel <= 1);
1188 per_channel_ = p.
vals_[0];
1198 double per_channel_;
1202 bool per_channel =
params_[
"per_channel"].value_ <= per_channel_ ? true :
false;
1211 AugSaltAndPepper(
const std::array<double, 2>& p,
const double& per_channel) : per_channel_(per_channel)
1213 assert(per_channel >= 0 && per_channel <= 1);
1231 per_channel_ = p.
vals_[0];
1241 double mean_ = 0., std_ = 1.;
1243 std::vector<double> ch_mean_;
1244 std::vector<double> ch_std_;
1263 AugNormalize(
const double& mean,
const double& std) : mean_(mean), std_(std), per_channel_(false) {}
1270 AugNormalize(
const std::vector<double>& mean,
const std::vector<double>& std) : ch_mean_(mean), ch_std_(std), per_channel_(true) {}
1277 m.GenericGet(
"mean",
true, p);
1280 per_channel_ =
false;
1284 per_channel_ =
true;
1287 throw std::runtime_error(
"AugNormalize: invalid mean type");
1290 if (per_channel_ ==
false) {
1307 std::vector<int> size_;
1312 if (!gt.IsEmpty()) {
1313 CenterCrop(gt, const_cast<Image&>(gt), size_);
1329 for (
const auto& x : p.
vals_) {
1330 size_.emplace_back(static_cast<int>(x));
1343 double divisor_, divisor_gt_;
1350 if (!gt.IsEmpty()) {
1352 const_cast<Image&>(gt).Div(divisor_gt_);
1361 AugToFloat32(
const double& divisor = 1.,
const double& divisor_gt = 1.) : divisor_{ divisor }, divisor_gt_{ divisor_gt } {}
1368 divisor_ = p.
vals_[0];
1370 divisor_gt_ = p.
vals_[0];
1386 if (!gt.IsEmpty()) {
1387 const_cast<Image&>(gt).Div(255);
1402 double new_min_, new_max_;
1406 ScaleTo(img, img, new_min_, new_max_);
1414 AugScaleTo(
const double& new_min,
const double& new_max) : new_min_{ new_min }, new_max_{ new_max } {}
1421 new_min_ = p.
vals_[0];
1424 new_max_ = p.
vals_[0];
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.
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)
AugBrightness(std::istream &is)
AugRotate(std::istream &is)
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)
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)
AugmentationParam()=default
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 >_interp=InterpolationType::nearest)
AugResizeDim constructor.
InterpolationType
Enum class representing the ECVL interpolation types.
void AdditiveLaplaceNoise(const Image &src, Image &dst, double std_dev)
Adds Laplace distributed noise to an Image.
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.
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 > ¢er={}, const double &scale=1., const InterpolationType &interp=InterpolationType::linear, const InterpolationType >_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)
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.
void Normalize(const Image &src, Image &dst, const double &mean, const double &std)
Normalize Image image with mean and standard deviation.
void ConvertTo(DataType dtype, bool saturate=true)
Convert Image to another DataType.
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.
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 > ¢er={}, 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.
SequentialAugmentationContainer(Ts &&... t)
Augmentation wrapper for ecvl::AdditiveLaplaceNoise.
AugResizeScale(const std::vector< double > &scale, const InterpolationType &interp=InterpolationType::linear, const InterpolationType >_interp=InterpolationType::nearest)
AugResizeScale constructor.
Augmentation wrapper for ecvl::Pepper.
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)
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 >=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)
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.
AugOpticalDistortion(std::istream &is)
std::vector< double > vals_
#define ECVL_ERROR_AUGMENTATION_NAME
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
AugGammaContrast(const std::array< double, 2 > &gamma)
AugGammaContrast constructor.
Augmentation wrapper for ecvl::ResizeScale.
AugScaleTo(std::istream &is)