Ejemplo n.º 1
0
        static public Color[] V1(Color[] llist, int ColorsCount)
        {
            List <RGB> list = new List <RGB>();

            foreach (Color item in llist)
            {
                list.Add(new RGB(item));
            }

            List <List <Color> > Result = new List <List <Color> >();
            List <RGB>           Part   = new List <RGB>();
            int maxLength      = 0;
            int emptyListCount = 0;

            int[] groupLengths = new int[ColorsCount];

            list.Sort(delegate(RGB left, RGB right)
                      { return(right.Hue.CompareTo(left.Hue)); });

            float lower = (float)list[list.Count - 1].Hue;
            float upper = (float)list[0].Hue;

            float KeyStep = (upper - lower) / ColorsCount;

            upper = KeyStep + lower;

            for (int i = 0; i < ColorsCount; i++)
            {
                if (i == ColorsCount - 1)
                {
                    upper = (float)list[0].Hue;
                }
                foreach (RGB item in list)
                {
                    if ((float)item.Hue >= (float)lower && (float)item.Hue <= (float)upper)
                    {
                        Part.Add(item);
                    }
                }

                if (Part.Count > 2)
                {
                    Part = ColorPalette.DistrictByHue(Part, true);
                    Part.Sort(delegate(RGB left, RGB right)
                              { return(left.Brightness.CompareTo(right.Brightness)); });
                }

                if (maxLength < Part.Count)
                {
                    maxLength = Part.Count;
                }
                if (Part.Count == 0)
                {
                    emptyListCount += 1;
                }

                groupLengths[i] = Part.Count;

                List <Color> temp = new List <Color>();
                foreach (RGB item in Part)
                {
                    temp.Add(item.Color);
                }

                Result.Add(temp.GetRange(0, temp.Count));
                Part.Clear();

                lower = lower + KeyStep;
                upper = upper + KeyStep;
            }

            List <Color>         maxList    = new List <Color>();
            List <List <Color> > emptyLists = new List <List <Color> >();

            Array.Sort(groupLengths);
            maxList    = Result.Find(group => group.Count == maxLength);
            emptyLists = Result.FindAll(x => x.Count == 0);

            if (emptyListCount != 0 && maxLength > 1)
            {
                for (int i = 0; i < emptyLists.Count; i++)
                {
                    int col = 0;
                    int LargestPartIndex = 0;

                    Array.Sort(groupLengths);
                    maxLength        = groupLengths[groupLengths.Length - 1];
                    LargestPartIndex = Result.FindIndex(group => group.Count == maxLength);

                    col = Result[LargestPartIndex].Count / 2;
                    emptyLists[i].AddRange(Result[LargestPartIndex].GetRange(0, col));
                    Result[LargestPartIndex].RemoveRange(0, col);
                    groupLengths[groupLengths.Length - 1] = groupLengths[groupLengths.Length - 1] / 2;
                }

                int cnt = 0;
                for (int i = 0; i < Result.Count; i++)
                {
                    if (Result[i].Count == 0)
                    {
                        Result[i] = emptyLists[cnt];
                        cnt      += 1;
                    }
                }
            }

            int index = Result.FindIndex(group => group.Count != 0);

            for (int i = 0; i < Result.Count; i++)
            {
                if (Result[i].Count == 0)
                {
                    Result[i] = Result[index];
                }
            }

            return(ColorPalette.GetAverageColors(Result).ToArray());
        }
Ejemplo n.º 2
0
        static public Color[] V44(Color[] llist, int ColorsCount)
        {
            List <RGB> RGB_AllColors = new List <RGB>();

            for (int i = 0; i < llist.Length; i++)
            {
                RGB_AllColors.Add(new RGB(llist[i], K_means.AllWeights[i]));
            }

            List <List <Color> > Result = new List <List <Color> >();
            List <RGB>           Part   = new List <RGB>();
            int maxLength      = 0;
            int emptyListCount = 0;

            int[] groupLengths = new int[ColorsCount];

            RGB_AllColors.Sort(delegate(RGB left, RGB right)
                               { return(right.Hue.CompareTo(left.Hue)); });

            for (int i = 0; i < ColorsCount; i++)
            {
                float currentHueValue = 0f;

                if (i < 3)
                {
                    foreach (RGB item in RGB_AllColors)
                    {
                        // элементы на границах попадают в обе группы
                        currentHueValue = item.Hue;
                        if ((float)currentHueValue >= (float)(120f * (float)i) && (float)currentHueValue <= (float)(120f * (float)(i + 1)))
                        {
                            Part.Add(item);
                        }
                    }
                }

                if (Part.Count >= 2)
                {
                    Part = ColorPalette.DistrictByHue(Part, true);
                    Part.Sort(delegate(RGB left, RGB right)
                              { return(left.Brightness.CompareTo(right.Brightness)); });
                }

                List <Color> temp = new List <Color>();
                foreach (RGB item in Part)
                {
                    for (int f = 0; f < item.Weight; f++)
                    {
                        temp.Add(item.Color);
                    }
                }

                if (maxLength < temp.Count)
                {
                    maxLength = temp.Count;
                }
                if (temp.Count == 0)
                {
                    emptyListCount += 1;
                }

                groupLengths[i] = temp.Count;

                Result.Add(temp.GetRange(0, temp.Count));
                Part.Clear();
            }

            List <Color>         maxList    = new List <Color>();
            List <List <Color> > emptyLists = new List <List <Color> >();

            Array.Sort(groupLengths);
            maxList    = Result.Find(group => group.Count == maxLength);
            emptyLists = Result.FindAll(x => x.Count == 0);

            if (emptyListCount != 0 && maxLength > 1)
            {
                for (int i = 0; i < emptyLists.Count; i++)
                {
                    int col = 0;
                    int LargestPartIndex = 0;

                    Array.Sort(groupLengths);
                    maxLength        = groupLengths[groupLengths.Length - 1];
                    LargestPartIndex = Result.FindIndex(group => group.Count == maxLength);

                    col = Result[LargestPartIndex].Count / 2;
                    emptyLists[i].AddRange(Result[LargestPartIndex].GetRange(0, col));
                    Result[LargestPartIndex].RemoveRange(0, col);
                    groupLengths[groupLengths.Length - 1] = groupLengths[groupLengths.Length - 1] / 2;
                }

                int cnt = 0;
                for (int i = 0; i < Result.Count; i++)
                {
                    if (Result[i].Count == 0)
                    {
                        Result[i] = emptyLists[cnt];
                        cnt      += 1;
                    }
                }
            }

            for (int i = 0; i < Result.Count; i++)
            {
                if (Result[i].Count == 0)
                {
                    Result[i].Add(maxList[0]);
                }
            }

            return(ColorPalette.GetAverageColors(Result).ToArray());
        }
Ejemplo n.º 3
0
        static public List <List <Color> > RunSingleThread(Color[] RGB_AllColors, int ClasterCount, int InitVersion)
        {
            int IterationCount = 0;
            int ColorsCount;
            int weight;

            double
                var_L,
                var_a,
                var_b,
                count,
                minE,
                E;

            List <List <CIELab> > ResultClasters = new List <List <CIELab> >();

            CIELab[] PreviousCentroids = new CIELab[ClasterCount];
            CIELab[] CIELab_AllColors  = Converter.Array_RGBtoCIELab(RGB_AllColors);

            AllWeights = ColorPalette.GetColorsWeights(RGB_AllColors);
            Color[]  RGB_AllColorsDistr    = ColorPalette.DistrictByRGB(RGB_AllColors);
            CIELab[] CIELab_AllColorsDistr = Converter.Array_RGBtoCIELab(RGB_AllColorsDistr);

            ColorsCount = RGB_AllColorsDistr.Length;

            for (int i = 0; i < ClasterCount; i++)
            {
                PreviousCentroids[i] = CIELab_AllColors[0];
                ResultClasters.Add(new List <CIELab>());
            }

            switch (InitVersion)
            {
            case 1:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V1(RGB_AllColors, ClasterCount));
                break;

            case 2:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V2(RGB_AllColors, ClasterCount));
                break;

            case 3:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V3(RGB_AllColors, ClasterCount));
                break;

            case 4:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V4(RGB_AllColors, ClasterCount));
                break;

            case 5:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V5(RGB_AllColors, ClasterCount));
                break;

            default:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V4(RGB_AllColors, ClasterCount));
                break;
            }

            while (true)
            {
                IterationCount++;

                double[,] accum = new double[ClasterCount, 4];
                CIELab CurrentColor;

                int NumOfNearestClaster = 0;

                for (int f = 0; f < ColorsCount; f++)
                {
                    minE         = 1000000d;
                    CurrentColor = CIELab_AllColorsDistr[f];
                    weight       = AllWeights[f];

                    for (int i = 0; i < ClasterCount; i++)
                    {
                        var_L = CurrentColor.L - CurrentCentroids[i].L;
                        var_a = CurrentColor.a - CurrentCentroids[i].a;
                        var_b = CurrentColor.b - CurrentCentroids[i].b;

                        var_L = var_L * var_L;
                        var_a = var_a * var_a;
                        var_b = var_b * var_b;

                        E = var_L + var_a + var_b;

                        if (E < minE)
                        {
                            minE = E;
                            NumOfNearestClaster = i;
                        }
                    }

                    accum[NumOfNearestClaster, 0] += CurrentColor.L * weight;
                    accum[NumOfNearestClaster, 1] += CurrentColor.a * weight;
                    accum[NumOfNearestClaster, 2] += CurrentColor.b * weight;
                    accum[NumOfNearestClaster, 3] += weight;
                }

                CurrentCentroids.CopyTo(PreviousCentroids, 0);

                for (int f = 0; f < ClasterCount; f++)
                {
                    count = var_L = var_a = var_b = 0;

                    count += accum[f, 3];

                    var_L += accum[f, 0];
                    var_a += accum[f, 1];
                    var_b += accum[f, 2];

                    var_L = var_L / count;
                    var_a = var_a / count;
                    var_b = var_b / count;

                    CurrentCentroids[f] = new CIELab(var_L, var_a, var_b);
                }

                bool equal = CompareClasters(CurrentCentroids, PreviousCentroids);
                if (equal || IterationCount >= 500)
                {
                    Group(CIELab_AllColorsDistr, ResultClasters, ClasterCount);
                    FillEmptyClasters(ResultClasters, ClasterCount);
                    break;
                }
            }

            if (ClasterCount == 20)
            {
                ColorPalette.s = IterationCount.ToString() + "\t count";
            }

            return(Converter.GroupList_CIELabtoRBG(ResultClasters));
        }
Ejemplo n.º 4
0
        static public Color[] V5(Color[] llist, int ColorsCount)
        {
            List <RGB> RGB_AllColors = new List <RGB>();

            foreach (Color item in llist)
            {
                RGB_AllColors.Add(new RGB(item));
            }

            List <List <Color> > Result = new List <List <Color> >();
            List <RGB>           Part   = new List <RGB>();
            int maxLength      = 0;
            int emptyListCount = 0;

            RGB_AllColors.Sort(delegate(RGB left, RGB right)
                               { return(right.Hue.CompareTo(left.Hue)); });

            for (int i = 0; i < ColorsCount; i++)
            {
                if (i < 3)
                {
                    foreach (RGB item in RGB_AllColors)
                    {
                        if ((float)item.Hue >= (float)(120f * (float)i) && (float)item.Hue <= (float)(120f * (float)(i + 1)))
                        {
                            Part.Add(item);
                        }
                    }
                }

                if (Part.Count >= 2)
                {
                    Part = ColorPalette.DistrictByHue(Part, true);
                    Part.Sort(delegate(RGB left, RGB right)
                              { return(left.Hue.CompareTo(right.Hue)); });
                }

                if (maxLength < Part.Count)
                {
                    maxLength = Part.Count;
                }
                if (Part.Count == 0)
                {
                    emptyListCount += 1;
                }

                List <Color> temp = new List <Color>();
                foreach (RGB item in Part)
                {
                    temp.Add(item.Color);
                }

                Result.Add(temp.GetRange(0, temp.Count));
                Part.Clear();
            }

            if (emptyListCount != 0 && maxLength > 1)
            {
                double E_value    = 0d;
                double E_valueMax = 0d;
                int    GroupIndex = 0;

                while (emptyListCount != 0)
                {
                    Result.Sort(delegate(List <Color> left, List <Color> right)
                                { return(right.Count.CompareTo(left.Count)); });

                    E_value    = 0d;
                    E_valueMax = 0d;
                    GroupIndex = 0;

                    for (int i = 0; i < ColorsCount; i++)
                    {
                        if (Result[i].Count > 1)
                        {
                            Color  left      = ColorPalette.GetAverageColor(Result[i].GetRange(0, Result[i].Count / 2));
                            Color  right     = ColorPalette.GetAverageColor(Result[i].GetRange(Result[i].Count / 2, Result[i].Count / 2));
                            CIELab CIE_left  = CIELab.RGB_to_CIELab(left);
                            CIELab CIE_right = CIELab.RGB_to_CIELab(right);

                            E_value = CIELab.deltaE76(CIE_left, CIE_right);

                            if (E_value > E_valueMax)
                            {
                                GroupIndex = i;
                                E_valueMax = E_value;
                            }
                        }
                    }

                    maxLength = Result[GroupIndex].Count;
                    if (maxLength == 1)
                    {
                        break;
                    }

                    Result[ColorsCount - 1].AddRange(Result[GroupIndex].GetRange(0, maxLength / 2));
                    Result[GroupIndex].RemoveRange(0, maxLength / 2);
                    emptyListCount--;
                }
            }

            int index = Result.FindIndex(group => group.Count != 0);

            for (int i = 0; i < Result.Count; i++)
            {
                if (Result[i].Count == 0)
                {
                    Result[i] = Result[index];
                }
            }

            return(ColorPalette.GetAverageColors(Result).ToArray());
        }
Ejemplo n.º 5
0
        static public List <List <Color> > RunMultiThread(Color[] RGB_AllColors, int ClasterCount, int InitVersion)
        {
            int IterationCount = 0;
            int ThreadCount    = 3;
            int ColorsCount    = RGB_AllColors.Length;

            double
                var_L,
                var_a,
                var_b,
                count;

            List <List <CIELab> > ResultClasters = new List <List <CIELab> >();

            CIELab[] PreviousCentroids = new CIELab[ClasterCount];
            CIELab[] CIELab_AllColors;
            AccumParts = new List <double[, ]>();

            switch (InitVersion)
            {
            case 1:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V1(RGB_AllColors, ClasterCount));
                break;

            case 2:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V2(RGB_AllColors, ClasterCount));
                break;

            case 3:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V3(RGB_AllColors, ClasterCount));
                break;

            case 4:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V4(RGB_AllColors, ClasterCount));
                break;

            case 5:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V5(RGB_AllColors, ClasterCount));
                break;

            default:
                CurrentCentroids = Converter.Array_RGBtoCIELab(InitializeCentroids.V4(RGB_AllColors, ClasterCount));
                break;
            }

            AllWeights    = ColorPalette.GetColorsWeights(RGB_AllColors);
            RGB_AllColors = ColorPalette.DistrictByRGB(RGB_AllColors);

            CIELab_AllColors = Converter.Array_RGBtoCIELab(RGB_AllColors);
            WeightsParts     = Converter.SplitOnParts(AllWeights, ThreadCount);
            CIELab_Parts     = Converter.SplitOnParts(CIELab_AllColors, ThreadCount);

            for (int j = 0; j < ThreadCount; j++)
            {
                AccumParts.Add(new double[ClasterCount, 4]);

                for (int i = 0; i < ClasterCount; i++)
                {
                    PreviousCentroids[i] = CIELab_Parts[0][0];
                }
            }

            for (int i = 0; i < ClasterCount; i++)
            {
                ResultClasters.Add(new List <CIELab>());
            }

            var watch = System.Diagnostics.Stopwatch.StartNew();

            while (true)
            {
                IterationCount++;

                using (CountdownEvent complete = new CountdownEvent(ThreadCount))
                {
                    ThreadPool.QueueUserWorkItem(delegate { MainAlgorithm(CIELab_Parts[0], ClasterCount, 0); complete.Signal(); });
                    ThreadPool.QueueUserWorkItem(delegate { MainAlgorithm(CIELab_Parts[1], ClasterCount, 1); complete.Signal(); });
                    ThreadPool.QueueUserWorkItem(delegate { MainAlgorithm(CIELab_Parts[2], ClasterCount, 2); complete.Signal(); });

                    complete.Wait();
                }

                CurrentCentroids.CopyTo(PreviousCentroids, 0);

                for (int f = 0; f < ClasterCount; f++)
                {
                    count = var_L = var_a = var_b = 0;

                    for (int j = 0; j < ThreadCount; j++)
                    {
                        count += AccumParts[j][f, 3];

                        var_L += AccumParts[j][f, 0];
                        var_a += AccumParts[j][f, 1];
                        var_b += AccumParts[j][f, 2];
                    }

                    var_L = var_L / count;
                    var_a = var_a / count;
                    var_b = var_b / count;

                    CurrentCentroids[f] = new CIELab(var_L, var_a, var_b);
                }

                bool equal = CompareClasters(CurrentCentroids, PreviousCentroids);
                if (equal || IterationCount >= 500)
                {
                    Group(CIELab_AllColors, ResultClasters, ClasterCount);
                    FillEmptyClasters(ResultClasters, ClasterCount);
                    break;
                }
            }
            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;

            if (ClasterCount == 20)
            {
                ColorPalette.s += IterationCount.ToString() + "\t count\n";
                ColorPalette.s += ((float)elapsedMs / 1000).ToString() + "\t mainAlgo";
            }

            return(Converter.GroupList_CIELabtoRBG(ResultClasters));
        }