Compare commits
3 Commits
071e064698
...
7d9e250c68
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d9e250c68 | |||
| 8dd297434b | |||
| 0e7aba5991 |
@@ -5,36 +5,36 @@
|
|||||||
|
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
ColourExtractor::ColourExtractor(size_t h_levels, size_t s_levels,
|
ColourExtractor::ColourExtractor(size_t h_levels, size_t s_levels,
|
||||||
size_t l_levels)
|
size_t v_levels)
|
||||||
:m_pixels(NULL), m_max_colour_count(0), m_h_levels(h_levels),
|
:m_pixels(NULL), m_max_colour_count(0), m_h_levels(h_levels),
|
||||||
m_s_levels(s_levels), m_l_levels(l_levels)
|
m_s_levels(s_levels), m_v_levels(v_levels)
|
||||||
{
|
{
|
||||||
m_pixels = new size_t[m_h_levels * m_s_levels * m_l_levels];
|
m_pixels = new size_t[m_h_levels * m_s_levels * m_v_levels];
|
||||||
memset(m_pixels, 0, m_h_levels * m_s_levels * m_l_levels * sizeof(size_t));
|
memset(m_pixels, 0, m_h_levels * m_s_levels * m_v_levels * sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROTECTED FUNCS
|
// PROTECTED FUNCS
|
||||||
size_t ColourExtractor::quantize(struct ColourHSL hsl) const
|
size_t ColourExtractor::quantize(struct ColourHSV hsv) const
|
||||||
{
|
{
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
|
|
||||||
size_t h_quant = 0;
|
size_t h_quant = 0;
|
||||||
size_t s_quant = 0;
|
size_t s_quant = 0;
|
||||||
size_t l_quant = 0;
|
size_t v_quant = 0;
|
||||||
|
|
||||||
l_quant = static_cast<size_t>(round(hsl.l * (m_l_levels - 1)));
|
v_quant = static_cast<size_t>(round(hsv.v * (m_v_levels - 1)));
|
||||||
if (0 == l_quant)
|
if (0 == v_quant)
|
||||||
{
|
{
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_quant = static_cast<size_t>(round(hsl.s * (m_s_levels - 1)));
|
s_quant = static_cast<size_t>(round(hsv.s * (m_s_levels - 1)));
|
||||||
if (0 == s_quant)
|
if (0 == s_quant)
|
||||||
{
|
{
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
h_quant = static_cast<size_t>(round(hsl.h / 360.0 * (m_h_levels - 1)));
|
h_quant = static_cast<size_t>(round(hsv.h / 360.0 * (m_h_levels - 1)));
|
||||||
|
|
||||||
end:
|
end:
|
||||||
result += h_quant;
|
result += h_quant;
|
||||||
@@ -42,21 +42,21 @@ size_t ColourExtractor::quantize(struct ColourHSL hsl) const
|
|||||||
result *= m_s_levels;
|
result *= m_s_levels;
|
||||||
result += s_quant;
|
result += s_quant;
|
||||||
|
|
||||||
result *= m_l_levels;
|
result *= m_v_levels;
|
||||||
result += l_quant;
|
result += v_quant;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ColourHSL ColourExtractor::dequantize(size_t colour) const
|
struct ColourHSV ColourExtractor::dequantize(size_t colour) const
|
||||||
{
|
{
|
||||||
struct ColourHSL result;
|
struct ColourHSV result;
|
||||||
size_t h_quant;
|
size_t h_quant;
|
||||||
size_t s_quant;
|
size_t s_quant;
|
||||||
size_t l_quant;
|
size_t v_quant;
|
||||||
|
|
||||||
l_quant = colour % m_l_levels;
|
v_quant = colour % m_v_levels;
|
||||||
colour /= m_l_levels;
|
colour /= m_v_levels;
|
||||||
|
|
||||||
s_quant = colour % m_s_levels;
|
s_quant = colour % m_s_levels;
|
||||||
colour /= m_s_levels;
|
colour /= m_s_levels;
|
||||||
@@ -65,31 +65,31 @@ struct ColourHSL ColourExtractor::dequantize(size_t colour) const
|
|||||||
|
|
||||||
result.h = static_cast<double>(h_quant) * 360.0 / (m_h_levels - 1);
|
result.h = static_cast<double>(h_quant) * 360.0 / (m_h_levels - 1);
|
||||||
result.s = static_cast<double>(s_quant) / (m_s_levels - 1);
|
result.s = static_cast<double>(s_quant) / (m_s_levels - 1);
|
||||||
result.l = static_cast<double>(l_quant) / (m_l_levels - 1);
|
result.v = static_cast<double>(v_quant) / (m_v_levels - 1);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUBLIC FUNCS
|
// PUBLIC FUNCS
|
||||||
void ColourExtractor::get_quantization_levels(size_t& h_levels,
|
void ColourExtractor::get_quantization_levels(size_t& h_levels,
|
||||||
size_t& s_levels, size_t& l_levels) const
|
size_t& s_levels, size_t& v_levels) const
|
||||||
{
|
{
|
||||||
h_levels = m_h_levels;
|
h_levels = m_h_levels;
|
||||||
s_levels = m_s_levels;
|
s_levels = m_s_levels;
|
||||||
l_levels = m_l_levels;
|
v_levels = m_v_levels;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColourExtractor::set_quantization_levels(size_t h_levels, size_t s_levels,
|
void ColourExtractor::set_quantization_levels(size_t h_levels, size_t s_levels,
|
||||||
size_t l_levels)
|
size_t v_levels)
|
||||||
{
|
{
|
||||||
delete[] m_pixels;
|
delete[] m_pixels;
|
||||||
|
|
||||||
m_h_levels = h_levels;
|
m_h_levels = h_levels;
|
||||||
m_s_levels = s_levels;
|
m_s_levels = s_levels;
|
||||||
m_l_levels = l_levels;
|
m_v_levels = v_levels;
|
||||||
|
|
||||||
m_pixels = new size_t[m_h_levels * m_s_levels * m_l_levels];
|
m_pixels = new size_t[m_h_levels * m_s_levels * m_v_levels];
|
||||||
memset(m_pixels, 0, m_h_levels * m_s_levels * m_l_levels * sizeof(size_t));
|
memset(m_pixels, 0, m_h_levels * m_s_levels * m_v_levels * sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ColourExtractor::get_h_quantization_levels() const
|
size_t ColourExtractor::get_h_quantization_levels() const
|
||||||
@@ -103,8 +103,8 @@ void ColourExtractor::set_h_quantization_levels(size_t h_levels)
|
|||||||
|
|
||||||
m_h_levels = h_levels;
|
m_h_levels = h_levels;
|
||||||
|
|
||||||
m_pixels = new size_t[m_h_levels * m_s_levels * m_l_levels];
|
m_pixels = new size_t[m_h_levels * m_s_levels * m_v_levels];
|
||||||
memset(m_pixels, 0, m_h_levels * m_s_levels * m_l_levels * sizeof(size_t));
|
memset(m_pixels, 0, m_h_levels * m_s_levels * m_v_levels * sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ColourExtractor::get_s_quantization_levels() const
|
size_t ColourExtractor::get_s_quantization_levels() const
|
||||||
@@ -118,30 +118,30 @@ void ColourExtractor::set_s_quantization_levels(size_t s_levels)
|
|||||||
|
|
||||||
m_s_levels = s_levels;
|
m_s_levels = s_levels;
|
||||||
|
|
||||||
m_pixels = new size_t[m_h_levels * m_s_levels * m_l_levels];
|
m_pixels = new size_t[m_h_levels * m_s_levels * m_v_levels];
|
||||||
memset(m_pixels, 0, m_h_levels * m_s_levels * m_l_levels * sizeof(size_t));
|
memset(m_pixels, 0, m_h_levels * m_s_levels * m_v_levels * sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ColourExtractor::get_v_quantization_levels() const
|
size_t ColourExtractor::get_v_quantization_levels() const
|
||||||
{
|
{
|
||||||
return m_l_levels;
|
return m_v_levels;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColourExtractor::set_v_quantization_levels(size_t l_levels)
|
void ColourExtractor::set_v_quantization_levels(size_t v_levels)
|
||||||
{
|
{
|
||||||
delete[] m_pixels;
|
delete[] m_pixels;
|
||||||
|
|
||||||
m_l_levels = l_levels;
|
m_v_levels = v_levels;
|
||||||
|
|
||||||
m_pixels = new size_t[m_h_levels * m_s_levels * m_l_levels];
|
m_pixels = new size_t[m_h_levels * m_s_levels * m_v_levels];
|
||||||
memset(m_pixels, 0, m_h_levels * m_s_levels * m_l_levels * sizeof(size_t));
|
memset(m_pixels, 0, m_h_levels * m_s_levels * m_v_levels * sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColourExtractor::add_pixel(struct ColourHSL hsl)
|
void ColourExtractor::add_pixel(struct ColourHSV hsv)
|
||||||
{
|
{
|
||||||
size_t colour_quant;
|
size_t colour_quant;
|
||||||
|
|
||||||
colour_quant = quantize(hsl);
|
colour_quant = quantize(hsv);
|
||||||
m_pixels[colour_quant] += 1;
|
m_pixels[colour_quant] += 1;
|
||||||
|
|
||||||
if (m_max_colour_count < m_pixels[colour_quant])
|
if (m_max_colour_count < m_pixels[colour_quant])
|
||||||
@@ -152,22 +152,22 @@ void ColourExtractor::add_pixel(struct ColourHSL hsl)
|
|||||||
|
|
||||||
void ColourExtractor::clear_pixels()
|
void ColourExtractor::clear_pixels()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_h_levels * m_s_levels * m_l_levels; ++i)
|
for (size_t i = 0; i < m_h_levels * m_s_levels * m_v_levels; ++i)
|
||||||
{
|
{
|
||||||
m_pixels[i] = 0;
|
m_pixels[i] = 0;
|
||||||
}
|
}
|
||||||
m_max_colour_count = 0;
|
m_max_colour_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ColourHSL ColourExtractor::extract_colour() const
|
struct ColourHSV ColourExtractor::extract_colour() const
|
||||||
{
|
{
|
||||||
struct ColourHSL result = {0.0, 0.0, 0.0};
|
struct ColourHSV result = {0.0, 0.0, 0.0};
|
||||||
struct ColourHSL temp_colour;
|
struct ColourHSV temp_colour;
|
||||||
size_t max_colour_value = 0;
|
size_t max_colour_value = 0;
|
||||||
size_t temp_colour_value;
|
size_t temp_colour_value;
|
||||||
double temp_colour_weight;
|
double temp_colour_weight;
|
||||||
|
|
||||||
for (size_t i = 0; i < m_h_levels * m_s_levels * m_l_levels; ++i)
|
for (size_t i = 0; i < m_h_levels * m_s_levels * m_v_levels; ++i)
|
||||||
{
|
{
|
||||||
if (0 == m_pixels[i])
|
if (0 == m_pixels[i])
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
class ColourExtractor
|
class ColourExtractor
|
||||||
{
|
{
|
||||||
protected:
|
private:
|
||||||
// Holds all quantized pixels
|
// Holds all quantized pixels
|
||||||
size_t* m_pixels;
|
size_t* m_pixels;
|
||||||
|
|
||||||
@@ -17,30 +17,30 @@ protected:
|
|||||||
// Quantization levels for the HSV colours
|
// Quantization levels for the HSV colours
|
||||||
size_t m_h_levels;
|
size_t m_h_levels;
|
||||||
size_t m_s_levels;
|
size_t m_s_levels;
|
||||||
size_t m_l_levels;
|
size_t m_v_levels;
|
||||||
|
|
||||||
// Quantizes the colour
|
// Quantizes the colour
|
||||||
size_t quantize(struct ColourHSL hsl) const;
|
size_t quantize(struct ColourHSV hsv) const;
|
||||||
|
|
||||||
// Dequantizes the colour
|
// Dequantizes the colour
|
||||||
struct ColourHSL dequantize(size_t colour) const;
|
struct ColourHSV dequantize(size_t colour) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Evaluates the given colour based on its weight
|
// Evaluates the given colour based on its weight
|
||||||
virtual size_t evaluate_colour(struct ColourHSL hsl, double weight)
|
virtual size_t evaluate_colour(struct ColourHSV hsv, double weight)
|
||||||
const = 0;
|
const = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Params: HSV quantization levels
|
// Params: HSV quantization levels
|
||||||
ColourExtractor(size_t h_levels = 36, size_t s_levels = 10,
|
ColourExtractor(size_t h_levels = 36, size_t s_levels = 10,
|
||||||
size_t l_levels = 10);
|
size_t v_levels = 10);
|
||||||
|
|
||||||
void get_quantization_levels(size_t& h_levels, size_t& s_levels,
|
void get_quantization_levels(size_t& h_levels, size_t& s_levels,
|
||||||
size_t& l_levels) const;
|
size_t& v_levels) const;
|
||||||
|
|
||||||
// Note: clears all pixels
|
// Note: clears all pixels
|
||||||
void set_quantization_levels(size_t h_levels, size_t s_levels,
|
void set_quantization_levels(size_t h_levels, size_t s_levels,
|
||||||
size_t l_levels);
|
size_t v_levels);
|
||||||
|
|
||||||
size_t get_h_quantization_levels() const;
|
size_t get_h_quantization_levels() const;
|
||||||
|
|
||||||
@@ -55,16 +55,16 @@ public:
|
|||||||
size_t get_v_quantization_levels() const;
|
size_t get_v_quantization_levels() const;
|
||||||
|
|
||||||
// Note: clears all pixels
|
// Note: clears all pixels
|
||||||
void set_v_quantization_levels(size_t l_levels);
|
void set_v_quantization_levels(size_t v_levels);
|
||||||
|
|
||||||
// Adds a pixel to be considered for extraction
|
// Adds a pixel to be considered for extraction
|
||||||
void add_pixel(struct ColourHSL hsl);
|
void add_pixel(struct ColourHSV hsv);
|
||||||
|
|
||||||
// Clears all pixels
|
// Clears all pixels
|
||||||
void clear_pixels();
|
void clear_pixels();
|
||||||
|
|
||||||
// Extracts a single colour from all added pixels
|
// Extracts a single colour from all added pixels
|
||||||
struct ColourHSL extract_colour() const;
|
struct ColourHSV extract_colour() const;
|
||||||
|
|
||||||
~ColourExtractor();
|
~ColourExtractor();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,36 +2,31 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
ComplimentaryColourExtractor::ComplimentaryColourExtractor(struct ColourHSL hsl,
|
ComplimentaryColourExtractor::ComplimentaryColourExtractor(struct ColourHSV hsv,
|
||||||
size_t h_levels, size_t s_levels, size_t v_levels)
|
size_t h_levels, size_t s_levels, size_t v_levels)
|
||||||
:ColourExtractor(h_levels, s_levels, v_levels), m_main_colour(hsl)
|
:ColourExtractor(h_levels, s_levels, v_levels), m_main_colour(hsv)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROTECTED FUNCS
|
// PROTECTED FUNCS
|
||||||
size_t ComplimentaryColourExtractor::evaluate_colour(struct ColourHSL hsl,
|
size_t ComplimentaryColourExtractor::evaluate_colour(struct ColourHSV hsv,
|
||||||
double weight) const
|
double weight) const
|
||||||
{
|
{
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
double angle_delta;
|
double angle_delta;
|
||||||
// double additional_colour_weight;
|
double additional_colour_weight;
|
||||||
|
|
||||||
if ((0 == (1.0 - fabs(2 * m_main_colour.l - 1.0))) ||
|
if ((0.0 == hsv.s) || (0.0 == m_main_colour.s))
|
||||||
(0 == (1.0 - fabs(2 * hsl.l - 1.0))) ||
|
|
||||||
(0 == m_main_colour.s) ||
|
|
||||||
(0 == hsl.s))
|
|
||||||
{
|
{
|
||||||
angle_delta = 90.0;
|
angle_delta = 180.0;
|
||||||
// additional_colour_weight = 0.5;
|
additional_colour_weight = 0.5;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// additional_colour_weight = 1.0;
|
additional_colour_weight = 1.0;
|
||||||
/* SECTION BEGIN */
|
/* SECTION BEGIN */
|
||||||
angle_delta = fabs(hsl.h - m_main_colour.h);
|
angle_delta = fabs(hsv.h - m_main_colour.h);
|
||||||
if (angle_delta > 180.0F)
|
if (angle_delta > 180.0F)
|
||||||
{
|
{
|
||||||
angle_delta = 360.0F - angle_delta;
|
angle_delta = 360.0F - angle_delta;
|
||||||
@@ -39,62 +34,22 @@ size_t ComplimentaryColourExtractor::evaluate_colour(struct ColourHSL hsl,
|
|||||||
/* SECTION END */
|
/* SECTION END */
|
||||||
}
|
}
|
||||||
|
|
||||||
// double main_x = cos(m_main_colour.h * M_PI / 180.0) * m_main_colour.s;
|
|
||||||
// double main_y = sin(m_main_colour.h * M_PI / 180.0) * m_main_colour.s;
|
|
||||||
// double main_z = 1.0 - 2 * m_main_colour.l;
|
|
||||||
// double eval_x = cos(hsl.h * M_PI / 180.0) * hsl.s;
|
|
||||||
// double eval_y = sin(hsl.h * M_PI / 180.0) * hsl.s;
|
|
||||||
// double eval_z = 1.0 - 2 * hsl.l;
|
|
||||||
// // double total_x = main_x - eval_x;
|
|
||||||
// // double total_y = main_y - eval_y;
|
|
||||||
// // double total_z = main_z - eval_z;
|
|
||||||
// //double vec_magn = sqrt(pow(total_x, 2) + pow(total_y, 2) + pow(total_z, 2));
|
|
||||||
// double angle_diff = -(((main_x * eval_x + main_y * eval_y + main_z * eval_z) /
|
|
||||||
// (sqrt(pow(main_x, 2) + pow(main_y, 2) + pow(main_z, 2)) *
|
|
||||||
// sqrt(pow(eval_x, 2) + pow(eval_y, 2) + pow(eval_z, 2)))) - 1.0) / 2;
|
|
||||||
|
|
||||||
|
|
||||||
// static double max_angle_diff = 0.0;
|
|
||||||
// printf("Main - %f %f %f\n", m_main_colour.h, m_main_colour.s, m_main_colour.l);
|
|
||||||
// printf("Eval - %f %f %f\n", hsl.h, hsl.s, hsl.l);
|
|
||||||
// printf("Main Vec - %f %f %f\n", main_x, main_y, main_z);
|
|
||||||
// printf("Eval Vec - %f %f %f\n", eval_x, eval_y, eval_z);
|
|
||||||
// // printf("Res Vec - %f %f %f\n", total_x, total_y, total_z);
|
|
||||||
// printf("Ang diff - %f\n", angle_diff);
|
|
||||||
// if (angle_diff > max_angle_diff)
|
|
||||||
// {
|
|
||||||
// max_angle_diff = angle_diff;
|
|
||||||
// printf("Max Angle Diff\n");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// angle_delta = fabs(hsl.h - m_main_colour.h);
|
|
||||||
// if (angle_delta > 180.0F)
|
|
||||||
// {
|
|
||||||
// angle_delta = 360.0F - angle_delta;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// result = static_cast<size_t>(round(1000.0 * pow(weight, 0.3) * hsv.v *
|
// result = static_cast<size_t>(round(1000.0 * pow(weight, 0.3) * hsv.v *
|
||||||
// fmin(1.0, hsv.v + hsv.s) * additional_colour_weight * angle_delta));
|
// fmin(1.0, hsv.v + hsv.s) * additional_colour_weight * angle_delta));
|
||||||
|
|
||||||
// result = static_cast<size_t>(round(1000.0 * pow(weight, 0.3) * hsl.l *
|
result = static_cast<size_t>(round(1000.0 * pow(weight, 0.3) * hsv.v *
|
||||||
// additional_colour_weight * angle_delta));
|
additional_colour_weight * angle_delta));
|
||||||
|
|
||||||
result = static_cast<size_t>(round(1000.0 * pow(weight, 0.3) *
|
|
||||||
pow(((1.0 - fabs(2 * hsl.l - 1.0)) * (1 - 1.0 / m_l_levels) + 1.0 / m_l_levels), 0.3) *
|
|
||||||
hsl.s *
|
|
||||||
// additional_colour_weight *
|
|
||||||
angle_delta));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUBLIC FUNCS
|
// PUBLIC FUNCS
|
||||||
struct ColourHSL ComplimentaryColourExtractor::get_main_colour() const
|
struct ColourHSV ComplimentaryColourExtractor::get_main_colour() const
|
||||||
{
|
{
|
||||||
return m_main_colour;
|
return m_main_colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComplimentaryColourExtractor::set_main_colour(struct ColourHSL hsl)
|
void ComplimentaryColourExtractor::set_main_colour(struct ColourHSV hsv)
|
||||||
{
|
{
|
||||||
m_main_colour = hsl;
|
m_main_colour = hsv;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,18 +7,18 @@ class ComplimentaryColourExtractor : public ColourExtractor
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Main colour against which we are finding the complimentary
|
// Main colour against which we are finding the complimentary
|
||||||
struct ColourHSL m_main_colour;
|
struct ColourHSV m_main_colour;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Implemented - Evaluates the given colour based on its weight
|
// Implemented - Evaluates the given colour based on its weight
|
||||||
virtual size_t evaluate_colour(struct ColourHSL hsl, double weight) const;
|
virtual size_t evaluate_colour(struct ColourHSV hsv, double weight) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ComplimentaryColourExtractor(struct ColourHSL hsl, size_t h_levels = 36,
|
ComplimentaryColourExtractor(struct ColourHSV hsv, size_t h_levels = 36,
|
||||||
size_t s_levels = 10, size_t v_levels = 10);
|
size_t s_levels = 10, size_t v_levels = 10);
|
||||||
|
|
||||||
struct ColourHSL get_main_colour() const;
|
struct ColourHSV get_main_colour() const;
|
||||||
void set_main_colour(struct ColourHSL hsl);
|
void set_main_colour(struct ColourHSV hsv);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COMPLIMENTARY_COLOUR_EXTRACTOR_H_
|
#endif // COMPLIMENTARY_COLOUR_EXTRACTOR_H_
|
||||||
|
|||||||
37
main.cpp
37
main.cpp
@@ -1,6 +1,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
@@ -12,21 +12,20 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
void usage(char *name)
|
||||||
|
{
|
||||||
|
cout << "Usage: " << name << " [input image]" << endl;
|
||||||
|
cout << "Supported image formats: JPG, PNG, TGA, BMP, GIF" << endl;
|
||||||
|
cout << "Image must have 3 or more channels" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
void print_pixel(ColourRGB rgb)
|
void print_pixel(ColourRGB rgb)
|
||||||
{
|
{
|
||||||
uint8_t r = static_cast<uint8_t>(round(rgb.r * 255));
|
uint8_t r = static_cast<uint8_t>(round(rgb.r * 255));
|
||||||
uint8_t g = static_cast<uint8_t>(round(rgb.g * 255));
|
uint8_t g = static_cast<uint8_t>(round(rgb.g * 255));
|
||||||
uint8_t b = static_cast<uint8_t>(round(rgb.b * 255));
|
uint8_t b = static_cast<uint8_t>(round(rgb.b * 255));
|
||||||
|
|
||||||
cout << "#" << std::hex << (int)r << (int)g << (int)b;
|
printf("#%02x%02x%02x - %3d %3d %3d", r, g ,b, r, g, b);
|
||||||
cout << std::dec << " - " << (int)r << " " << (int)g << " " << (int)b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void usage(char *name)
|
|
||||||
{
|
|
||||||
cout << "Usage: " << name << " [input image]" << endl;
|
|
||||||
cout << "Supported image formats: JPG, PNG, TGA, BMP, GIF" << endl;
|
|
||||||
cout << "Image must have 3 or more channels" << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@@ -38,8 +37,8 @@ int main(int argc, char **argv)
|
|||||||
unsigned char *image = nullptr;
|
unsigned char *image = nullptr;
|
||||||
ColourRGB pixel;
|
ColourRGB pixel;
|
||||||
ColourRGB pixel2;
|
ColourRGB pixel2;
|
||||||
ColourHSL pixel_hsl;
|
ColourHSV pixel_hsv;
|
||||||
MainColourExtractor main_extractor(36, 10, 10);
|
MainColourExtractor main_extractor(0.2, 36, 10, 10);
|
||||||
ComplimentaryColourExtractor comp_extractor({0, 0, 0}, 36, 10, 10);
|
ComplimentaryColourExtractor comp_extractor({0, 0, 0}, 36, 10, 10);
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
@@ -86,16 +85,16 @@ int main(int argc, char **argv)
|
|||||||
// TODO: Handle alpha here
|
// TODO: Handle alpha here
|
||||||
}
|
}
|
||||||
|
|
||||||
pixel_hsl = RGBtoHSL(pixel);
|
pixel_hsv = RGBtoHSV(pixel);
|
||||||
main_extractor.add_pixel(pixel_hsl);
|
main_extractor.add_pixel(pixel_hsv);
|
||||||
comp_extractor.add_pixel(pixel_hsl);
|
comp_extractor.add_pixel(pixel_hsv);
|
||||||
}
|
}
|
||||||
stbi_image_free(image);
|
stbi_image_free(image);
|
||||||
|
|
||||||
pixel_hsl = main_extractor.extract_colour();
|
pixel_hsv = main_extractor.extract_colour();
|
||||||
comp_extractor.set_main_colour(pixel_hsl);
|
comp_extractor.set_main_colour(pixel_hsv);
|
||||||
pixel = HSLtoRGB(pixel_hsl);
|
pixel = HSVtoRGB(pixel_hsv);
|
||||||
pixel2 = HSLtoRGB(comp_extractor.extract_colour());
|
pixel2 = HSVtoRGB(comp_extractor.extract_colour());
|
||||||
|
|
||||||
cout << "Main - ";
|
cout << "Main - ";
|
||||||
print_pixel(pixel);
|
print_pixel(pixel);
|
||||||
|
|||||||
@@ -3,21 +3,49 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
MainColourExtractor::MainColourExtractor(size_t h_levels, size_t s_levels,
|
MainColourExtractor::MainColourExtractor(double lightness_threshold,
|
||||||
size_t l_levels)
|
size_t h_levels, size_t s_levels, size_t v_levels)
|
||||||
: ColourExtractor(h_levels, s_levels, l_levels)
|
:ColourExtractor(h_levels, s_levels, v_levels),
|
||||||
|
m_lightness_threshold(lightness_threshold)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROTECTED FUNCS
|
// PRIVATE FUNCS
|
||||||
size_t MainColourExtractor::evaluate_colour(struct ColourHSL hsl, double weight)
|
double MainColourExtractor::calculate_lightness(struct ColourHSV hsv) const
|
||||||
const
|
|
||||||
{
|
{
|
||||||
size_t result = 0;
|
double result = 0.0;
|
||||||
|
struct ColourRGB rgb;
|
||||||
|
|
||||||
result = static_cast<size_t>(round(1000.0 * pow(weight, 0.3) *
|
rgb = HSVtoRGB(hsv);
|
||||||
(hsl.s + 1.0 / m_h_levels) *
|
result = 0.299F * rgb.r + 0.587F * rgb.g + 0.114F * rgb.b;
|
||||||
((1.0 - fabs(2 * hsl.l - 1.0)) * (1 - 1.0 / m_l_levels) + 1.0 / m_l_levels)));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PROTECTED FUNCS
|
||||||
|
size_t MainColourExtractor::evaluate_colour(struct ColourHSV hsv, double weight)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
size_t result = 0;
|
||||||
|
double lightness;
|
||||||
|
|
||||||
|
lightness = calculate_lightness(hsv);
|
||||||
|
if (lightness >= m_lightness_threshold)
|
||||||
|
{
|
||||||
|
result = static_cast<size_t>(round(1000.0 * (pow(weight, 0.3) +
|
||||||
|
0.009999999776482582) * hsv.v * (hsv.s + 0.1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUBLIC FUNCS
|
||||||
|
double MainColourExtractor::get_lightness_threshold() const
|
||||||
|
{
|
||||||
|
return m_lightness_threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainColourExtractor::set_lightness_threshold(double value)
|
||||||
|
{
|
||||||
|
m_lightness_threshold = value;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,13 +5,24 @@
|
|||||||
|
|
||||||
class MainColourExtractor : public ColourExtractor
|
class MainColourExtractor : public ColourExtractor
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
// The minimum lightness a colour needs to have to be considered for
|
||||||
|
// evaluation
|
||||||
|
double m_lightness_threshold;
|
||||||
|
|
||||||
|
// Calculates the lightness of a colour
|
||||||
|
double calculate_lightness(struct ColourHSV hsv) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Implemented - Evaluates the given colour based on its weight
|
// Implemented - Evaluates the given colour based on its weight
|
||||||
virtual size_t evaluate_colour(struct ColourHSL hsv, double weight) const;
|
virtual size_t evaluate_colour(struct ColourHSV hsv, double weight) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainColourExtractor(size_t h_levels = 36, size_t s_levels = 10,
|
MainColourExtractor(double lightness_threshold = 0.2, size_t h_levels = 36,
|
||||||
size_t l_levels = 10);
|
size_t s_levels = 10, size_t v_levels = 10);
|
||||||
|
|
||||||
|
double get_lightness_threshold() const;
|
||||||
|
void set_lightness_threshold(double value);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAIN_COLOUR_EXTRACTOR_H_
|
#endif // MAIN_COLOUR_EXTRACTOR_H_
|
||||||
|
|||||||
Reference in New Issue
Block a user