Example #1
0
        static public List <CIELab[]> SplitOnParts(CIELab[] inputArray, int PartsCount)
        {
            List <CIELab[]> outputList = new List <CIELab[]>();

            int[,] Sizes = new int[PartsCount, 3];

            int PartSize = inputArray.Length / PartsCount;

            Sizes[0, 0] = 0;
            Sizes[0, 1] = (inputArray.Length - PartSize * (PartsCount - 1)) - 1;
            Sizes[0, 2] = Sizes[0, 1] - Sizes[0, 0] + 1;

            for (int i = 1; i < PartsCount; i++)
            {
                Sizes[i, 0] = Sizes[i - 1, 1] + 1;
                Sizes[i, 1] = Sizes[i, 0] + PartSize - 1;
                Sizes[i, 2] = Sizes[i, 1] - Sizes[i, 0] + 1;
            }

            for (int i = 0; i < PartsCount; i++)
            {
                outputList.Add(new CIELab[Sizes[i, 2]]);

                for (int j = 0; j < Sizes[i, 2]; j++)
                {
                    outputList[i][j] = new CIELab(inputArray[j + Sizes[i, 0]]);
                }
            }

            return(outputList);
        }
        static public Color CIELab_to_RGB(CIELab LAB)
        {
            double[] XYZ = new double[3];
            XYZ = CIELab_to_XYZ(LAB);

            return(XYZ_to_RGB(XYZ));
        }
Example #3
0
        static public CIELab[] Array_RGBtoCIELab(Color[] inputList)
        {
            CIELab[] outputList = new CIELab[inputList.Length];
            for (int i = 0; i < inputList.Length; i++)
            {
                outputList[i] = CIELab.RGB_to_CIELab(inputList[i]);
            }

            return(outputList);
        }
        static public double deltaE76(CIELab first, CIELab second)
        {
            double
                var_L,
                var_a,
                var_b;

            var_L = first.L - second.L;
            var_a = first.a - second.a;
            var_b = first.b - second.b;

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

            return(var_L + var_a + var_b);
        }
        public void GetColorInfo(Color color)
        {
            ChangeNeeded = false;

            TargetRGB    = color;
            TargetHSV.H  = color.GetHue();
            TargetHSV.S  = color.GetSaturation();
            TargetHSV.V  = color.GetBrightness();
            TargetXYZ    = CIELab.RGB_to_XYZ(color);
            TargetCIELab = CIELab.XYZ_to_CIELab(TargetXYZ);

            SetRGB();
            SetHSV();
            SetXYZ();
            SetCIELab();

            ChangeNeeded = true;
        }
Example #6
0
        static public List <List <Color> > GroupList_CIELabtoRBG(List <List <CIELab> > inputList)
        {
            List <List <Color> > outputList = new List <List <Color> >();
            List <Color>         temp       = new List <Color>();

            foreach (List <CIELab> list in inputList)
            {
                foreach (CIELab color in list)
                {
                    temp.Add(CIELab.CIELab_to_RGB(color));
                }

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

            return(outputList);
        }
        static public double[] CIELab_to_XYZ(CIELab LAB)
        {
            double[] XYZ   = new double[3];
            double   var_Y = (LAB.L + 16d) / 116d;
            double   var_X = LAB.a / 500d + var_Y;
            double   var_Z = var_Y - LAB.b / 200d;

            if (Math.Pow(var_Y, 3d) > 0.008856d)
            {
                var_Y = Math.Pow(var_Y, 3);
            }
            else
            {
                var_Y = (var_Y - 16d / 116d) / 7.787d;
            }
            if (Math.Pow(var_X, 3d) > 0.008856d)
            {
                var_X = Math.Pow(var_X, 3);
            }
            else
            {
                var_X = (var_X - 16d / 116d) / 7.787d;
            }
            if (Math.Pow(var_Z, 3d) > 0.008856)
            {
                var_Z = Math.Pow(var_Z, 3);
            }
            else
            {
                var_Z = (var_Z - 16d / 116d) / 7.787d;
            }

            XYZ[0] = var_X * ref_x;
            XYZ[1] = var_Y * ref_y;
            XYZ[2] = var_Z * ref_z;
            return(XYZ);
        }
Example #8
0
        static public Color HSV_to_RGB(HSV hsv)
        {
            double H = hsv.H;
            double S = hsv.S;
            double V = hsv.V;

            while (H < 0)
            {
                H += 360;
            }
            ;
            while (H >= 360)
            {
                H -= 360;
            }
            ;
            double R, G, B;

            if (V <= 0)
            {
                R = G = B = 0;
            }
            else if (S <= 0)
            {
                R = G = B = V;
            }
            else
            {
                double hf = H / 60.0;
                int    i  = (int)Math.Floor(hf);
                double f  = hf - i;
                double pv = V * (1 - S);
                double qv = V * (1 - S * f);
                double tv = V * (1 - S * (1 - f));
                switch (i)
                {
                case 0:
                    R = V;
                    G = tv;
                    B = pv;
                    break;

                case 1:
                    R = qv;
                    G = V;
                    B = pv;
                    break;

                case 2:
                    R = pv;
                    G = V;
                    B = tv;
                    break;

                case 3:
                    R = pv;
                    G = qv;
                    B = V;
                    break;

                case 4:
                    R = tv;
                    G = pv;
                    B = V;
                    break;

                case 5:
                    R = V;
                    G = pv;
                    B = qv;
                    break;

                case 6:
                    R = V;
                    G = tv;
                    B = pv;
                    break;

                case -1:
                    R = V;
                    G = pv;
                    B = qv;
                    break;

                default:
                    R = G = B = V;
                    break;
                }
            }
            int r = CIELab.FixOutOfRangeVaue((int)(R * 255.0));
            int g = CIELab.FixOutOfRangeVaue((int)(G * 255.0));
            int b = CIELab.FixOutOfRangeVaue((int)(B * 255.0));

            return(Color.FromArgb(r, g, b));
        }
 public CIELab(CIELab get)
 {
     L = get.L;
     a = get.a;
     b = get.b;
 }
 public bool Equal(CIELab first)
 {
     return(L == first.L && a == first.a && b == first.b);
 }
Example #11
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());
        }
Example #12
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));
        }
Example #13
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));
        }
        public void ConvertColor()
        {
            ChangeNeeded = false;
            switch (ConvertType)
            {
            case "RGB":
                TargetRGB = Color.FromArgb(Int32.Parse(RGB_R.Text), Int32.Parse(RGB_G.Text), Int32.Parse(RGB_B.Text));

                TargetXYZ    = CIELab.RGB_to_XYZ(TargetRGB);
                TargetCIELab = CIELab.RGB_to_CIELab(TargetRGB);
                TargetHSV    = HSV.RGB_to_HSV(TargetRGB);

                SetHSV();
                SetXYZ();
                SetCIELab();
                break;

            case "HSV":
                TargetHSV.H = Double.Parse(HSV_H.Text);
                TargetHSV.S = Double.Parse(HSV_S.Text);
                TargetHSV.V = Double.Parse(HSV_V.Text);

                TargetRGB    = HSV.HSV_to_RGB(TargetHSV);
                TargetXYZ    = CIELab.RGB_to_XYZ(TargetRGB);
                TargetCIELab = CIELab.RGB_to_CIELab(TargetRGB);

                SetRGB();
                SetXYZ();
                SetCIELab();
                break;

            case "XYZ":
                TargetXYZ[0] = Double.Parse(XYZ_X.Text) * 100d;
                TargetXYZ[1] = Double.Parse(XYZ_Y.Text) * 100d;
                TargetXYZ[2] = Double.Parse(XYZ_Z.Text) * 100d;

                TargetRGB    = CIELab.XYZ_to_RGB(TargetXYZ);
                TargetCIELab = CIELab.XYZ_to_CIELab(TargetXYZ);
                TargetHSV    = HSV.RGB_to_HSV(TargetRGB);

                SetRGB();
                SetHSV();
                SetCIELab();
                break;

            case "Lab":
                TargetCIELab.L = Double.Parse(Lab_L.Text);
                TargetCIELab.a = Double.Parse(Lab_a.Text);
                TargetCIELab.b = Double.Parse(Lab_b.Text);

                TargetRGB = CIELab.CIELab_to_RGB(TargetCIELab);
                TargetXYZ = CIELab.CIELab_to_XYZ(TargetCIELab);
                TargetHSV = HSV.RGB_to_HSV(TargetRGB);

                SetRGB();
                SetHSV();
                SetXYZ();
                break;
            }
            targetColor.BackColor = TargetRGB;
            ConvertType           = "";
            ChangeNeeded          = true;
        }