So I was trying to puzzle out how to calculate the average hue of a number of objects whose colors are represented by HSL values. Thankfully, I stumbled across this Stack Overflow post, and set to work implementing the algorithm provided in the top answer (I am working in C++).
Unfortunately, my implementation doesn't seem to work. Here it is, in full; note that though I write "Hue" I am using angles, in degrees, as per the initial implementation (switching from 0-360 angles to 0-256 hues, once I know my code works, shouldn't be hard).
#include <iostream>
#include <vector>
#include <cmath>
#define PI (4*atan(1))
int main()
{
///
/// Calculations adapted from this source:
/// https://stackoverflow.com/questions/8169654/how-to-calculate-mean-and-standard-deviation-for-hue-values-from-0-to-360
std::vector<double> Hues = {355, 5, 5, 5, 5};
//These will be used to store the sum of the angles
double X = 0.0;
double Y = 0.0;
//Loop through all H values
for (int hue = 0; hue < Hues.size(); ++hue)
{
//Add the X and Y values to the sum X and Y
X += cos(Hues[hue] / 180 * PI);
Y += sin(Hues[hue] / 180 * PI);
}
//Now average the X and Y values
X /= Hues.size();
Y /= Hues.size();
//Get atan2 of those
double AverageColor = atan2(X, Y) * 180 / PI;
std::cout << "Average: " << AverageColor << "\n";
return 0;
}
Instead of the expected answer of 3 (since 355 should be equivalent to -5 in this scheme), I get 86.9951.
Can somebody point out what I'm doing wrong? This seems very basic.
How is average hue computed and reported? The average hue is calculated using mean of circular quantities. The standard way of computing the average cannot be used because hue is a periodic quantity (modulo 360). The ˉhr is then converted to degress using 180πˉhr(mod360).
HSL(Hue-Saturation-Lightness) The HSL color model is used in numerical color specifications. The advantage of HSL over RGB is that it is far more intuitive: you can guess at the colors you want, and then tweak.
atan2
takes its arguments in reverse order. I know, annoying! So try:
double AverageColor = atan2(Y, X) * 180 / PI;
The answer it gives now is 3.00488.
Try atan2(Y, X)
. atan2(a,b)
is similar to atan(a/b)
, and you need the arctangent of the average sine over the average cosine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With