private void KMeansCPU(bool async = false) { DoubleColor[,] LABImageArray = new DoubleColor[SourceImageColorArray.GetLength(0), SourceImageColorArray.GetLength(1)]; var cp = SourceImageColorProfile; var start1 = DateTime.Now; ColorProfileConverter.ConvertImageToLAB(SourceImageColorArray, LABImageArray, cp); DoubleColor[,] result; if (async == false) { result = KMeansCalc.CalculateKMeans(LABImageArray, KMeansParam, Globals.max_iter, Globals.eps); } else { result = KMeansCalc.CalculateKMeansAsync(LABImageArray, KMeansParam, Globals.max_iter, Globals.eps); } ColorProfileConverter.ConvertImageFromLAB(result, DestImageColorArray, cp); var end = DateTime.Now; string s = ""; if (async == true) { s = "[ASYNC]"; } Debug.WriteLine($"CPU TIME{s}: {end - start1}"); Dispatcher.Invoke(() => { Paint.CopyToWriteableBitmap(DestImageWB, DestImageColorArray); }); }
public static double Distance(DoubleColor c1, DoubleColor c2) { double dL = c1.R - c2.R; double da = c1.G - c2.G; double db = c1.B - c2.B; return(Math.Sqrt(dL * dL + da * da + db * db)); }
public static DoubleColor ConvertColorToXYZ(DoubleColor color, ColorProfile src) { color.InverseGammaCorrection(src.Gamma); var v = src.RGBtoXYZ.MultiplyByVectorRight(color.R, color.G, color.B); DoubleColor XYZ = new DoubleColor(v.X, v.Y, v.Z); return(XYZ); }
public static DoubleColor ConvertColorToXYZ(DoubleColor color, ColorProfileEnum from) { ColorProfile cp = null; switch (from) { case ColorProfileEnum.sRGB: { cp = ColorProfileFactory.GetFactory().sRBGcolorProfile; } break; case ColorProfileEnum.adobeRGB: { cp = ColorProfileFactory.GetFactory().adobeRBGcolorProfile; } break; case ColorProfileEnum.appleRGB: { cp = ColorProfileFactory.GetFactory().appleRBGcolorProfile; } break; case ColorProfileEnum.CIE_RGB: { cp = ColorProfileFactory.GetFactory().CIE_RBGcolorProfile; } break; case ColorProfileEnum.WideGamut: { cp = ColorProfileFactory.GetFactory().WideGamutcolorProfile; } break; case ColorProfileEnum.PAL: { cp = ColorProfileFactory.GetFactory().PALcolorProfile; } break; default: break; } color.InverseGammaCorrection(cp.Gamma); var v = cp.RGBtoXYZ.MultiplyByVectorRight(color.R, color.G, color.B); DoubleColor XYZ = new DoubleColor(v.X, v.Y, v.Z); //XYZ.ToXYZ(); return(XYZ); //return new DoubleColor(-1, -1, -1); }
public static void ConvertImageToDoubleColor(SimpleColor[,] imageSource, DoubleColor[,] imageDest) { Parallel.For(0, imageSource.GetLength(0), i => { for (int j = 0; j < imageSource.GetLength(1); j++) { imageDest[i, j] = new DoubleColor(imageSource[i, j]); } }); }
public static DoubleColor ConvertColorFromXYZ(DoubleColor color, ColorProfile dest, MyMatrix bradfordMatrix = null) { if (bradfordMatrix != null) { (color.R, color.G, color.B) = bradfordMatrix.MultiplyByVectorRight(color.R, color.G, color.B); } var v = dest.XYZtoRGB.MultiplyByVectorRight(color.R, color.G, color.B); DoubleColor XYZ = new DoubleColor(v.X, v.Y, v.Z); XYZ.GammaCorrection(dest.Gamma); return(XYZ); }
public static void ConvertImageToLAB(SimpleColor[,] imageSource, DoubleColor[,] imageDest, ColorProfile from) { Parallel.For(0, imageSource.GetLength(0), i => { for (int j = 0; j < imageSource.GetLength(1); j++) { DoubleColor color = new DoubleColor(imageSource[i, j]); var c1 = ConvertColorToXYZ(color, from); var c2 = ConvertColorFromXYZToLAB(c1, from); imageDest[i, j] = c2; } }); }
public static DoubleColor ConvertColorFromXYZToLAB(DoubleColor color, ColorProfile cp) { //var cp = ColorProfileFactory.GetFactory().GetColorProfile(from); double YR = 100d; double XR = cp.White_X * YR / cp.White_Y; double ZR = cp.White_Z * YR / cp.White_Y; double xr = color.R / XR; double yr = color.G / YR; double zr = color.B / ZR; double k_modifier = 903.3; double eps_modifier = 0.008856; double fx; double fy; double fz; if (xr > eps_modifier) { fx = Math.Pow(xr, 1d / 3d); } else { fx = (k_modifier * xr + 16d) / 116d; } if (yr > eps_modifier) { fy = Math.Pow(yr, 1d / 3d); } else { fy = (k_modifier * yr + 16d) / 116d; } if (zr > eps_modifier) { fz = Math.Pow(zr, 1d / 3d); } else { fz = (k_modifier * zr + 16d) / 116d; } double L = 116d * fy - 16d; double a = 500d * (fx - fy); double b = 200d * (fy - fz); return(new DoubleColor(L, a, b)); }
public static void ConvertImage(SimpleColor[,] imageSource, SimpleColor[,] imageDest, ColorProfile from, ColorProfile to) { var bradfordMatrix = MyMatrix.GenerateBradfordMatrix(from, to); Parallel.For(0, imageSource.GetLength(0), i => { for (int j = 0; j < imageSource.GetLength(1); j++) { DoubleColor color = new DoubleColor(imageSource[i, j]); var c1 = ConvertColorToXYZ(color, from); var c2 = ConvertColorFromXYZ(c1, to, bradfordMatrix); imageDest[i, j] = c2.ToSimpleColor(); } }); }
public static DoubleColor ConvertColorFromLABToXYZ(DoubleColor color, ColorProfile cp) { //var cp = ColorProfileFactory.GetFactory().GetColorProfile(from); double YR = 100d; double XR = cp.White_X * YR / cp.White_Y; double ZR = cp.White_Z * YR / cp.White_Y; double xr; double yr; double zr; double k_modifier = 903.3; double eps_modifier = 0.008856; double fy = (color.R + 16d) / 116d; double fx = color.G / 500d + fy; double fz = fy - color.B / 200d; xr = Math.Pow(fx, 3); if (xr <= eps_modifier) { xr = (116d * fx - 16d) / k_modifier; } if (color.R > k_modifier * eps_modifier) { yr = Math.Pow((color.R + 16d) / 116d, 3); } else { yr = color.R / k_modifier; } zr = Math.Pow(fz, 3); if (zr <= eps_modifier) { zr = (116d * fz - 16d) / k_modifier; } double X = xr * XR; double Y = yr * YR; double Z = zr * ZR; return(new DoubleColor(X, Y, Z)); }
public static DoubleColor[,] CalculateKMeansAsync(DoubleColor[,] array, int k_means, int max_iter, double eps) { double[,] distances = new double[array.GetLength(0), array.GetLength(1)]; int[,] clusters = new int[array.GetLength(0), array.GetLength(1)]; DoubleColor[] centroids = new DoubleColor[k_means]; List <(int, int)> centroids_cords = new List <(int, int)>(); Random rand = new Random(); for (int i = 0; i < centroids.Length; i++) { int x = rand.Next(0, array.GetLength(0)); int y = rand.Next(0, array.GetLength(1)); int iters = 0; while (centroids_cords.Exists(a => DoubleColor.Distance(array[a.Item1, a.Item2], array[x, y]) < eps) == true || iters > max_iter) { x = rand.Next(0, array.GetLength(0)); y = rand.Next(0, array.GetLength(1)); iters++; } centroids[i] = array[x, y]; } for (int iter_number = 0; iter_number < max_iter; iter_number++) { //Phase Distance Calculation Parallel.For(0, array.GetLength(0), x => { for (int y = 0; y < array.GetLength(1); y++) { var minDist = double.MaxValue; int index = -1; for (int k = 0; k < centroids.Length; k++) { //if(x==0&&y==0) //{ // ; //} var cur_dist = DoubleColor.Distance(centroids[k], array[x, y]); if (cur_dist < minDist) { minDist = cur_dist; index = k; } } //if (index == -1) // ; clusters[x, y] = index; } }); //Phase Centroid Recalculation bool hasCentroidChanged = false; Parallel.For(0, centroids.Length, k => { int count = 0; DoubleColor color_sum = new DoubleColor(0d, 0d, 0d); for (int x = 0; x < array.GetLength(0); x++) { for (int y = 0; y < array.GetLength(1); y++) { if (clusters[x, y] == k) { count++; color_sum.R += array[x, y].R; color_sum.G += array[x, y].G; color_sum.B += array[x, y].B; } } } if (count != 0) { color_sum.R /= (double)count; color_sum.G /= (double)count; color_sum.B /= (double)count; } var centroid_dist = DoubleColor.Distance(centroids[k], color_sum); if (centroid_dist > eps) { centroids[k] = color_sum; hasCentroidChanged = true; } }); if (hasCentroidChanged == false) { break; } } DoubleColor[,] resultArray = new DoubleColor[array.GetLength(0), array.GetLength(1)]; Parallel.For(0, array.GetLength(0), x => { for (int y = 0; y < array.GetLength(1); y++) { resultArray[x, y] = centroids[clusters[x, y]]; } }); return(resultArray); }
public static DoubleColor ConvertColorFromXYZ(DoubleColor color, ColorProfileEnum from, ColorProfileEnum to) { ColorProfile cp = null; switch (to) { case ColorProfileEnum.sRGB: { cp = ColorProfileFactory.GetFactory().sRBGcolorProfile; } break; case ColorProfileEnum.adobeRGB: { cp = ColorProfileFactory.GetFactory().adobeRBGcolorProfile; } break; case ColorProfileEnum.appleRGB: { cp = ColorProfileFactory.GetFactory().appleRBGcolorProfile; } break; case ColorProfileEnum.CIE_RGB: { cp = ColorProfileFactory.GetFactory().CIE_RBGcolorProfile; } break; case ColorProfileEnum.WideGamut: { cp = ColorProfileFactory.GetFactory().WideGamutcolorProfile; } break; case ColorProfileEnum.PAL: { cp = ColorProfileFactory.GetFactory().PALcolorProfile; } break; default: break; } //color.InverseGammaCorrection(cp.Gamma); MyMatrix bradford = MyMatrix.GenerateBradfordMatrix(from, to); if (bradford != null) { (color.R, color.G, color.B) = bradford.MultiplyByVectorRight(color.R, color.G, color.B); } var v = cp.XYZtoRGB.MultiplyByVectorRight(color.R, color.G, color.B); DoubleColor XYZ = new DoubleColor(v.X, v.Y, v.Z); XYZ.GammaCorrection(cp.Gamma); return(XYZ); //return new DoubleColor(-1, -1, -1); }
public static void CreateHSVBitmap(SimpleColor[,] pixels) { int middle_x = pixels.GetLength(1) / 2; int middle_y = pixels.GetLength(0) / 2; for (int y = 0; y < pixels.GetLength(0); y++) { for (int x = 0; x < pixels.GetLength(1); x++) { if (y < Globals.BorderWidth || y > pixels.GetLength(0) - Globals.BorderWidth || x < Globals.BorderWidth || x > pixels.GetLength(1) - Globals.BorderWidth) { pixels[y, x] = new SimpleColor(0, 0, 0); } else { pixels[y, x] = new SimpleColor(255, 255, 255); double dist = Distance(middle_x, middle_y, x, y); if (dist <= Globals.Radius) { //calculate HSV //double V = 1; double C = dist / (double)Globals.Radius; double m = 1 - C; double cos = Cosinus(middle_x, middle_y, x, y, dist); if (y <= middle_y)// angle between 0 and pi { double H = Math.Acos(cos); double angleH = H * 180d / Math.PI; double int_H = (angleH / 60d); //C to dist double X = C * (1 - Math.Abs((int_H % 2) - 1)); if (int_H <= 1) { var color = new DoubleColor(C + m, X + m, m); var simpleColor = color.ToSimpleColor(); //double R = 0.5 + C * Math.Cos(angleH) / Math.Cos(60 - H); //double B = 0.5 - C; //double G = 1.5 - B - R; //color = new DoubleColor(R, G, B); //simpleColor = color.ToSimpleColor(); pixels[y, x] = simpleColor; } else if (int_H <= 2) { var color = new DoubleColor(X + m, C + m, m); pixels[y, x] = color.ToSimpleColor(); } else { var color = new DoubleColor(m, C + m, X + m); pixels[y, x] = color.ToSimpleColor(); } } else // angle between pi and 2 pi { double H = Math.Acos(cos); double angleH = 360d - H * 180 / Math.PI; double int_H = (angleH / 60); //C to dist double X = C * (1 - Math.Abs((int_H % 2) - 1)); if (int_H <= 4) { var color = new DoubleColor(m, X + m, C + m); pixels[y, x] = color.ToSimpleColor(); } else if (int_H <= 5) { var color = new DoubleColor(X + m, m, C + m); pixels[y, x] = color.ToSimpleColor(); } else { var color = new DoubleColor(C + m, m, X + m); pixels[y, x] = color.ToSimpleColor(); } } } } } } }
private void TestButtonRadioButton_Click(object sender, RoutedEventArgs e) { var tab1 = new float[2]; var tab2 = new float[2]; var tab3 = new float[2]; for (int i = 0; i < tab1.Length; i++) { if (i == 0) { tab1[i] = 1f; tab2[i] = 1f; tab3[i] = 1f; } else { tab1[i] = 2f; tab2[i] = 2f; tab3[i] = 2f; } } var inttab1 = new int[10]; var inttab2 = new int[10]; for (int i = 0; i < inttab1.Length; i++) { inttab1[i] = 3; inttab2[i] = 7; } DoubleColor[,] LABImageArray = new DoubleColor[SourceImageColorArray.GetLength(0), SourceImageColorArray.GetLength(1)]; int from = SourceColorSpaceComboBox.SelectedIndex; ColorProfileConverter.ConvertImageToLAB(SourceImageColorArray, LABImageArray, (ColorProfileEnum)from); int rows = LABImageArray.GetLength(0); int cols = LABImageArray.GetLength(1); var vector_x = new float[rows * cols]; var vector_y = new float[rows * cols]; var vector_z = new float[rows * cols]; for (int x = 0; x < rows; x++) { for (int y = 0; y < cols; y++) { vector_x[y + x * cols] = (float)LABImageArray[x, y].R; vector_y[y + x * cols] = (float)LABImageArray[x, y].G; vector_z[y + x * cols] = (float)LABImageArray[x, y].B; } } using (var wrapper = new Logic()) { //var result = wrapper.addParallelVectors(inttab1, inttab2, inttab1.Length); //for (int i = 0; i < result.Length; i++) //{ // Debug.Write($"{result[i]}, "); //} //Debug.WriteLine(""); var iters = wrapper.KMeansGather(tab1, tab2, tab3, tab1.Length, 1, MaxIter); Debug.WriteLine($"KMEANS: Iters: {iters}"); for (int i = 0; i < tab1.Length; i++) { Debug.WriteLine($"X: {tab1[i]} Y: {tab2[i]} Z: {tab3[i]}"); } var img_iters = wrapper.KMeansGather(vector_x, vector_y, vector_z, vector_x.Length, KMeansParam, MaxIter); Debug.WriteLine($"Image iterations: {img_iters}"); } for (int x = 0; x < rows; x++) { for (int y = 0; y < cols; y++) { LABImageArray[x, y].R = vector_x[y + x * cols]; LABImageArray[x, y].G = vector_y[y + x * cols]; LABImageArray[x, y].B = vector_z[y + x * cols]; } } ColorProfileConverter.ConvertImageFromLAB(LABImageArray, DestImageColorArray, (ColorProfileEnum)from); Paint.CopyToWriteableBitmap(DestImageWB, DestImageColorArray); }