public List <Image[]> Split(string source) { //Densities double linesDensity = 0.4; // gray % to split lines double symbDensity = 0.5; // gray % to split symbols double faultDensity = 0.4; // gray % to split close symbols double clearDensity = 0.2; // gray % to clean symbols // Maximum pixels for splitting close letters int maxfault = 2; // Minimum height of line int minlinepx = 8; // Maximum interference on line when cleaning symbols int intf = 2; // Pixels % to consider space double space = 0.5; Image img1 = Image.FromFile(source); Bitmap b1 = new Bitmap(img1); List <Bitmap> lines = new List <Bitmap>(); Image memory = Image.FromFile("..\\..\\symbols.png"); Bitmap meme = new Bitmap(memory); lines.Add(meme); // Get List of Lines int st = -1; int fin = -1; for (int i = 0; i < b1.Height; i++) { for (int j = 0; j < b1.Width; j++) { if (Resizer.inGray(b1.GetPixel(j, i).R, b1.GetPixel(j, i).G, b1.GetPixel(j, i).B) >= linesDensity) { if (st == -1) { st = i; } break; } if (j == b1.Width - 1 && st > -1 && i - minlinepx >= st) { fin = i - 1; //Console.WriteLine(st + " " + fin); Rectangle cloneRect = new Rectangle(0, st, b1.Width, fin - st + 1); System.Drawing.Imaging.PixelFormat format = b1.PixelFormat; Bitmap cloned = b1.Clone(cloneRect, format); lines.Add(cloned); st = -1; fin = -1; } else if (j == b1.Width - 1 && st > -1 && i - minlinepx < st) { st = -1; } } } // Get Symbols List <Image[]> images = new List <Image[]>(); foreach (Bitmap line in lines) { st = -1; fin = -1; List <Bitmap> im1 = new List <Bitmap>(); int spacepixels = 0; // Get symbol list for (int i = 0; i < line.Width; i++) { int fault = 0; for (int j = 0; j < line.Height; j++) { if (Resizer.inGray(line.GetPixel(i, j).R, line.GetPixel(i, j).G, line.GetPixel(i, j).B) >= symbDensity) { if (st == -1) { st = i; } break; } else if (Resizer.inGray(line.GetPixel(i, j).R, line.GetPixel(i, j).G, line.GetPixel(i, j).B) >= faultDensity) { fault++; if (fault > maxfault) { if (st == -1) { st = i; } break; } } if (j == line.Height - 1 && st > -1) { fin = i - 1; //Console.WriteLine("spc " + spacepixels + " " + (fin - st + 1) * space); if ((spacepixels > (fin - st + 1) * space) && im1.Count() > 0 && !line.Equals(lines[0])) { Image img2 = Image.FromFile("..\\..\\space.png"); Bitmap spc = new Bitmap(img2); im1.Add(spc); //Console.WriteLine("Add " + fin); } Rectangle cloneRect = new Rectangle(st, 0, fin - st + 1, line.Height); System.Drawing.Imaging.PixelFormat format = line.PixelFormat; //Console.WriteLine(st + " " + fin); Bitmap cloned = line.Clone(cloneRect, format); im1.Add(cloned); st = -1; fin = -1; spacepixels = 0; break; } //Check spaces if (j == line.Height - 1) { spacepixels++; } } } Image[] imgs = new Image[im1.Count()]; //Clear symbols for (int i = 0; i < im1.Count(); i++) { Bitmap symb = im1[i]; int sth = -1; int finh = -1; for (int k = 0; k < symb.Height; k++) { int count = 0; for (int m = 0; m < symb.Width; m++) { if (Resizer.inGray(symb.GetPixel(m, k).R, symb.GetPixel(m, k).G, symb.GetPixel(m, k).B) >= clearDensity) { count++; if (sth == -1 && count > intf) { sth = k; } if (count > intf) { finh = k; } } } } /// Very bad fix, need to change if (sth == -1) { imgs[i] = Image.FromFile("..\\..\\space.png"); } /// else { Rectangle cloneRect = new Rectangle(0, sth, symb.Width, finh - sth + 1); System.Drawing.Imaging.PixelFormat format = symb.PixelFormat; //Console.WriteLine(st + " " + fin); Bitmap cloned = symb.Clone(cloneRect, format); imgs[i] = (Image)cloned; } } images.Add(imgs); } return(images); }
public List <string[]> Run() { int size = 0; // Initialize result symbol list and similarity coefficients List <string[]> res_symb = new List <string[]>(); for (int i = 1; i < imgs.Count(); i++) { res_symb.Add(new string[imgs[i].GetLength(0)]); size += imgs[i].GetLength(0); } // Buffer data string[] buf_res = new string[size]; double[] similarity = new double[size]; var Iterate = new Action <int>(process => { List <double[][]> alls = new List <double[][]>(); double[][] mains = Resizer.ResizeImage(imgs[0][process], imgs[0][process].Width, imgs[0][process].Height); for (int i = 1; i < imgs.Count(); i++) { for (int j = 0; j < imgs[i].GetLength(0); j++) { alls.Add(Resizer.ResizeImage(imgs[i][j], mains.GetLength(0), mains[0].GetLength(0))); } } // Preparation List <double> mains1 = new List <double>(); for (int i = 0; i < mains.GetLength(0); i++) { for (int j = 0; j < mains[i].GetLength(0); j++) { mains1.Add(mains[i][j]); } } List <double> alls1 = new List <double>(); foreach (double[][] element in alls) { for (int i = 0; i < element.GetLength(0); i++) { for (int j = 0; j < element[i].GetLength(0); j++) { alls1.Add(element[i][j]); } } } int[] ress = new int[alls.Count()]; for (int i = 0; i < alls.Count(); i++) { ress[i] = 0; } var CPUCalc = new Action(() => { Parallel.For(0, alls1.Count(), i => { ////// First Neuron Layer double buf = Math.Abs(mains1[i % mains1.Count()] - alls1[i]); ////// Second Neuron Layer if (buf <= 0.7) { Interlocked.Increment(ref ress[i / mains1.Count()]); } }); }); var GPUCalc = new Action(() => { OpenCLTemplate.CLCalc.Program.Variable varV1 = new OpenCLTemplate.CLCalc.Program.Variable(alls1.ToArray()); OpenCLTemplate.CLCalc.Program.Variable varV2 = new OpenCLTemplate.CLCalc.Program.Variable(mains1.ToArray()); OpenCLTemplate.CLCalc.Program.Variable varV3 = new OpenCLTemplate.CLCalc.Program.Variable(new int[1] { mains1.Count() }); OpenCLTemplate.CLCalc.Program.Variable varV4 = new OpenCLTemplate.CLCalc.Program.Variable(ress); OpenCLTemplate.CLCalc.Program.Variable[] args = new OpenCLTemplate.CLCalc.Program.Variable[] { varV1, varV2, varV3, varV4 }; int[] workers = new int[1] { alls1.Count() }; // Cannot execute GPU from different threads at the same time //lock(GPULock) //{ VectorSum.Execute(args, workers); varV4.ReadFromDeviceTo(ress); //} }); if (process < symbols.Count() * percent) { CPUCalc(); } else { GPUCalc(); } Parallel.For(0, alls.Count(), i => { lock (WriteLock) { ////// Third Neuron Layer if ((double)ress[i] / mains1.Count() > similarity[i]) { similarity[i] = (double)ress[i] / mains1.Count(); buf_res[i] = symbols[process]; } ; } }); }); var GoCPU = new Action(() => { Parallel.For(0, (int)((double)symbols.Count() * percent), new ParallelOptions { MaxDegreeOfParallelism = cores }, Iterate); }); var GoGPU = new Action(() => { Parallel.For((int)((double)symbols.Count() * percent), symbols.Count(), new ParallelOptions { MaxDegreeOfParallelism = cores }, Iterate); }); Parallel.Invoke(() => GoCPU(), () => GoGPU()); // Final int count = 0; for (int i = 0; i < res_symb.Count(); i++) { for (int j = 0; j < res_symb[i].GetLength(0); j++) { res_symb[i][j] = buf_res[count]; count++; } } return(res_symb); }