Add color transform and inv color transform (#2914)

* add color transform

* simplify inv_color_transform

* fix typo

* Update dlib/image_transforms/random_color_transform.h

* Update dlib/image_transforms/random_color_transform.h

---------

Co-authored-by: Davis E. King <davis685@gmail.com>
pull/2918/head
Adrià Arrufat 7 months ago committed by GitHub
parent 631c47c7fd
commit f775b55cd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -7,34 +7,31 @@
#include "../image_processing/generic_image.h" #include "../image_processing/generic_image.h"
#include "../pixel.h" #include "../pixel.h"
#include "../rand.h" #include "../rand.h"
#include "../matrix.h"
namespace dlib namespace dlib
{ {
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
class random_color_transform class color_transform
{ {
public: public:
color_transform(
random_color_transform ( const double gamma_ = 1,
dlib::rand& rnd, const double red_scale_ = 1,
const double gamma_magnitude = 0.5, const double green_scale_ = 1,
const double color_magnitude = 0.2 const double blue_scale_ = 1
) ) : gamma(gamma_), red_scale(red_scale_), green_scale(green_scale_), blue_scale(blue_scale_)
{ {
// pick a random gamma correction factor. DLIB_CASSERT(gamma_ >= 0)
const double gamma = std::max(0.0, 1 + gamma_magnitude*(rnd.get_random_double() - 0.5)); DLIB_CASSERT(0 <= red_scale_ && red_scale_ <= 1)
DLIB_CASSERT(0 <= green_scale_ && green_scale_ <= 1)
// pick a random color balancing scheme. DLIB_CASSERT(0 <= blue_scale_ && blue_scale_ <= 1)
double red_scale = 1 - rnd.get_random_double() * color_magnitude; const double m = 255 * std::max({red_scale_, green_scale_, blue_scale_});
double green_scale = 1 - rnd.get_random_double() * color_magnitude;
double blue_scale = 1 - rnd.get_random_double() * color_magnitude;
const double m = 255 * std::max({red_scale, green_scale, blue_scale});
red_scale /= m; red_scale /= m;
green_scale /= m; green_scale /= m;
blue_scale /= m; blue_scale /= m;
// Now compute a lookup table for all the color channels. The table tells us // Now compute a lookup table for all the color channels. The table tells us
// what the transform does. // what the transform does.
table.resize(256 * 3); table.resize(256 * 3);
@ -61,14 +58,82 @@ namespace dlib
return p; return p;
} }
double get_gamma() const { return gamma; }
double get_red_scale() const { return red_scale; }
double get_green_scale() const { return green_scale; }
double get_blue_scale() const { return blue_scale; }
private:
std::vector<unsigned char> table;
double gamma;
double red_scale;
double green_scale;
double blue_scale;
};
class inv_color_transform
{
public:
inv_color_transform(
const color_transform& tform
)
{
const auto gamma = tform.get_gamma();
const auto red_scale = tform.get_red_scale();
const auto green_scale = tform.get_green_scale();
const auto blue_scale = tform.get_blue_scale();
// Now compute a lookup table for all the color channels. The table tells us
// what the transform does.
table.resize(256 * 3);
unsigned long i = 0;
for (int k = 0; k < 256; ++k)
{
table[i++] = static_cast<unsigned char>(std::pow(k / 255.0, 1 / gamma) / red_scale + 0.5);
}
for (int k = 0; k < 256; ++k)
{
table[i++] = static_cast<unsigned char>(std::pow(k / 255.0, 1 / gamma) / green_scale + 0.5);
}
for (int k = 0; k < 256; ++k)
{
table[i++] = static_cast<unsigned char>(std::pow(k / 255.0, 1 / gamma) / blue_scale + 0.5);
}
}
rgb_pixel operator()(rgb_pixel p) const
{
p.red = table[static_cast<unsigned int>(p.red)];
p.green = table[static_cast<unsigned int>(p.green + 256)];
p.blue = table[static_cast<unsigned int>(p.blue + 512)];
return p;
}
private: private:
std::vector<unsigned char> table; std::vector<unsigned char> table;
}; };
// ----------------------------------------------------------------------------------------
inline color_transform random_color_transform (
dlib::rand& rnd,
const double gamma_magnitude = 0.5,
const double color_magnitude = 0.2
)
{
// pick a random gamma correction factor.
const double gamma = std::max(0.0, 1 + gamma_magnitude * (rnd.get_random_double() - 0.5));
// pick a random color balancing scheme.
const double red_scale = 1 - rnd.get_random_double() * color_magnitude;
const double green_scale = 1 - rnd.get_random_double() * color_magnitude;
const double blue_scale = 1 - rnd.get_random_double() * color_magnitude;
return color_transform(gamma, red_scale, green_scale, blue_scale);
}
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename image_type> template <typename image_type>
void disturb_colors ( color_transform disturb_colors (
image_type& img_, image_type& img_,
dlib::rand& rnd, dlib::rand& rnd,
const double gamma_magnitude = 0.5, const double gamma_magnitude = 0.5,
@ -76,10 +141,10 @@ namespace dlib
) )
{ {
if (gamma_magnitude == 0 && color_magnitude == 0) if (gamma_magnitude == 0 && color_magnitude == 0)
return; return {};
image_view<image_type> img(img_); image_view<image_type> img(img_);
random_color_transform tform(rnd, gamma_magnitude, color_magnitude); const auto tform = random_color_transform(rnd, gamma_magnitude, color_magnitude);
for (long r = 0; r < img.nr(); ++r) for (long r = 0; r < img.nr(); ++r)
{ {
for (long c = 0; c < img.nc(); ++c) for (long c = 0; c < img.nc(); ++c)
@ -90,6 +155,7 @@ namespace dlib
assign_pixel(img[r][c], temp); assign_pixel(img[r][c], temp);
} }
} }
return tform;
} }
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -111,9 +177,9 @@ namespace dlib
// Except that we used the square root of the eigenvalues (which I'm pretty sure is // Except that we used the square root of the eigenvalues (which I'm pretty sure is
// what the authors intended). // what the authors intended).
matrix<double,3,3> tform; matrix<double,3,3> tform;
tform = -66.379, 25.094, 6.79698, tform = -66.379, 25.094, 6.79698,
-68.0492, -0.302309, -13.9539, -68.0492, -0.302309, -13.9539,
-68.4907, -24.0199, 7.27653; -68.4907, -24.0199, 7.27653;
matrix<double,3,1> v; matrix<double,3,1> v;
v = rnd.get_random_gaussian(),rnd.get_random_gaussian(),rnd.get_random_gaussian(); v = rnd.get_random_gaussian(),rnd.get_random_gaussian(),rnd.get_random_gaussian();
v = round(tform*0.1*v); v = round(tform*0.1*v);
@ -132,7 +198,7 @@ namespace dlib
gtable[i] = put_in_range(0, 255, i+goffset); gtable[i] = put_in_range(0, 255, i+goffset);
btable[i] = put_in_range(0, 255, i+boffset); btable[i] = put_in_range(0, 255, i+boffset);
} }
// now transform the image. // now transform the image.
image_view<image_type> img(img_); image_view<image_type> img(img_);
for (long r = 0; r < img.nr(); ++r) for (long r = 0; r < img.nr(); ++r)
@ -154,4 +220,3 @@ namespace dlib
} }
#endif // DLIB_RANDOM_cOLOR_TRANSFORM_Hh_ #endif // DLIB_RANDOM_cOLOR_TRANSFORM_Hh_

@ -12,33 +12,96 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
class random_color_transform class color_transform
{ {
/*! /*!
WHAT THIS OBJECT REPRESENTS WHAT THIS OBJECT REPRESENTS
This object generates a random color balancing and gamma correction This object generates a color balancing and gamma correction transform.
transform. It then allows you to apply that specific transform to as many It then allows you to apply that specific transform to as many
rgb_pixel objects as you like. rgb_pixel objects as you like.
!*/ !*/
public: public:
random_color_transform ( color_transform (
dlib::rand& rnd, const double gamma = 1.0,
const double gamma_magnitude = 0.5, const double red_scale = 1.0,
const double color_magnitude = 0.2 const double green_scale = 1.0,
const double blue_scale = 1.0
); );
/*! /*!
requires requires
- 0 <= gamma_magnitude - 0 <= gamma
- 0 <= color_magnitude <= 1 - 0 <= red_scale <= 1
- 0 <= green_scale <= 1
- 0 <= blue_scale <= 1
ensures ensures
- This constructor generates a random color transform which can be applied - This constructor generates a color transform which can be applied by
by calling this object's operator() method. calling this object's operator() method.
- The color transform is a gamma correction and color rebalancing. If - The color transform is a gamma correction and color rebalancing. If
gamma_magnitude == 0 and color_magnitude == 0 then the transform doesn't gamma == 1, red_scale == 1, green_scale == 1 and blue_scale == 1 then
change any colors at all. However, the larger these parameters the more the transform doesn't change any colors at all. However, the farther
noticeable the resulting transform. away from 1 these parameters are, the more noticeable the resulting
transform.
!*/
rgb_pixel operator()(
rgb_pixel p
) const;
/*!
ensures
- returns the color transformed version of p.
!*/
double get_gamma() const;
/*!
ensures
- returns the gamma used in this color transform.
!*/
double get_red_scale() const;
/*!
ensures
- returns the red scale used in this color transform.
!*/
double get_green_scale() const;
/*!
ensures
- returns the green scale used in this color transform.
!*/
double get_blue_scale() const;
/*!
ensures
- returns the blue scale used in this color transform.
!*/
};
// ----------------------------------------------------------------------------------------
class inv_color_transform
{
/*!
WHAT THIS OBJECT REPRESENTS
This object generates a color balancing and gamma correction transform.
It then allows you to apply that specific transform to as many
rgb_pixel objects as you like. In particular, it generates the inverse
transform of the one constructed by color_transform with the same
parameters.
!*/
public:
color_transform (
const color_transform& tform
);
/*!
ensures
- This constructor generates a color transform which can be applied by
calling this object's operator() method.
- The resulting transform is the inverse of tform, which can be used to
undo the effect of tform.
!*/ !*/
rgb_pixel operator()( rgb_pixel operator()(
@ -46,14 +109,28 @@ namespace dlib
) const; ) const;
/*! /*!
ensures ensures
- returns the color transformed version of p. - returns the color transformed version of p.
!*/ !*/
}; };
// ----------------------------------------------------------------------------------------
inline color_transform random_color_transform (
dlib::rand& rnd,
const double gamma_magnitude = 0.5,
const double color_magnitude = 0.2
);
/*!
ensures
- returns a random color balancing and gamma corection transform. It then
allows you to apply that specific transform to as many rgb_pixel objects as
you like.
!*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
template <typename image_type> template <typename image_type>
void disturb_colors ( color_transform disturb_colors (
image_type& img, image_type& img,
dlib::rand& rnd, dlib::rand& rnd,
const double gamma_magnitude = 0.5, const double gamma_magnitude = 0.5,
@ -62,11 +139,12 @@ namespace dlib
/*! /*!
requires requires
- image_type == an image object that implements the interface defined in - image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h dlib/image_processing/generic_image.h
ensures ensures
- Applies a random color transform to the given image. This is done by - Applies a random color transform to the given image. This is done by
creating a random_color_transform with the given parameters and then creating a random_color_transform with the given parameters and then
transforming each pixel in the image with the resulting transform. transforming each pixel in the image with the resulting transform.
- Returns the color transform used to transform the given image.
!*/ !*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -91,4 +169,3 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
#endif // DLIB_RANDOM_cOLOR_TRANSFORM_ABSTRACT_Hh_ #endif // DLIB_RANDOM_cOLOR_TRANSFORM_ABSTRACT_Hh_

Loading…
Cancel
Save