Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from davisking:master #64

Merged
merged 1 commit into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 88 additions & 23 deletions dlib/image_transforms/random_color_transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,31 @@
#include "../image_processing/generic_image.h"
#include "../pixel.h"
#include "../rand.h"
#include "../matrix.h"

namespace dlib
{

// ----------------------------------------------------------------------------------------

class random_color_transform
class color_transform
{
public:

random_color_transform (
dlib::rand& rnd,
const double gamma_magnitude = 0.5,
const double color_magnitude = 0.2
)
color_transform(
const double gamma_ = 1,
const double red_scale_ = 1,
const double green_scale_ = 1,
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.
const double gamma = std::max(0.0, 1 + gamma_magnitude*(rnd.get_random_double() - 0.5));

// pick a random color balancing scheme.
double red_scale = 1 - rnd.get_random_double() * color_magnitude;
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});
DLIB_CASSERT(gamma_ >= 0)
DLIB_CASSERT(0 <= red_scale_ && red_scale_ <= 1)
DLIB_CASSERT(0 <= green_scale_ && green_scale_ <= 1)
DLIB_CASSERT(0 <= blue_scale_ && blue_scale_ <= 1)
const double m = 255 * std::max({red_scale_, green_scale_, blue_scale_});
red_scale /= m;
green_scale /= m;
blue_scale /= m;

// Now compute a lookup table for all the color channels. The table tells us
// what the transform does.
table.resize(256 * 3);
Expand All @@ -61,25 +58,93 @@ namespace dlib
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:
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>
void disturb_colors (
color_transform disturb_colors (
image_type& img_,
dlib::rand& rnd,
const double gamma_magnitude = 0.5,
const double color_magnitude = 0.2
)
{
if (gamma_magnitude == 0 && color_magnitude == 0)
return;
return {};

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 c = 0; c < img.nc(); ++c)
Expand All @@ -90,6 +155,7 @@ namespace dlib
assign_pixel(img[r][c], temp);
}
}
return tform;
}

// ----------------------------------------------------------------------------------------
Expand All @@ -111,9 +177,9 @@ namespace dlib
// Except that we used the square root of the eigenvalues (which I'm pretty sure is
// what the authors intended).
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.4907, -24.0199, 7.27653;
-68.4907, -24.0199, 7.27653;
matrix<double,3,1> v;
v = rnd.get_random_gaussian(),rnd.get_random_gaussian(),rnd.get_random_gaussian();
v = round(tform*0.1*v);
Expand All @@ -132,7 +198,7 @@ namespace dlib
gtable[i] = put_in_range(0, 255, i+goffset);
btable[i] = put_in_range(0, 255, i+boffset);
}

// now transform the image.
image_view<image_type> img(img_);
for (long r = 0; r < img.nr(); ++r)
Expand All @@ -154,4 +220,3 @@ namespace dlib
}

#endif // DLIB_RANDOM_cOLOR_TRANSFORM_Hh_

113 changes: 95 additions & 18 deletions dlib/image_transforms/random_color_transform_abstract.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,48 +12,125 @@ namespace dlib

// ----------------------------------------------------------------------------------------

class random_color_transform
class color_transform
{
/*!
WHAT THIS OBJECT REPRESENTS
This object generates a random color balancing and gamma correction
transform. It then allows you to apply that specific transform to as many
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.
!*/

public:

random_color_transform (
dlib::rand& rnd,
const double gamma_magnitude = 0.5,
const double color_magnitude = 0.2
color_transform (
const double gamma = 1.0,
const double red_scale = 1.0,
const double green_scale = 1.0,
const double blue_scale = 1.0
);
/*!
requires
- 0 <= gamma_magnitude
- 0 <= color_magnitude <= 1
- 0 <= gamma
- 0 <= red_scale <= 1
- 0 <= green_scale <= 1
- 0 <= blue_scale <= 1
ensures
- This constructor generates a random color transform which can be applied
by calling this object's operator() method.
- This constructor generates a color transform which can be applied by
calling this object's operator() method.
- The color transform is a gamma correction and color rebalancing. If
gamma_magnitude == 0 and color_magnitude == 0 then the transform doesn't
change any colors at all. However, the larger these parameters the more
noticeable the resulting transform.
gamma == 1, red_scale == 1, green_scale == 1 and blue_scale == 1 then
the transform doesn't change any colors at all. However, the farther
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 p
) const;
/*!
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>
void disturb_colors (
color_transform disturb_colors (
image_type& img,
dlib::rand& rnd,
const double gamma_magnitude = 0.5,
Expand All @@ -62,11 +139,12 @@ namespace dlib
/*!
requires
- image_type == an image object that implements the interface defined in
dlib/image_processing/generic_image.h
dlib/image_processing/generic_image.h
ensures
- Applies a random color transform to the given image. This is done by
creating a random_color_transform with the given parameters and then
transforming each pixel in the image with the resulting transform.
- Returns the color transform used to transform the given image.
!*/

// ----------------------------------------------------------------------------------------
Expand All @@ -91,4 +169,3 @@ namespace dlib
// ----------------------------------------------------------------------------------------

#endif // DLIB_RANDOM_cOLOR_TRANSFORM_ABSTRACT_Hh_

Loading