|
|
|
@ -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_
|
|
|
|
|
|
|
|
|
|