mirror of
https://github.com/davisking/dlib.git
synced 2024-11-01 10:14:53 +08:00
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>
This commit is contained in:
parent
631c47c7fd
commit
f775b55cd9
@ -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);
|
||||
@ -61,14 +58,82 @@ 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,
|
||||
@ -76,10 +141,10 @@ namespace dlib
|
||||
)
|
||||
{
|
||||
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)
|
||||
@ -90,6 +155,7 @@ namespace dlib
|
||||
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
|
||||
// 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);
|
||||
@ -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)
|
||||
@ -154,4 +220,3 @@ namespace dlib
|
||||
}
|
||||
|
||||
#endif // DLIB_RANDOM_cOLOR_TRANSFORM_Hh_
|
||||
|
||||
|
@ -12,33 +12,37 @@ 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()(
|
||||
@ -46,14 +50,87 @@ namespace dlib
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the color transformed version of p.
|
||||
- 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.
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
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,
|
||||
@ -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.
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -91,4 +169,3 @@ namespace dlib
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#endif // DLIB_RANDOM_cOLOR_TRANSFORM_ABSTRACT_Hh_
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user