LoginSignup
6
8

More than 5 years have passed since last update.

C# 色相(Hue)の平均値を取得する

Last updated at Posted at 2017-02-14

C# 色相(Hue)の平均値を取得する

0(360)をまたぐ色相の画像を作成する

色相(Hue)
image

339~360 0~23のグラデーションを作成する
image

正方形の画像を作成し、色相の平均値を取得する
HueAverageTest.png

単純な平均

単純に全ピクセルのHue合計から、ピクセル分で割って平均を出すスクリプト。
しかし、これでは平均値が175.6723になってしまった。

image

SimpleAverage.cs

        private void btnImageAverageHue_Click(object sender, EventArgs e)
        {
            CalcSimpleHueAverage(@"画像のフルパス");
        }

        private void CalcSimpleHueAverage(string imgFilePath)
        {
            Bitmap bmp = new Bitmap(imgFilePath);

            List<float> HueList = new List<float>();

            for (int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    Color color = bmp.GetPixel(x, y);
                    HueList.Add(color.GetHue());
                }
            }

            float avrageHue = 0;
            foreach(float hue in HueList)
            {
                avrageHue += hue;
            }
            avrageHue /= (float)HueList.Count;

            Console.WriteLine(avrageHue.ToString());
        }

色相を円形として計算する

灰色部分に色が分布されているので、このエリアから色の平均を取る

HueAverage.png

まだ、あまり理解していないが、sin,cosを使用して、X,y座標からベクトルを算出して、その平均を求めることで、0の境界線の平均が取れるようだ。
0.742729783566296と理想的な赤の色相の値を取得することが出来た。

CalcCircleHueAverage.cs

        private void btnImageAverageHue_Click(object sender, EventArgs e)
        {
            //CalcSimpleHueAverage(@"画像のフルパス");
            CalcCircleHueAverage(@"画像のフルパス");
        }

        private void CalcCircleHueAverage(string imgFilePath)
        {
            Bitmap bmp = new Bitmap(imgFilePath);

            List<double> HueList = new List<double>();

            for (int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    Color color = bmp.GetPixel(x, y);
                    HueList.Add(color.GetHue());
                }
            }

            double X = 0.0;
            double Y = 0.0;

            for (int hue = 0; hue < HueList.Count; ++hue)
            {
                //Add the X and Y values to the sum X and Y
                X += Math.Cos(HueList[hue] / 180.0d * Math.PI);
                Y += Math.Sin(HueList[hue] / 180.0d * Math.PI);
            }

            X /= HueList.Count;
            Y /= HueList.Count;

            double AverageColor = Math.Atan2(Y, X) * 180.0d / Math.PI;

            Console.WriteLine(AverageColor.ToString());
        }


Atan2は-nからnの値を取る

Atan2は-nからnの値を取るため、degree(0°~360°)に直した値を返すようにする。

CalcCircleHueAverage.cs
        private void btnImageAverageHue_Click(object sender, EventArgs e)
        {
            //CalcSimpleHueAverage(@"D:\Projects\private\CSharp\Color\HueAverageTest.png");

            Bitmap bmp = new Bitmap(@"D:\Projects\private\CSharp\Color\HueAverageTest.png");

            List<double> HueList = new List<double>();

            for (int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width; x++)
                {
                    Color color = bmp.GetPixel(x, y);
                    HueList.Add(color.GetHue());
                }
            }

            CalcCircleHueAverage(HueList);
        }

        private double fmod(double a, double b)
        {
            return a - Math.Floor(a / b) * b;
        }

        private double CalcCircleHueAverage(List<double> HueList)
        {
            double X = 0.0;
            double Y = 0.0;

            for (int hue = 0; hue < HueList.Count; ++hue)
            {
                //Add the X and Y values to the sum X and Y
                X += Math.Cos(HueList[hue] / 180.0d * Math.PI);
                Y += Math.Sin(HueList[hue] / 180.0d * Math.PI);
            }

            X /= HueList.Count;
            Y /= HueList.Count;

            double AverageColor = fmod(Math.Atan2(Y, X) * 180.0d / Math.PI, 360d);
            return AverageColor;
        }

参照

Averaging circular values (particularly Hues in HSL color scheme)
http://stackoverflow.com/questions/13959276/averaging-circular-values-particularly-hues-in-hsl-color-scheme

How can i average Hue value in image?
https://jp.mathworks.com/matlabcentral/answers/111370-how-can-i-average-hue-value-in-image?requestedDomain=www.mathworks.com

色相の平均値の算出方法
http://okwave.jp/qa/q3582670.html

How to map atan2() to degrees 0-360
http://stackoverflow.com/questions/1311049/how-to-map-atan2-to-degrees-0-360

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8