Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top