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(); } } } } } } }
public DoubleColor(SimpleColor color) { R = (double)color.R / 255d; G = (double)color.G / 255d; B = (double)color.B / 255d; }
//param 0-gather, 1-scatter, 2-reduce_by_key private void KMeansGPULaunch(int param) { var start1 = DateTime.Now; int rows = SourceImageColorArray.GetLength(0); int cols = SourceImageColorArray.GetLength(1); var colors_array = new int[rows * cols]; for (int x = 0; x < rows; x++) { for (int y = 0; y < cols; y++) { colors_array[y + x * cols] = SourceImageColorArray[x, y].ToInt(); } } var RGBtoXYZMatrix = SourceImageCP.RGBtoXYZ.toFloatMatrix(); var XYZtoRGBMatrix = SourceImageCP.XYZtoRGB.toFloatMatrix(); float YR = 100f; double XR_double = SourceImageCP.White_X * YR / SourceImageCP.White_Y; double ZR_double = SourceImageCP.White_Z * YR / SourceImageCP.White_Y; float XR = (float)XR_double; float ZR = (float)ZR_double; float gamma = (float)SourceImageCP.Gamma; var start2 = DateTime.Now; using (var wrapper = new Logic()) { try { var img_iters = wrapper.KMeansImage(colors_array, colors_array.Length, XR, YR, ZR, gamma, RGBtoXYZMatrix, XYZtoRGBMatrix, KMeansParam, MaxIter, param); Debug.WriteLine($"Image iterations: {img_iters}"); } catch (Exception e) { Debug.WriteLine($"Unexpected error: {e.Message}"); return; } } var end = DateTime.Now; for (int x = 0; x < rows; x++) { for (int y = 0; y < cols; y++) { DestImageColorArray[x, y] = new SimpleColor(colors_array[y + x * cols]); } } Dispatcher.Invoke(() => { Paint.CopyToWriteableBitmap(DestImageWB, colors_array, rows, cols); }); string method = "NONE"; if (param == 0) { method = "GATHER"; } else if (param == 1) { method = "SCATTER"; } else if (param == 2) { method = "RBK"; } Debug.WriteLine($"GPU TIME[{method}]: {end - start2} , with memory allocation: {end - start1}"); }