public static void QuickCorr(GThread thread, ProfileStrucuture[, ,] profile_GPU, ForeGroundStrucuture[] foregorungRGB_GPU, BackGroundStrucuture[] BackgroundXYZ_GPU, TestingStructure[] ptr, SampleStructure[,] samples) { // map from threadIdx/BlockIdx to pixel position int x = thread.threadIdx.x + thread.blockIdx.x * thread.blockDim.x; int y = thread.threadIdx.y + thread.blockIdx.y * thread.blockDim.y; int offset = x + y * thread.blockDim.x * thread.gridDim.x; double ox = (x - 1.0 / 2.0); double oy = (y - 1.0 / 2.0); // double closestColor = double.MaxValue; double diffL = 0.0; double diffA = 0.0; double diffB = 0.0; //int BestL = 0; //int BestA = 0; //int BestB = 0; //1 - Converts the foreground to how the display shows it ProfileStrucuture foregroundColorToShow = new ProfileStrucuture(); ProfileStrucuture foregroundLAB = ToLAB(foregorungRGB_GPU[offset]); int binL = ((int)Math.Round(foregroundLAB.L / 5.0)) * 5; int binA = ((int)Math.Round(foregroundLAB.A / 5.0)) * 5; int binB = ((int)Math.Round(foregroundLAB.B / 5.0)) * 5; if (binL > 100) binL = 100; if (binA < -86.17385493791946) binA = -85; if (binA > 98.2448002875424) binA = 100; if (binB < -107.8619171648283) binB = -110; if (binB > 94.47705120353054) binB = 95; binL = (int)(binL * 0.2) + 0; binA = (int)(binA * 0.2) + 20; binB = (int)(binB * 0.2) + 22; foregroundColorToShow.ML = profile_GPU[binL, binA, binB].ML; foregroundColorToShow.MA = profile_GPU[binL, binA, binB].MA; foregroundColorToShow.MB = profile_GPU[binL, binA, binB].MB; //1.1 - Extra step for Quick Correction Point3D origin = new Point3D(10.0, 20.0, 22.0); Point3D step = new Point3D(10, 20, 22); //2 - Get the accuracy ProfileStrucuture actualBin = GetProfileBin(origin.X, origin.Y, origin.Z, profile_GPU); if (actualBin.isempty == TRUE) return; BackGroundStrucuture PredictionXYZ = addXYZ_st(actualBin.MX, actualBin.MY, actualBin.MZ, BackgroundXYZ_GPU[offset]); ProfileStrucuture PredictionLAB = XYZtoLAB_st(PredictionXYZ); //diffL = foregroundColorToShow.ML - PredictionLAB.L; //diffA = foregroundColorToShow.MA - PredictionLAB.A; //diffB = foregroundColorToShow.MB - PredictionLAB.B; diffL = PredictionLAB.L - foregroundColorToShow.ML; diffA = PredictionLAB.A - foregroundColorToShow.MA; diffB = PredictionLAB.B - foregroundColorToShow.MB; //diffL = PredictionXYZ.X - foregroundColorToShow.MX; //diffA = PredictionXYZ.Y - foregroundColorToShow.MY; //diffB = PredictionXYZ.Z - foregroundColorToShow.MZ; diffL = diffL * diffL; diffA = diffA * diffA; diffB = diffB * diffB; //originBin.distanceLAB actualBin.distance = Math.Sqrt(diffL + diffA + diffB); //declaring 6 separate samples - CUDA does not support array declaration in kernel device code Point3D top = new Point3D(); Point3D bottom = new Point3D(); Point3D left = new Point3D(); Point3D right = new Point3D(); Point3D forward = new Point3D(); Point3D backward = new Point3D(); while (step.X > 0 || step.Y > 0 && step.Z > 0) { //sample 6 bins top.X = origin.X + step.X; top.Y = origin.Y; top.Z = origin.Z; bottom.X = origin.X - step.X; bottom.Y = origin.Y; bottom.Z = origin.Z; left.X = origin.X; left.Y = origin.Y - step.Y; left.Z = origin.Z; right.X = origin.X; right.Y = origin.Y + step.Y; right.Z = origin.Z; forward.X = origin.X; forward.Y = origin.Y; forward.Z = origin.Z - step.Z; backward.X = origin.X; backward.Y = origin.Y; backward.Z = origin.Z + step.Z; samples[offset, 0] = GetProfileBinForSample(top.X, top.Y, top.Z, profile_GPU); samples[offset, 1] = GetProfileBinForSample(bottom.X, bottom.Y, bottom.Z, profile_GPU); samples[offset, 2] = GetProfileBinForSample(left.X, left.Y, left.Z, profile_GPU); samples[offset, 3] = GetProfileBinForSample(right.X, right.Y, right.Z, profile_GPU); samples[offset, 4] = GetProfileBinForSample(forward.X, forward.Y, forward.Z, profile_GPU); samples[offset, 5] = GetProfileBinForSample(backward.X, backward.Y, backward.Z, profile_GPU); int countSamplesClosestThanOrigin = 0; //calculate color correction for all samples #region for (int index = 0; index < 6; index++) { if (samples[offset, index].isempty == TRUE || samples[offset, index].isempty == 0.0) continue; BackGroundStrucuture temp_XYZ = addXYZ_st(samples[offset, index].MX, samples[offset, index].MY, samples[offset, index].MZ, BackgroundXYZ_GPU[offset]); ProfileStrucuture PredictionlAB = XYZtoLAB_st(temp_XYZ); diffL = PredictionlAB.L - foregroundColorToShow.ML; diffA = PredictionlAB.A - foregroundColorToShow.MA; diffB = PredictionlAB.B - foregroundColorToShow.MB; diffL = diffL * diffL; diffA = diffA * diffA; diffB = diffB * diffB; //curr_distanceLAB samples[offset, index].distance = Math.Sqrt(diffL + diffA + diffB); if (samples[offset, index].distance >= actualBin.distance) { continue; } else { samples[offset, index].isMoreAccurateThanOrigin = (int)TRUE; countSamplesClosestThanOrigin++; } } #endregion if (countSamplesClosestThanOrigin == 0) { step = HalfTheStep(step); continue; } //if there is at least one sample more accurate, it moves the origin in that direction, maintains the step and checks again else { //6.1 calculates weights double totalimprovements = 0; for (int index = 0; index < 6; index++) { if (!(samples[offset, index].isMoreAccurateThanOrigin == TRUE)) { continue; } totalimprovements += (actualBin.distance - samples[offset, index].distance); } for (int index = 0; index < 6; index++) { if (!(samples[offset, index].isMoreAccurateThanOrigin == 1)) { continue; } samples[offset, index].weight = ((actualBin.distance - samples[offset, index].distance) / totalimprovements); } //6.2 calculates displacement Point3D displacement = new Point3D(0, 0, 0); for (int index = 0; index < 6; index++) { if (!(samples[offset, index].isMoreAccurateThanOrigin == 1)) { continue; } displacement.X = displacement.X + (samples[offset, index].L - origin.X) * samples[offset, index].weight; displacement.Y = displacement.Y + (samples[offset, index].A - origin.Y) * samples[offset, index].weight; displacement.Z = displacement.Z + (samples[offset, index].B - origin.Z) * samples[offset, index].weight; } if (displacement.X > 0) displacement.X = Math.Ceiling(displacement.X); else displacement.X = Math.Floor(displacement.X); if (displacement.Y > 0) displacement.Y = Math.Ceiling(displacement.Y); else displacement.Y = Math.Floor(displacement.Y); if (displacement.Z > 0) displacement.Z = Math.Ceiling(displacement.Z); else displacement.Z = Math.Floor(displacement.Z); //6.3 pokes new origin Point3D newOriginLoc = new Point3D(); newOriginLoc.X = origin.X + displacement.X; newOriginLoc.Y = origin.Y + displacement.Y; newOriginLoc.Z = origin.Z + displacement.Z; ProfileStrucuture newOriginBin = GetProfileBin(newOriginLoc.X, newOriginLoc.Y, newOriginLoc.Z, profile_GPU); while (newOriginBin.isempty == TRUE) { /////////////////////// round to even missing /////////////////// //6.4 moves half the magnitude in the given direction displacement.X = Math.Round(displacement.X / 2); displacement.Y = Math.Round(displacement.Y / 2); displacement.Z = Math.Round(displacement.Z / 2); newOriginLoc.X = origin.X + displacement.X; newOriginLoc.Y = origin.Y + displacement.Y; newOriginLoc.Z = origin.Z + displacement.Z; newOriginBin = GetProfileBin(newOriginLoc.X, newOriginLoc.Y, newOriginLoc.Z, profile_GPU); } //calclates the accuracy of the posible new origin if (newOriginBin.isempty == TRUE) return; PredictionXYZ = addXYZ_st(newOriginBin.MX, newOriginBin.MY, newOriginBin.MZ, BackgroundXYZ_GPU[offset]); ProfileStrucuture PredictionlAB = XYZtoLAB_st(PredictionXYZ); diffL = PredictionlAB.L - foregroundColorToShow.ML; diffA = PredictionlAB.A - foregroundColorToShow.MA; diffB = PredictionlAB.B - foregroundColorToShow.MB; //diffL = PredictionXYZ.X - foregroundColorToShow.MX; //diffA = PredictionXYZ.Y - foregroundColorToShow.MY; //diffB = PredictionXYZ.Z - foregroundColorToShow.MZ; diffL = diffL * diffL; diffA = diffA * diffA; diffB = diffB * diffB; //originBin.distanceLAB newOriginBin.distance = Math.Sqrt(diffL + diffA + diffB); if ((origin.X == newOriginLoc.X && origin.Y == newOriginLoc.Y && origin.Z == newOriginLoc.Z) || actualBin.distance <= newOriginBin.distance) // it's the same location then just reduces the step step = HalfTheStep(step); else { origin = newOriginLoc; actualBin = newOriginBin; } } } TestingStructure ValueToReturn = new TestingStructure(); ValueToReturn.Given_R = actualBin.L; ValueToReturn.Given_G = actualBin.A; ValueToReturn.Given_B = actualBin.B; ValueToReturn.distance = actualBin.distance; ptr[offset] = ValueToReturn; }
public static TestingStructure[] CorrectColour(System.Drawing.Color rgb, double X, double Y, double Z) { //rgb = System.Drawing.Color.FromArgb(69, 77, 217); //X = 0.0630982813175294; //Y = 0.616476271122916; //Z = 0.667048468232457; //cuda intializer CudafyModule km = CudafyModule.TryDeserialize(); if (km == null || !km.TryVerifyChecksums()) { // km = CudafyTranslator.Cudafy((typeof(ForeGroundStrucuture)), (typeof(BackGroundStrucuture)), typeof(Color)); km = CudafyTranslator.Cudafy((typeof(ProfileStrucuture)), (typeof(ForeGroundStrucuture)), (typeof(BackGroundStrucuture)), (typeof(SampleStructure)), (typeof(TestingStructure)), typeof(quick_corr)); km.TrySerialize(); } CudafyTranslator.GenerateDebug = true; // cuda or emulator GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId); //GPGPU gpu = CudafyHost.GetDevice(eGPUType.Emulator); Console.WriteLine("Running quick correction using {0}", gpu.GetDeviceProperties(false).Name); gpu.LoadModule(km); TestingStructure[] distance_CPU = new TestingStructure[1]; // allocate memory on the GPU for the bitmap (same size as ptr) #region DataTable profile = new DataTable(); try { // add the csv bin file using (GenericParserAdapter parser = new GenericParserAdapter(@"C:\lev\STColorCorrection\Data\PROFILE\p3700.csv")) { System.Data.DataSet dsResult = parser.GetDataSet(); profile = dsResult.Tables[0]; } } catch (Exception ex) { Console.WriteLine(ex); } #endregion // allocate temp memory, initialize it, copy to constant memory on the GPU // L 0-21 A 0-41 B 0-45 ProfileStrucuture[, ,] profiles_CPU = new ProfileStrucuture[21, 41, 45]; ForeGroundStrucuture[] foregorungRGB_CPU = new ForeGroundStrucuture[1]; BackGroundStrucuture[] BackgroundXYZ_CPU = new BackGroundStrucuture[1]; SampleStructure[,] samples_CPU = new SampleStructure[1, 6]; //profile inicialization #region for (int indexL = 0; indexL < 21; indexL++) { for (int indexA = 0; indexA < 41; indexA++) { for (int indexB = 0; indexB < 45; indexB++) { profiles_CPU[indexL, indexA, indexB].L = indexL; profiles_CPU[indexL, indexA, indexB].A = indexA; profiles_CPU[indexL, indexA, indexB].B = indexB; //profiles_CPU[indexL, indexA, indexB].Given_R = 0; //profiles_CPU[indexL, indexA, indexB].Given_G = 0; //profiles_CPU[indexL, indexA, indexB].Given_B = 0; profiles_CPU[indexL, indexA, indexB].ML = 0; profiles_CPU[indexL, indexA, indexB].MA = 0; profiles_CPU[indexL, indexA, indexB].MB = 0; profiles_CPU[indexL, indexA, indexB].MX = 0; profiles_CPU[indexL, indexA, indexB].MY = 0; profiles_CPU[indexL, indexA, indexB].MZ = 0; profiles_CPU[indexL, indexA, indexB].distance = -1.0; profiles_CPU[indexL, indexA, indexB].weight = -1.0; profiles_CPU[indexL, indexA, indexB].isempty = TRUE; profiles_CPU[indexL, indexA, indexB].isMoreAccurateThanOrigin = FALSE; } } } int lvalue, avalue, bvalue; try { for (int i = 1; i < profile.Rows.Count; i++) { lvalue = Convert.ToInt32(profile.Rows[i][0].ToString()); avalue = Convert.ToInt32(profile.Rows[i][1].ToString()); bvalue = Convert.ToInt32(profile.Rows[i][2].ToString()); lvalue = (int)(lvalue * 0.2); avalue = (int)(avalue * 0.2) + 20; bvalue = (int)(bvalue * 0.2) + 22; profiles_CPU[lvalue, avalue, bvalue].L = lvalue; profiles_CPU[lvalue, avalue, bvalue].A = avalue; profiles_CPU[lvalue, avalue, bvalue].B = bvalue; //profiles_CPU[lvalue, avalue, bvalue].Given_R = (double)Convert.ToByte(profile.Rows[i][9].ToString()); //profiles_CPU[lvalue, avalue, bvalue].Given_G = (double)Convert.ToByte(profile.Rows[i][10].ToString()); //profiles_CPU[lvalue, avalue, bvalue].Given_B = (double)Convert.ToByte(profile.Rows[i][11].ToString()); profiles_CPU[lvalue, avalue, bvalue].ML = (double)Convert.ToDouble(profile.Rows[i][3].ToString()); profiles_CPU[lvalue, avalue, bvalue].MA = (double)Convert.ToDouble(profile.Rows[i][4].ToString()); profiles_CPU[lvalue, avalue, bvalue].MB = (double)Convert.ToDouble(profile.Rows[i][5].ToString()); profiles_CPU[lvalue, avalue, bvalue].MX = (double)Convert.ToDouble(profile.Rows[i][6].ToString()); profiles_CPU[lvalue, avalue, bvalue].MY = (double)Convert.ToDouble(profile.Rows[i][7].ToString()); profiles_CPU[lvalue, avalue, bvalue].MZ = (double)Convert.ToDouble(profile.Rows[i][8].ToString()); profiles_CPU[lvalue, avalue, bvalue].isempty = FALSE; } } catch (Exception ex) { Console.WriteLine(ex); } #endregion //grab the colors ProfileStrucuture[, ,] profile_GPU = gpu.CopyToDevice(profiles_CPU); SampleStructure[,] samples_GPU = gpu.CopyToDevice(samples_CPU); Point3D background = new Point3D(X, Y, Z); //foreground and background image inicialization #region try { for (int i = 0; i < 1; i++) { foregorungRGB_CPU[i].R = rgb.R; foregorungRGB_CPU[i].G = rgb.G; foregorungRGB_CPU[i].B = rgb.B; BackgroundXYZ_CPU[i].X = background.X; BackgroundXYZ_CPU[i].Y = background.Y; BackgroundXYZ_CPU[i].Z = background.Z; } } catch (Exception ex) { Console.WriteLine(ex); } #endregion //begin execution // capture the start time gpu.StartTimer(); ForeGroundStrucuture[] foregorungRGB_GPU = gpu.CopyToDevice(foregorungRGB_CPU); BackGroundStrucuture[] BackgroundXYZ_GPU = gpu.CopyToDevice(BackgroundXYZ_CPU); //out put TestingStructure[] distance_GPU = gpu.Allocate(distance_CPU); // generate a bitmap from our sphere data //Image size: 1024 x 768 //dim3 grids = new dim3(1024 / 16, 768 / 16); //dim3 threads = new dim3(16, 16); dim3 grids = new dim3(1, 1); dim3 threads = new dim3(1, 1); //quick_correct //gpu.Launch(grids, threads, ((Action<GThread, ProfileStrucuture[, ,], ForeGroundStrucuture[], BackGroundStrucuture[], ProfileStrucuture[], SampleStructure[,]>)QuickCorr), profile_GPU, foregorungRGB_GPU, BackgroundXYZ_GPU, distance_GPU, samples_GPU); //quick correct - testing gpu.Launch(grids, threads, ((Action<GThread, ProfileStrucuture[, ,], ForeGroundStrucuture[], BackGroundStrucuture[], TestingStructure[], SampleStructure[,]>)QuickCorr), profile_GPU, foregorungRGB_GPU, BackgroundXYZ_GPU, distance_GPU, samples_GPU); // copy our bitmap back from the GPU for display gpu.CopyFromDevice(distance_GPU, distance_CPU); // get stop time, and display the timing results double elapsedTime = gpu.StopTimer(); distance_CPU[0].execution_time = elapsedTime; Console.WriteLine("Time to generate: {0} ms", elapsedTime); gpu.Free(foregorungRGB_GPU); gpu.Free(BackgroundXYZ_GPU); gpu.Free(distance_GPU); gpu.FreeAll(); return distance_CPU; }
//public static void Execute() //{ // //cuda intializer // CudafyModule km = CudafyModule.TryDeserialize(); // if (km == null || !km.TryVerifyChecksums()) // { // // km = CudafyTranslator.Cudafy((typeof(ForeGroundStrucuture)), (typeof(BackGroundStrucuture)), typeof(Color)); // km = CudafyTranslator.Cudafy(typeof(ProfileStrucuture),typeof(ForeGroundStrucuture), typeof(BackGroundStrucuture), typeof(Color)); // km.TrySerialize(); // } // CudafyTranslator.GenerateDebug = true; // // cuda or emulator // GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId); // //GPGPU gpu = CudafyHost.GetDevice(eGPUType.Emulator); // gpu.LoadModule(km); // ProfileStrucuture[] distance_CPU = new ProfileStrucuture[786432]; // // allocate memory on the GPU for the bitmap (same size as ptr) // DataTable profile = new DataTable(); // try // { // // add the csv bin file // using (GenericParserAdapter parser = new GenericParserAdapter(@"C:\lev\STColorCorrection\Data\PROFILE\p3700.csv")) // { // System.Data.DataSet dsResult = parser.GetDataSet(); // profile = dsResult.Tables[0]; // } // } // catch(Exception ex) // {Console.WriteLine(ex); } // // allocate temp memory, initialize it, copy to constant memory on the GPU // // L 0-21 A 0-41 B 0-45 // ProfileStrucuture[ , , ] profiles_CPU = new ProfileStrucuture[21,41,45]; // ForeGroundStrucuture[] foregorungRGB_CPU = new ForeGroundStrucuture[786432]; // BackGroundStrucuture[] BackgroundXYZ_CPU = new BackGroundStrucuture[786432]; // for (int indexL = 0; indexL < 21; indexL++) // { // for (int indexA = 0; indexA < 41; indexA++) // { // for (int indexB = 0; indexB < 45; indexB++) // { // profiles_CPU[indexL, indexA, indexB].L = indexL; // profiles_CPU[indexL, indexA, indexB].A = indexA; // profiles_CPU[indexL, indexA, indexB].B = indexB; // //profiles_CPU[indexL, indexA, indexB].Given_R = 0; // //profiles_CPU[indexL, indexA, indexB].Given_G = 0; // //profiles_CPU[indexL, indexA, indexB].Given_B = 0; // profiles_CPU[indexL, indexA, indexB].ML = 0; // profiles_CPU[indexL, indexA, indexB].MA = 0; // profiles_CPU[indexL, indexA, indexB].MB = 0; // profiles_CPU[indexL, indexA, indexB].MX = 0; // profiles_CPU[indexL, indexA, indexB].MY = 0; // profiles_CPU[indexL, indexA, indexB].MZ = 0; // profiles_CPU[indexL, indexA, indexB].isempty = -1; // profiles_CPU[indexL, indexA, indexB].isMoreAccurateThanOrigin = -1; // } // } // } // int lvalue, avalue, bvalue; // try // { // for (int i = 1; i < profile.Rows.Count; i++) // { // lvalue=Convert.ToInt32 (profile.Rows[i][0].ToString()); // avalue = Convert.ToInt32(profile.Rows[i][1].ToString()); // bvalue= Convert.ToInt32(profile.Rows[i][2].ToString()); // lvalue=(int)(lvalue*0.2); // avalue=(int)(avalue*0.2)+20; // bvalue=(int)(bvalue*0.2)+22; // profiles_CPU[lvalue, avalue, bvalue].L = lvalue; // profiles_CPU[lvalue, avalue, bvalue].A = avalue; // profiles_CPU[lvalue, avalue, bvalue].B = bvalue; // //profiles_CPU[lvalue, avalue, bvalue].Given_R = (double)Convert.ToByte(profile.Rows[i][9].ToString()); // //profiles_CPU[lvalue, avalue, bvalue].Given_G = (double)Convert.ToByte(profile.Rows[i][10].ToString()); // //profiles_CPU[lvalue, avalue, bvalue].Given_B = (double)Convert.ToByte(profile.Rows[i][11].ToString()); // profiles_CPU[lvalue, avalue, bvalue].ML = (double)Convert.ToDouble(profile.Rows[i][3].ToString()); // profiles_CPU[lvalue, avalue, bvalue].MA = (double)Convert.ToDouble(profile.Rows[i][4].ToString()); // profiles_CPU[lvalue, avalue, bvalue].MB = (double)Convert.ToDouble(profile.Rows[i][5].ToString()); // profiles_CPU[lvalue, avalue, bvalue].MX = (double)Convert.ToDouble(profile.Rows[i][6].ToString()); // profiles_CPU[lvalue, avalue, bvalue].MY = (double)Convert.ToDouble(profile.Rows[i][7].ToString()); // profiles_CPU[lvalue, avalue, bvalue].MZ = (double)Convert.ToDouble(profile.Rows[i][8].ToString()); // profiles_CPU[lvalue, avalue, bvalue].isempty = 1; // } // } // catch (Exception ex) // { Console.WriteLine(ex); } // try // { // for (int i = 0; i < 786432; i++) // { // foregorungRGB_CPU[i].R = 1; // foregorungRGB_CPU[i].G = 1; // foregorungRGB_CPU[i].B = 255; // BackgroundXYZ_CPU[i].X = 0.629866667F; // BackgroundXYZ_CPU[i].Y = 0.653533333F; // BackgroundXYZ_CPU[i].Z = 0.684966667F; // } // } // catch (Exception ex) // { Console.WriteLine(ex); } // ProfileStrucuture[, ,] profile_GPU = gpu.CopyToDevice(profiles_CPU); // for (int i = 0; i < 1; i++) // { // // capture the start time // gpu.StartTimer(); // ForeGroundStrucuture[] foregorungRGB_GPU = gpu.CopyToDevice(foregorungRGB_CPU); // BackGroundStrucuture[] BackgroundXYZ_GPU = gpu.CopyToDevice(BackgroundXYZ_CPU); // //out put // ProfileStrucuture[] distance_GPU = gpu.Allocate(distance_CPU); // // generate a bitmap from our sphere data // //Image size: 1024 x 768 // //dim3 grids = new dim3(1, 1); // //dim3 threads = new dim3(1,1); // dim3 grids = new dim3(1024 / 16, 768 / 16); // dim3 threads = new dim3(16, 16); // gpu.Launch(grids, threads, ((Action<GThread, ProfileStrucuture[, ,], ForeGroundStrucuture[], BackGroundStrucuture[], ProfileStrucuture[]>)Bruteforce), profile_GPU, foregorungRGB_GPU, BackgroundXYZ_GPU, distance_GPU); // //gpu.Launch(grids, threads, ((Action<GThread, ForeGroundStrucuture[], BackGroundStrucuture[], double[]>)Bruteforce), foregorungRGB_GPU, BackgroundXYZ_GPU, distance_GPU); // // copy our bitmap back from the GPU for display // gpu.CopyFromDevice(distance_GPU, distance_CPU); // // get stop time, and display the timing results // double elapsedTime = gpu.StopTimer(); // Console.WriteLine("Time to generate: {0} ms", elapsedTime); // gpu.Free(foregorungRGB_GPU); // gpu.Free(BackgroundXYZ_GPU); // gpu.Free(distance_GPU); // } // gpu.FreeAll(); // } public static TestingStructure[] CorrectColour(System.Drawing.Color rgb, double X, double Y, double Z) { //set these to constant if you want testing //rgb = System.Drawing.Color.FromArgb(65, 108, 20); //X = 0.613829950099918; //Y = 0.938638756488747; //Z = 1.08019833591292; //cuda intializer CudafyModule km = CudafyModule.TryDeserialize(); if (km == null || !km.TryVerifyChecksums()) { // km = CudafyTranslator.Cudafy((typeof(ForeGroundStrucuture)), (typeof(BackGroundStrucuture)), typeof(Color)); km = CudafyTranslator.Cudafy(typeof(ProfileStrucuture), typeof(ForeGroundStrucuture), typeof(BackGroundStrucuture), typeof(TestingStructure), typeof(Color)); km.TrySerialize(); } CudafyTranslator.GenerateDebug = true; // cuda or emulator GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId); //sGPGPU gpu = CudafyHost.GetDevice(eGPUType.Emulator); gpu.LoadModule(km); Console.WriteLine("Running brute force correction using {0}", gpu.GetDeviceProperties(false).Name); TestingStructure[] distance_CPU = new TestingStructure[1]; // allocate memory on the GPU for the bitmap (same size as ptr) DataTable profile = new DataTable(); try { // add the csv bin file using (GenericParserAdapter parser = new GenericParserAdapter(@"C:\lev\STColorCorrection\Data\PROFILE\p3700.csv")) { System.Data.DataSet dsResult = parser.GetDataSet(); profile = dsResult.Tables[0]; } } catch (Exception ex) { Console.WriteLine(ex); } // allocate temp memory, initialize it, copy to constant memory on the GPU // L 0-21 A 0-41 B 0-45 ProfileStrucuture[ , , ] profiles_CPU = new ProfileStrucuture[21, 41, 45]; ForeGroundStrucuture[] foregorungRGB_CPU = new ForeGroundStrucuture[1]; BackGroundStrucuture[] BackgroundXYZ_CPU = new BackGroundStrucuture[1]; for (int indexL = 0; indexL < 21; indexL++) { for (int indexA = 0; indexA < 41; indexA++) { for (int indexB = 0; indexB < 45; indexB++) { profiles_CPU[indexL, indexA, indexB].L = indexL; profiles_CPU[indexL, indexA, indexB].A = indexA; profiles_CPU[indexL, indexA, indexB].B = indexB; //profiles_CPU[indexL, indexA, indexB].Given_R = 0; //profiles_CPU[indexL, indexA, indexB].Given_G = 0; //profiles_CPU[indexL, indexA, indexB].Given_B = 0; profiles_CPU[indexL, indexA, indexB].ML = 0; profiles_CPU[indexL, indexA, indexB].MA = 0; profiles_CPU[indexL, indexA, indexB].MB = 0; profiles_CPU[indexL, indexA, indexB].MX = 0; profiles_CPU[indexL, indexA, indexB].MY = 0; profiles_CPU[indexL, indexA, indexB].MZ = 0; profiles_CPU[indexL, indexA, indexB].isempty = TRUE; profiles_CPU[indexL, indexA, indexB].isMoreAccurateThanOrigin = -1; } } } int lvalue, avalue, bvalue; try { for (int i = 1; i < profile.Rows.Count; i++) { lvalue = Convert.ToInt32(profile.Rows[i][0].ToString()); avalue = Convert.ToInt32(profile.Rows[i][1].ToString()); bvalue = Convert.ToInt32(profile.Rows[i][2].ToString()); lvalue = (int)(lvalue * 0.2); avalue = (int)(avalue * 0.2) + 20; bvalue = (int)(bvalue * 0.2) + 22; profiles_CPU[lvalue, avalue, bvalue].L = lvalue; profiles_CPU[lvalue, avalue, bvalue].A = avalue; profiles_CPU[lvalue, avalue, bvalue].B = bvalue; //profiles_CPU[lvalue, avalue, bvalue].Given_R = (double)Convert.ToByte(profile.Rows[i][9].ToString()); //profiles_CPU[lvalue, avalue, bvalue].Given_G = (double)Convert.ToByte(profile.Rows[i][10].ToString()); //profiles_CPU[lvalue, avalue, bvalue].Given_B = (double)Convert.ToByte(profile.Rows[i][11].ToString()); profiles_CPU[lvalue, avalue, bvalue].ML = (double)Convert.ToDouble(profile.Rows[i][3].ToString()); profiles_CPU[lvalue, avalue, bvalue].MA = (double)Convert.ToDouble(profile.Rows[i][4].ToString()); profiles_CPU[lvalue, avalue, bvalue].MB = (double)Convert.ToDouble(profile.Rows[i][5].ToString()); profiles_CPU[lvalue, avalue, bvalue].MX = (double)Convert.ToDouble(profile.Rows[i][6].ToString()); profiles_CPU[lvalue, avalue, bvalue].MY = (double)Convert.ToDouble(profile.Rows[i][7].ToString()); profiles_CPU[lvalue, avalue, bvalue].MZ = (double)Convert.ToDouble(profile.Rows[i][8].ToString()); profiles_CPU[lvalue, avalue, bvalue].isempty = FALSE; } } catch (Exception ex) { Console.WriteLine(ex); } //foreground and background image inicialization #region try { for (int i = 0; i < 1; i++) { foregorungRGB_CPU[i].R = rgb.R; foregorungRGB_CPU[i].G = rgb.G; foregorungRGB_CPU[i].B = rgb.B; BackgroundXYZ_CPU[i].X = X; BackgroundXYZ_CPU[i].Y = Y; BackgroundXYZ_CPU[i].Z = Z; } } catch (Exception ex) { Console.WriteLine(ex); } #endregion ProfileStrucuture[, ,] profile_GPU = gpu.CopyToDevice(profiles_CPU); // capture the start time gpu.StartTimer(); ForeGroundStrucuture[] foregorungRGB_GPU = gpu.CopyToDevice(foregorungRGB_CPU); BackGroundStrucuture[] BackgroundXYZ_GPU = gpu.CopyToDevice(BackgroundXYZ_CPU); //out put TestingStructure[] distance_GPU = gpu.Allocate(distance_CPU); // generate a bitmap from our sphere data //Image size: 1024 x 768 dim3 grids = new dim3(1, 1); dim3 threads = new dim3(1, 1); //dim3 grids = new dim3(1024 / 16, 768 / 16); //dim3 threads = new dim3(16, 16); gpu.Launch(grids, threads, ((Action <GThread, ProfileStrucuture[, , ], ForeGroundStrucuture[], BackGroundStrucuture[], TestingStructure[]>)Bruteforce), profile_GPU, foregorungRGB_GPU, BackgroundXYZ_GPU, distance_GPU); //gpu.Launch(grids, threads, ((Action<GThread, ForeGroundStrucuture[], BackGroundStrucuture[], double[]>)Bruteforce), foregorungRGB_GPU, BackgroundXYZ_GPU, distance_GPU); // copy our bitmap back from the GPU for display gpu.CopyFromDevice(distance_GPU, distance_CPU); // get stop time, and display the timing results double elapsedTime = gpu.StopTimer(); distance_CPU[0].execution_time = elapsedTime; Console.WriteLine("Time to generate: {0} ms", elapsedTime); gpu.Free(foregorungRGB_GPU); gpu.Free(BackgroundXYZ_GPU); gpu.Free(distance_GPU); gpu.FreeAll(); return(distance_CPU); }
public static void Bruteforce(GThread thread, ProfileStrucuture[, ,] profile_GPU, ForeGroundStrucuture[] foregorungRGB_GPU, BackGroundStrucuture[] BackgroundXYZ_GPU, TestingStructure[] ptr) { // map from threadIdx/BlockIdx to pixel position int x = thread.threadIdx.x + thread.blockIdx.x * thread.blockDim.x; int y = thread.threadIdx.y + thread.blockIdx.y * thread.blockDim.y; int offset = x + y * thread.blockDim.x * thread.gridDim.x; double ox = (x - 1.0 / 2.0); double oy = (y - 1.0 / 2.0); double closestColor = double.MaxValue; double diffL = 0.0; double diffA = 0.0; double diffB = 0.0; int BestL = 0; int BestA = 0; int BestB = 0; ProfileStrucuture returnBin = new ProfileStrucuture(); ProfileStrucuture foregroundLAB = ToLAB(foregorungRGB_GPU[offset]); int binL = ((int)Math.Round(foregroundLAB.L / 5.0)) * 5; int binA = ((int)Math.Round(foregroundLAB.A / 5.0)) * 5; int binB = ((int)Math.Round(foregroundLAB.B / 5.0)) * 5; if (binL > 100) { binL = 100; } if (binA < -86.17385493791946) { binA = -85; } if (binA > 98.2448002875424) { binA = 100; } if (binB < -107.8619171648283) { binB = -110; } if (binB > 94.47705120353054) { binB = 95; } binL = (int)(binL * 0.2) + 0; binA = (int)(binA * 0.2) + 20; binB = (int)(binB * 0.2) + 22; returnBin.ML = profile_GPU[binL, binA, binB].ML; returnBin.MA = profile_GPU[binL, binA, binB].MA; returnBin.MB = profile_GPU[binL, binA, binB].MB; double closestBinDistance; for (int indexL = 0; indexL < 21; indexL++) { for (int indexA = 0; indexA < 41; indexA++) { for (int indexB = 0; indexB < 45; indexB++) { ProfileStrucuture actualBin = profile_GPU[indexL, indexA, indexB]; if (actualBin.isempty == TRUE) { continue; } BackGroundStrucuture PredictionXYZ = addXYZ_st(actualBin.MX, actualBin.MY, actualBin.MZ, BackgroundXYZ_GPU[offset]); ProfileStrucuture PredictionlAB = XYZtoLAB_st(PredictionXYZ); diffL = PredictionlAB.L - returnBin.ML; diffA = PredictionlAB.A - returnBin.MA; diffB = PredictionlAB.B - returnBin.MB; //diffL = PredictionXYZ.X - returnBin.MX; //diffA = PredictionXYZ.Y - returnBin.MY; //diffB = PredictionXYZ.Z - returnBin.MZ; diffL = diffL * diffL; diffA = diffA * diffA; diffB = diffB * diffB; closestBinDistance = Math.Sqrt(diffL + diffA + diffB); if (closestBinDistance >= closestColor) { continue; } else { closestColor = closestBinDistance; BestL = indexL; BestA = indexA; BestB = indexB; } } } } ProfileStrucuture return_bin = profile_GPU[BestL, BestA, BestB]; TestingStructure ValueToReturn = new TestingStructure(); ValueToReturn.Given_R = return_bin.L; ValueToReturn.Given_G = return_bin.A; ValueToReturn.Given_B = return_bin.B; ValueToReturn.distance = closestColor; ptr[offset] = ValueToReturn; }
public static void QuickCorr(GThread thread, ProfileStrucuture[, ,] profile_GPU, ForeGroundStrucuture[] foregorungRGB_GPU, BackGroundStrucuture[] BackgroundXYZ_GPU, TestingStructure[] ptr, SampleStructure[,] samples) { // map from threadIdx/BlockIdx to pixel position int x = thread.threadIdx.x + thread.blockIdx.x * thread.blockDim.x; int y = thread.threadIdx.y + thread.blockIdx.y * thread.blockDim.y; int offset = x + y * thread.blockDim.x * thread.gridDim.x; double ox = (x - 1.0 / 2.0); double oy = (y - 1.0 / 2.0); // double closestColor = double.MaxValue; double diffL = 0.0; double diffA = 0.0; double diffB = 0.0; //int BestL = 0; //int BestA = 0; //int BestB = 0; //1 - Converts the foreground to how the display shows it ProfileStrucuture foregroundColorToShow = new ProfileStrucuture(); ProfileStrucuture foregroundLAB = ToLAB(foregorungRGB_GPU[offset]); int binL = ((int)Math.Round(foregroundLAB.L / 5.0)) * 5; int binA = ((int)Math.Round(foregroundLAB.A / 5.0)) * 5; int binB = ((int)Math.Round(foregroundLAB.B / 5.0)) * 5; if (binL > 100) { binL = 100; } if (binA < -86.17385493791946) { binA = -85; } if (binA > 98.2448002875424) { binA = 100; } if (binB < -107.8619171648283) { binB = -110; } if (binB > 94.47705120353054) { binB = 95; } binL = (int)(binL * 0.2) + 0; binA = (int)(binA * 0.2) + 20; binB = (int)(binB * 0.2) + 22; foregroundColorToShow.ML = profile_GPU[binL, binA, binB].ML; foregroundColorToShow.MA = profile_GPU[binL, binA, binB].MA; foregroundColorToShow.MB = profile_GPU[binL, binA, binB].MB; //1.1 - Extra step for Quick Correction Point3D origin = new Point3D(10.0, 20.0, 22.0); Point3D step = new Point3D(10, 20, 22); //2 - Get the accuracy ProfileStrucuture actualBin = GetProfileBin(origin.X, origin.Y, origin.Z, profile_GPU); if (actualBin.isempty == TRUE) { return; } BackGroundStrucuture PredictionXYZ = addXYZ_st(actualBin.MX, actualBin.MY, actualBin.MZ, BackgroundXYZ_GPU[offset]); ProfileStrucuture PredictionLAB = XYZtoLAB_st(PredictionXYZ); //diffL = foregroundColorToShow.ML - PredictionLAB.L; //diffA = foregroundColorToShow.MA - PredictionLAB.A; //diffB = foregroundColorToShow.MB - PredictionLAB.B; diffL = PredictionLAB.L - foregroundColorToShow.ML; diffA = PredictionLAB.A - foregroundColorToShow.MA; diffB = PredictionLAB.B - foregroundColorToShow.MB; //diffL = PredictionXYZ.X - foregroundColorToShow.MX; //diffA = PredictionXYZ.Y - foregroundColorToShow.MY; //diffB = PredictionXYZ.Z - foregroundColorToShow.MZ; diffL = diffL * diffL; diffA = diffA * diffA; diffB = diffB * diffB; //originBin.distanceLAB actualBin.distance = Math.Sqrt(diffL + diffA + diffB); //declaring 6 separate samples - CUDA does not support array declaration in kernel device code Point3D top = new Point3D(); Point3D bottom = new Point3D(); Point3D left = new Point3D(); Point3D right = new Point3D(); Point3D forward = new Point3D(); Point3D backward = new Point3D(); while (step.X > 0 || step.Y > 0 && step.Z > 0) { //sample 6 bins top.X = origin.X + step.X; top.Y = origin.Y; top.Z = origin.Z; bottom.X = origin.X - step.X; bottom.Y = origin.Y; bottom.Z = origin.Z; left.X = origin.X; left.Y = origin.Y - step.Y; left.Z = origin.Z; right.X = origin.X; right.Y = origin.Y + step.Y; right.Z = origin.Z; forward.X = origin.X; forward.Y = origin.Y; forward.Z = origin.Z - step.Z; backward.X = origin.X; backward.Y = origin.Y; backward.Z = origin.Z + step.Z; samples[offset, 0] = GetProfileBinForSample(top.X, top.Y, top.Z, profile_GPU); samples[offset, 1] = GetProfileBinForSample(bottom.X, bottom.Y, bottom.Z, profile_GPU); samples[offset, 2] = GetProfileBinForSample(left.X, left.Y, left.Z, profile_GPU); samples[offset, 3] = GetProfileBinForSample(right.X, right.Y, right.Z, profile_GPU); samples[offset, 4] = GetProfileBinForSample(forward.X, forward.Y, forward.Z, profile_GPU); samples[offset, 5] = GetProfileBinForSample(backward.X, backward.Y, backward.Z, profile_GPU); int countSamplesClosestThanOrigin = 0; //calculate color correction for all samples #region for (int index = 0; index < 6; index++) { if (samples[offset, index].isempty == TRUE || samples[offset, index].isempty == 0.0) { continue; } BackGroundStrucuture temp_XYZ = addXYZ_st(samples[offset, index].MX, samples[offset, index].MY, samples[offset, index].MZ, BackgroundXYZ_GPU[offset]); ProfileStrucuture PredictionlAB = XYZtoLAB_st(temp_XYZ); diffL = PredictionlAB.L - foregroundColorToShow.ML; diffA = PredictionlAB.A - foregroundColorToShow.MA; diffB = PredictionlAB.B - foregroundColorToShow.MB; diffL = diffL * diffL; diffA = diffA * diffA; diffB = diffB * diffB; //curr_distanceLAB samples[offset, index].distance = Math.Sqrt(diffL + diffA + diffB); if (samples[offset, index].distance >= actualBin.distance) { continue; } else { samples[offset, index].isMoreAccurateThanOrigin = (int)TRUE; countSamplesClosestThanOrigin++; } } #endregion if (countSamplesClosestThanOrigin == 0) { step = DecreaseTheStep(step); continue; } //if there is at least one sample more accurate, it moves the origin in that direction, maintains the step and checks again else { //6.1 calculates weights double totalimprovements = 0; for (int index = 0; index < 6; index++) { if (!(samples[offset, index].isMoreAccurateThanOrigin == TRUE)) { continue; } totalimprovements += (actualBin.distance - samples[offset, index].distance); } for (int index = 0; index < 6; index++) { if (!(samples[offset, index].isMoreAccurateThanOrigin == 1)) { continue; } samples[offset, index].weight = ((actualBin.distance - samples[offset, index].distance) / totalimprovements); } //6.2 calculates displacement Point3D displacement = new Point3D(0, 0, 0); for (int index = 0; index < 6; index++) { if (!(samples[offset, index].isMoreAccurateThanOrigin == 1)) { continue; } displacement.X = displacement.X + (samples[offset, index].L - origin.X) * samples[offset, index].weight; displacement.Y = displacement.Y + (samples[offset, index].A - origin.Y) * samples[offset, index].weight; displacement.Z = displacement.Z + (samples[offset, index].B - origin.Z) * samples[offset, index].weight; } if (displacement.X > 0) { displacement.X = Math.Ceiling(displacement.X); } else { displacement.X = Math.Floor(displacement.X); } if (displacement.Y > 0) { displacement.Y = Math.Ceiling(displacement.Y); } else { displacement.Y = Math.Floor(displacement.Y); } if (displacement.Z > 0) { displacement.Z = Math.Ceiling(displacement.Z); } else { displacement.Z = Math.Floor(displacement.Z); } //6.3 pokes new origin Point3D newOriginLoc = new Point3D(); newOriginLoc.X = origin.X + displacement.X; newOriginLoc.Y = origin.Y + displacement.Y; newOriginLoc.Z = origin.Z + displacement.Z; ProfileStrucuture newOriginBin = GetProfileBin(newOriginLoc.X, newOriginLoc.Y, newOriginLoc.Z, profile_GPU); while (newOriginBin.isempty == TRUE) { /////////////////////// round to even missing /////////////////// //6.4 moves half the magnitude in the given direction displacement.X = Math.Round(displacement.X / 2); displacement.Y = Math.Round(displacement.Y / 2); displacement.Z = Math.Round(displacement.Z / 2); newOriginLoc.X = origin.X + displacement.X; newOriginLoc.Y = origin.Y + displacement.Y; newOriginLoc.Z = origin.Z + displacement.Z; newOriginBin = GetProfileBin(newOriginLoc.X, newOriginLoc.Y, newOriginLoc.Z, profile_GPU); } //calclates the accuracy of the posible new origin if (newOriginBin.isempty == TRUE) { return; } PredictionXYZ = addXYZ_st(newOriginBin.MX, newOriginBin.MY, newOriginBin.MZ, BackgroundXYZ_GPU[offset]); ProfileStrucuture PredictionlAB = XYZtoLAB_st(PredictionXYZ); diffL = PredictionlAB.L - foregroundColorToShow.ML; diffA = PredictionlAB.A - foregroundColorToShow.MA; diffB = PredictionlAB.B - foregroundColorToShow.MB; //diffL = PredictionXYZ.X - foregroundColorToShow.MX; //diffA = PredictionXYZ.Y - foregroundColorToShow.MY; //diffB = PredictionXYZ.Z - foregroundColorToShow.MZ; diffL = diffL * diffL; diffA = diffA * diffA; diffB = diffB * diffB; //originBin.distanceLAB newOriginBin.distance = Math.Sqrt(diffL + diffA + diffB); if ((origin.X == newOriginLoc.X && origin.Y == newOriginLoc.Y && origin.Z == newOriginLoc.Z) || actualBin.distance <= newOriginBin.distance) // it's the same location then just reduces the step { step = DecreaseTheStep(step); } else { origin = newOriginLoc; actualBin = newOriginBin; } } } TestingStructure ValueToReturn = new TestingStructure(); ValueToReturn.Given_R = actualBin.L; ValueToReturn.Given_G = actualBin.A; ValueToReturn.Given_B = actualBin.B; ValueToReturn.distance = actualBin.distance; ptr[offset] = ValueToReturn; }
public static void Bruteforce(GThread thread, ProfileStrucuture[, ,] profile_GPU, ForeGroundStrucuture[] foregorungRGB_GPU, BackGroundStrucuture[] BackgroundXYZ_GPU, TestingStructure[] ptr) { // map from threadIdx/BlockIdx to pixel position int x = thread.threadIdx.x + thread.blockIdx.x * thread.blockDim.x; int y = thread.threadIdx.y + thread.blockIdx.y * thread.blockDim.y; int offset = x + y * thread.blockDim.x * thread.gridDim.x; double ox = (x - 1.0 / 2.0); double oy = (y - 1.0 / 2.0); double closestColor = double.MaxValue; double diffL = 0.0; double diffA = 0.0; double diffB = 0.0; int BestL = 0; int BestA = 0; int BestB = 0; ProfileStrucuture returnBin = new ProfileStrucuture(); ProfileStrucuture foregroundLAB = ToLAB(foregorungRGB_GPU[offset]); int binL = ((int)Math.Round(foregroundLAB.L / 5.0)) * 5; int binA = ((int)Math.Round(foregroundLAB.A / 5.0)) * 5; int binB = ((int)Math.Round(foregroundLAB.B / 5.0)) * 5; if (binL > 100) binL = 100; if (binA < -86.17385493791946) binA = -85; if (binA > 98.2448002875424) binA = 100; if (binB < -107.8619171648283) binB = -110; if (binB > 94.47705120353054) binB = 95; binL = (int)(binL * 0.2) + 0; binA = (int)(binA * 0.2) + 20; binB = (int)(binB * 0.2) + 22; returnBin.ML = profile_GPU[binL, binA, binB].ML; returnBin.MA = profile_GPU[binL, binA, binB].MA; returnBin.MB = profile_GPU[binL, binA, binB].MB; double closestBinDistance; for (int indexL = 0; indexL < 21; indexL++) { for (int indexA = 0; indexA < 41; indexA++) { for (int indexB = 0; indexB < 45; indexB++) { ProfileStrucuture actualBin = profile_GPU[indexL, indexA, indexB]; if (actualBin.isempty == TRUE) continue; BackGroundStrucuture PredictionXYZ = addXYZ_st(actualBin.MX, actualBin.MY, actualBin.MZ, BackgroundXYZ_GPU[offset]); ProfileStrucuture PredictionlAB = XYZtoLAB_st(PredictionXYZ); diffL = PredictionlAB.L - returnBin.ML; diffA = PredictionlAB.A - returnBin.MA; diffB = PredictionlAB.B - returnBin.MB; //diffL = PredictionXYZ.X - returnBin.MX; //diffA = PredictionXYZ.Y - returnBin.MY; //diffB = PredictionXYZ.Z - returnBin.MZ; diffL = diffL * diffL; diffA = diffA * diffA; diffB = diffB * diffB; closestBinDistance = Math.Sqrt(diffL + diffA + diffB); if (closestBinDistance >= closestColor) continue; else { closestColor = closestBinDistance; BestL = indexL; BestA = indexA; BestB = indexB; } } } } ProfileStrucuture return_bin = profile_GPU[BestL, BestA, BestB]; TestingStructure ValueToReturn = new TestingStructure(); ValueToReturn.Given_R = return_bin.L; ValueToReturn.Given_G = return_bin.A; ValueToReturn.Given_B = return_bin.B; ValueToReturn.distance = closestColor; ptr[offset] = ValueToReturn; }