Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Averaging circular values (particularly Hues in HSL color scheme)

Tags:

c++

math

colors

hsl

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.

like image 399
GarrickW Avatar asked Dec 19 '12 19:12

GarrickW


People also ask

How do you calculate average hue?

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).

What does HSL mean in color?

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.


2 Answers

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.

like image 183
Joseph Mansfield Avatar answered Sep 28 '22 08:09

Joseph Mansfield


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.

like image 22
aschepler Avatar answered Sep 28 '22 08:09

aschepler