static void Main(string[] args) { navigationMatrix = new Matrix3D(); navigationMatrix.Translate(new Vector3D(0, 100, 110)); navigationMatrix.Scale(new Vector3D((double)1 / 5, (double)1 / 5, (double)1 / 5)); displayProfile = new Bin[Bin.RANGEL, Bin.RANGEA, Bin.RANGEB]; for (int l = 0; l < Bin.RANGEL; l++) for (int a = 0; a < Bin.RANGEA; a++) for (int b = 0; b < Bin.RANGEB; b++) displayProfile[l, a, b] = new Bin(l, a, b); PopulateProfile(displayProfile, navigationMatrix); String path = Environment.CurrentDirectory + PATH_TO_VIDEO; if (!System.IO.File.Exists(path)) return; //Opens the movie file capture = new Capture(path); double fps = capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FPS); //Reads frame by frame Timer timer = new Timer(1000 / fps); timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); timer.Start(); Console.Read(); }
private static void PopulateProfile(Bin[, ,] dProfile, Matrix3D navigationMatrix) { DataTable dataFile = new DataTable(); try { // add the csv bin file using (GenericParserAdapter parser = new GenericParserAdapter(PATH_TO_BIN_PROFILE)) { System.Data.DataSet dsResult = parser.GetDataSet(); dataFile = dsResult.Tables[0]; } } catch { } for (int i = 1; i < dataFile.Rows.Count; i++) { //lab vale as got form profile index Point3D labBin = new Point3D(); labBin.X = Convert.ToDouble(dataFile.Rows[i][0].ToString()); labBin.Y = Convert.ToDouble(dataFile.Rows[i][1].ToString()); labBin.Z = Convert.ToDouble(dataFile.Rows[i][2].ToString()); //trasfered points Point3D labCoordinate = navigationMatrix.Transform(labBin); //gets the bin to fill up Bin actualBin = GetProfileBin(dProfile, labCoordinate); //bin RGB Value actualBin.binRGB.X = Convert.ToByte(dataFile.Rows[i][9].ToString()); actualBin.binRGB.Y = Convert.ToByte(dataFile.Rows[i][10].ToString()); actualBin.binRGB.Z = Convert.ToByte(dataFile.Rows[i][11].ToString()); //Measure Lab Values actualBin.measuredLAB.X = Convert.ToDouble(dataFile.Rows[i][3].ToString()); actualBin.measuredLAB.Y = Convert.ToDouble(dataFile.Rows[i][4].ToString()); actualBin.measuredLAB.Z = Convert.ToDouble(dataFile.Rows[i][5].ToString()); //measured XYZ Values actualBin.measuredXYZ.X = Convert.ToDouble(dataFile.Rows[i][6].ToString()); actualBin.measuredXYZ.Y = Convert.ToDouble(dataFile.Rows[i][7].ToString()); actualBin.measuredXYZ.Z = Convert.ToDouble(dataFile.Rows[i][8].ToString()); //is empty check actualBin.isEmpty = false; } }
private static Bin GetProfileBin(Bin[, ,] profile, Point3D coordinates, Location location = Location.Top) { if (coordinates.X < 0 || coordinates.X >= Bin.RANGEL) return outOfBounds; if (coordinates.Y < 0 || coordinates.Y >= Bin.RANGEA) return outOfBounds; if (coordinates.Z < 0 || coordinates.Z >= Bin.RANGEB) return outOfBounds; Bin returnBin = profile[(int)coordinates.X, (int)coordinates.Y, (int)coordinates.Z]; returnBin.location = location; returnBin.isMoreAccurateThanOrigin = false; return returnBin; }
private void btn_1024x768_Click(object sender, RoutedEventArgs e) { Matrix3D navigationMatrix = new Matrix3D(); navigationMatrix.Translate(new Vector3D(0, 100, 110)); navigationMatrix.Scale(new Vector3D((double)1 / 5, (double)1 / 5, (double)1 / 5)); //2- Load the profile in a three dimensional array Bin[, ,] p3700 = new Bin[RANGEL, RANGEA, RANGEB]; for (int l = 0; l < RANGEL; l++) { for (int a = 0; a < RANGEA; a++) { for (int b = 0; b < RANGEB; b++) { p3700[l, a, b] = new Bin(l, a, b); } } } try { // add the csv bin file using (GenericParserAdapter parser = new GenericParserAdapter(@"C:\Users\jhincapie\Desktop\Projects\STColorCorrection\Data\PROFILE\p3700.csv")) { System.Data.DataSet dsResult = parser.GetDataSet(); profile = dsResult.Tables[0]; } } catch { } for (int i = 1; i < profile.Rows.Count; i++) { //lab vale as got form profile index Point3D labBin = new Point3D(); labBin.X = Convert.ToDouble(profile.Rows[i][0].ToString()); labBin.Y = Convert.ToDouble(profile.Rows[i][1].ToString()); labBin.Z = Convert.ToDouble(profile.Rows[i][2].ToString()); //trasfered points Point3D labCoordinate = navigationMatrix.Transform(labBin); //gets the bin to fill up Bin actualBin = GetProfileBin(p3700, labCoordinate); //bin RGB Value actualBin.binRGB.X = Convert.ToByte(profile.Rows[i][9].ToString()); actualBin.binRGB.Y = Convert.ToByte(profile.Rows[i][10].ToString()); actualBin.binRGB.Z = Convert.ToByte(profile.Rows[i][11].ToString()); //Measure Lab Values actualBin.measuredLAB.X = Convert.ToDouble(profile.Rows[i][3].ToString()); actualBin.measuredLAB.Y = Convert.ToDouble(profile.Rows[i][4].ToString()); actualBin.measuredLAB.Z = Convert.ToDouble(profile.Rows[i][5].ToString()); //measured XYZ Values actualBin.measuredXYZ.X = Convert.ToDouble(profile.Rows[i][6].ToString()); actualBin.measuredXYZ.Y = Convert.ToDouble(profile.Rows[i][7].ToString()); actualBin.measuredXYZ.Z = Convert.ToDouble(profile.Rows[i][8].ToString()); //is empty check actualBin.isEmpty = false; } Stopwatch stop2 = new Stopwatch(); stop2.Start(); // to create a random number Random randomGenerater = new Random(); for (int i = 0; i < 1024; i++) { for (int j = 0; j < 768; j++) { Byte[] rgb = new Byte[3]; randomGenerater.NextBytes(rgb); System.Drawing.Color foreground = System.Drawing.Color.FromArgb(rgb[0], rgb[1], rgb[2]); PerceptionLib.CIEXYZ backgroundCIEXYZ = new CIEXYZ(0, 0, 0); backgroundCIEXYZ.X = randomGenerater.NextDouble() * 0.9504; backgroundCIEXYZ.Y = randomGenerater.NextDouble() * 1.0000; backgroundCIEXYZ.Z = randomGenerater.NextDouble() * 1.0888; Point3D background = new Point3D(backgroundCIEXYZ.X, backgroundCIEXYZ.Y, backgroundCIEXYZ.Z); Bin foregroundBin = FindForegroundBin(p3700, navigationMatrix, foreground); PerceptionLib.Color fg = new PerceptionLib.Color(); //fg measured LAB value fg.LA = foregroundBin.measuredLAB.X; fg.A = foregroundBin.measuredLAB.Y; fg.B = foregroundBin.measuredLAB.Z; Bin corretedColorQCHS = QuickCorrection(p3700, navigationMatrix, foreground, background, HalfTheStep); } } stop2.Stop(); Console.WriteLine(stop2.ElapsedMilliseconds); }
private Bin SnakeCorrection(Bin[, ,] profile, Matrix3D navigationMatrix, System.Drawing.Color foreground, Point3D background) { //1- Converts the foreground to how the display shows it Bin foregroundBin = FindForegroundBin(profile, navigationMatrix, foreground); //2- general parameters Point3D origin = navigationMatrix.Transform(new Point3D(50, 0, 0)); //3- finds the correction accuracy of the current bin Bin originBin = GetProfileBin(profile, origin); CalculateCorrectionAccuracy(originBin, background, foregroundBin); //4- initializes the cycles counter int cycles = 0; //5- Creates the reusable variables - this is aimed at reducing time needed for memory allocation Bin[] samples = new Bin[6]; Point3D top = new Point3D(); Point3D bottom = new Point3D(); Point3D left = new Point3D(); Point3D right = new Point3D(); Point3D forward = new Point3D(); Point3D backward = new Point3D(); // final condition - when none is closest then it finishes int countSamplesClosestThanOrigin = 0; do { cycles++; //4- finds the correction accuracy of the 6 samplers and whether they are better than the origin top.X = origin.X + 1; top.Y = origin.Y; top.Z = origin.Z; bottom.X = origin.X - 1; bottom.Y = origin.Y; bottom.Z = origin.Z; left.X = origin.X; left.Y = origin.Y - 1; left.Z = origin.Z; right.X = origin.X; right.Y = origin.Y + 1; right.Z = origin.Z; forward.X = origin.X; forward.Y = origin.Y; forward.Z = origin.Z - 1; backward.X = origin.X; backward.Y = origin.Y; backward.Z = origin.Z + 1; samples[0] = GetProfileBin(profile, top, Location.Top); samples[1] = GetProfileBin(profile, bottom, Location.Bottom); samples[2] = GetProfileBin(profile, left, Location.Left); samples[3] = GetProfileBin(profile, right, Location.Right); samples[4] = GetProfileBin(profile, forward, Location.Forward); samples[5] = GetProfileBin(profile, backward, Location.Backward); countSamplesClosestThanOrigin = 0; for (int index = 0; index < samples.Length; index++) { CalculateCorrectionAccuracy(samples[index], background, foregroundBin); if (samples[index].distanceLAB >= originBin.distanceLAB) { continue; } samples[index].isMoreAccurateThanOrigin = true; countSamplesClosestThanOrigin++; } //5- if the origin is the most accurate, it halves the step and checks again if (countSamplesClosestThanOrigin > 0) { //6.1 calculates weights double totalimprovements = 0; for (int index = 0; index < samples.Length; index++) { if (!samples[index].isMoreAccurateThanOrigin) { continue; } totalimprovements += (originBin.distanceLAB - samples[index].distanceLAB); } for (int index = 0; index < samples.Length; index++) { if (!samples[index].isMoreAccurateThanOrigin) { continue; } samples[index].weight = (originBin.distanceLAB - samples[index].distanceLAB) / totalimprovements; } //6.2 calculates displacement Vector3D displacement = new Vector3D(0, 0, 0); for (int index = 0; index < samples.Length; index++) { if (!samples[index].isMoreAccurateThanOrigin) { continue; } displacement = displacement + (samples[index].binLAB - origin) * samples[index].weight; } displacement.X = displacement.X > 0 ? Math.Ceiling(displacement.X) : Math.Floor(displacement.X); displacement.Y = displacement.Y > 0 ? Math.Ceiling(displacement.Y) : Math.Floor(displacement.Y); displacement.Z = displacement.Z > 0 ? Math.Ceiling(displacement.Z) : Math.Floor(displacement.Z); //6.3 pokes new origin Point3D newOriginLoc = origin + displacement; Bin newOriginBin = GetProfileBin(profile, newOriginLoc); while (newOriginBin.isEmpty) { //6.4 moves half the magnitude in the given direction displacement.X = Math.Round(displacement.X / 2, MidpointRounding.ToEven); displacement.Y = Math.Round(displacement.Y / 2, MidpointRounding.ToEven); displacement.Z = Math.Round(displacement.Z / 2, MidpointRounding.ToEven); newOriginLoc = origin + displacement; newOriginBin = GetProfileBin(profile, newOriginLoc); } //calculates the accuracy of the possible new solution CalculateCorrectionAccuracy(newOriginBin, background, foregroundBin); if (origin == newOriginLoc) // it's the same location then just reduces the step { countSamplesClosestThanOrigin = 0; } else if (originBin.distanceLAB <= newOriginBin.distanceLAB) // the current location is still better, then just reduces the step { countSamplesClosestThanOrigin = 0; } else // the new location is better thus is moves there { origin = newOriginLoc; originBin = newOriginBin; } } } while (countSamplesClosestThanOrigin > 0); originBin.cycles = cycles; return(originBin); }
private void btn_Start_Click(object sender, RoutedEventArgs e) { Matrix3D navigationMatrix = new Matrix3D(); navigationMatrix.Translate(new Vector3D(0, 100, 110)); navigationMatrix.Scale(new Vector3D((double)1 / 5, (double)1 / 5, (double)1 / 5)); //2- Load the profile in a three dimensional array Bin[, ,] p3700 = new Bin[RANGEL, RANGEA, RANGEB]; for (int l = 0; l < RANGEL; l++) { for (int a = 0; a < RANGEA; a++) { for (int b = 0; b < RANGEB; b++) { p3700[l, a, b] = new Bin(l, a, b); } } } try { // add the csv bin file using (GenericParserAdapter parser = new GenericParserAdapter(Environment.CurrentDirectory + @"\..\..\..\..\..\Data\PROFILE\IdealProfile.csv")) { System.Data.DataSet dsResult = parser.GetDataSet(); profile = dsResult.Tables[0]; } } catch { } for (int i = 1; i < profile.Rows.Count; i++) { //lab vale as got form profile index Point3D labBin = new Point3D(); labBin.X = Convert.ToDouble(profile.Rows[i][0].ToString()); labBin.Y = Convert.ToDouble(profile.Rows[i][1].ToString()); labBin.Z = Convert.ToDouble(profile.Rows[i][2].ToString()); //trasfered points Point3D labCoordinate = navigationMatrix.Transform(labBin); //gets the bin to fill up Bin actualBin = GetProfileBin(p3700, labCoordinate); //bin RGB Value actualBin.binRGB.X = Convert.ToByte(profile.Rows[i][9].ToString()); actualBin.binRGB.Y = Convert.ToByte(profile.Rows[i][10].ToString()); actualBin.binRGB.Z = Convert.ToByte(profile.Rows[i][11].ToString()); //Measure Lab Values actualBin.measuredLAB.X = Convert.ToDouble(profile.Rows[i][3].ToString()); actualBin.measuredLAB.Y = Convert.ToDouble(profile.Rows[i][4].ToString()); actualBin.measuredLAB.Z = Convert.ToDouble(profile.Rows[i][5].ToString()); //measured XYZ Values actualBin.measuredXYZ.X = Convert.ToDouble(profile.Rows[i][6].ToString()); actualBin.measuredXYZ.Y = Convert.ToDouble(profile.Rows[i][7].ToString()); actualBin.measuredXYZ.Z = Convert.ToDouble(profile.Rows[i][8].ToString()); //is empty check actualBin.isEmpty = false; } //3- Get the parameters: foreground and background //System.Drawing.Color foreground = System.Drawing.Color.FromArgb(150, 150, 150); //PerceptionLib.CIEXYZ background = new CIEXYZ(0.2146, 0.43125, 0.07595); //RGB: 0 199 0 - greenish ///////////////// //code for comarison //populate template in datagrid PopulateGrid(Environment.CurrentDirectory + @"\..\..\..\..\..\Data\PROFILE\Comparison_Template.txt"); DataTable template = new DataTable(); Dispatcher.Invoke(DispatcherPriority.Render, new Action(() => { dtgrid_corrDisplay.Items.Refresh(); template = ((DataView)dtgrid_corrDisplay.ItemsSource).ToTable(); })); // to create a random number Random randomGenerater = new Random(); for (int i = 0; i < 1000; i++) { Byte[] rgb = new Byte[3]; randomGenerater.NextBytes(rgb); System.Drawing.Color foreground = System.Drawing.Color.FromArgb(rgb[0], rgb[1], rgb[2]); PerceptionLib.CIEXYZ backgroundCIEXYZ = new CIEXYZ(0, 0, 0); backgroundCIEXYZ.X = randomGenerater.NextDouble() * 0.9504; backgroundCIEXYZ.Y = randomGenerater.NextDouble() * 1.0000; backgroundCIEXYZ.Z = randomGenerater.NextDouble() * 1.0888; Point3D background = new Point3D(backgroundCIEXYZ.X, backgroundCIEXYZ.Y, backgroundCIEXYZ.Z); try { Bin foregroundBin = FindForegroundBin(p3700, navigationMatrix, foreground); PerceptionLib.Color foregroundLAB = new PerceptionLib.Color(); //fg measured LAB value foregroundLAB.LA = foregroundBin.measuredLAB.X; foregroundLAB.A = foregroundBin.measuredLAB.Y; foregroundLAB.B = foregroundBin.measuredLAB.Z; Stopwatch stop1 = new Stopwatch(); stop1.Start(); Bin corretedColorBF = null; corretedColorBF = BruteForceCorrection(p3700, navigationMatrix, foreground, background); stop1.Stop(); Stopwatch stop2 = new Stopwatch(); stop2.Start(); Bin corretedColorQCHS = QuickCorrection(p3700, navigationMatrix, foreground, background, HalfTheStep); stop2.Stop(); Stopwatch stop3 = new Stopwatch(); stop3.Start(); Bin corretedColorQCD = QuickCorrection(p3700, navigationMatrix, foreground, background, DecreaseTheStep); stop3.Stop(); Stopwatch stop4 = new Stopwatch(); stop4.Start(); Bin corretedColorSC = SnakeCorrection(p3700, navigationMatrix, foreground, background); stop4.Stop(); DataRow newRow = template.NewRow(); newRow["FgR"] = foreground.R.ToString(); newRow["FgG"] = foreground.G.ToString(); newRow["FgB"] = foreground.B.ToString(); newRow["BgX"] = background.X.ToString(); newRow["BgY"] = background.Y.ToString(); newRow["BgZ"] = background.Z.ToString(); newRow["FgL"] = foregroundLAB.LA.ToString(); newRow["FgA"] = foregroundLAB.A.ToString(); newRow["Fg_B"] = foregroundLAB.B.ToString(); newRow["BFL"] = corretedColorBF.binLAB.X.ToString(); newRow["BFA"] = corretedColorBF.binLAB.Y.ToString(); newRow["BFB"] = corretedColorBF.binLAB.Z.ToString(); newRow["BFDis"] = corretedColorBF.distanceLAB.ToString(); newRow["BFTime"] = stop1.ElapsedTicks.ToString(); newRow["QCHSL"] = corretedColorQCHS.binLAB.X.ToString(); newRow["QCHSA"] = corretedColorQCHS.binLAB.Y.ToString(); newRow["QCHSB"] = corretedColorQCHS.binLAB.Z.ToString(); newRow["QCHSCycles"] = corretedColorQCHS.cycles; newRow["QCHSDis"] = corretedColorQCHS.distanceLAB.ToString(); newRow["QCHSOffSet"] = Math.Abs(corretedColorBF.distanceLAB - corretedColorQCHS.distanceLAB); newRow["QCHSTime"] = stop2.ElapsedTicks.ToString(); newRow["QCHSRatio"] = (stop1.ElapsedTicks / stop2.ElapsedTicks).ToString(); newRow["QCDL"] = corretedColorQCD.binLAB.X.ToString(); newRow["QCDA"] = corretedColorQCD.binLAB.Y.ToString(); newRow["QCDB"] = corretedColorQCD.binLAB.Z.ToString(); newRow["QCDCycles"] = corretedColorQCD.cycles; newRow["QCDDis"] = corretedColorQCD.distanceLAB.ToString(); newRow["QCDOffSet"] = Math.Abs(corretedColorBF.distanceLAB - corretedColorQCD.distanceLAB); newRow["QCDTime"] = stop3.ElapsedTicks.ToString(); newRow["QCDRatio"] = (stop1.ElapsedTicks / stop3.ElapsedTicks).ToString(); newRow["SCL"] = corretedColorSC.binLAB.X.ToString(); newRow["SCA"] = corretedColorSC.binLAB.Y.ToString(); newRow["SCB"] = corretedColorSC.binLAB.Z.ToString(); newRow["SCCycles"] = corretedColorSC.cycles; newRow["SCDis"] = corretedColorSC.distanceLAB.ToString(); newRow["SCOffSet"] = Math.Abs(corretedColorBF.distanceLAB - corretedColorSC.distanceLAB); newRow["SCTime"] = stop4.ElapsedTicks.ToString(); newRow["SCRatio"] = (stop1.ElapsedTicks / stop4.ElapsedTicks).ToString(); template.Rows.Add(newRow); } catch { Console.WriteLine(""); } } Dispatcher.Invoke(new Action(() => { dtgrid_corrDisplay.ItemsSource = template.DefaultView; dtgrid_corrDisplay.Items.Refresh(); })); }