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)); }
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)); }