public List <List <TrainingSampleCharacter> > TrainOnImage(string imagePath, List <char[]> referenceLines, int xOffset = 4) { var cleaner = new ImageCleaner(); //cleaner.SaveChatColors(imagePath, "debug.png"); var results = new List <List <TrainingSampleCharacter> >(); using (Image <Rgba32> rgbImage = Image.Load(imagePath)) { var cache = new ImageCache(rgbImage); var chatRect = new Rectangle(4, 763, 3236, 1350); var offsets = OCRHelpers.LineOffsets; var lineHeight = 36; var refLineIndex = 0; for (int i = 0; i < offsets.Length; i++) { var line = TrainOnLine(referenceLines[refLineIndex], xOffset, chatRect, cache, lineHeight, offsets[i]); if (line.Count > 0 && line.Count == referenceLines[i].Length) { results.Add(line); refLineIndex++; } else if (line.Count == referenceLines[i].Length) { throw new Exception("Reference lines do not match up with found characters"); } } } return(results); }
public void TrainOnImages(string trainingDir, string outputDir, int xOffset = 253) { var trainingImagePaths = Directory.GetFiles(trainingDir).Where(f => f.EndsWith(".png")).ToArray(); var trainingTextPaths = Directory.GetFiles(trainingDir).Where(f => f.EndsWith(".txt")).ToArray(); var characters = new List <TrainingSampleCharacter>(); Console.WriteLine("Looking at training images"); for (int i = 0; i < trainingImagePaths.Length; i++) { Console.Write("\r" + trainingImagePaths[i]); var correctText = File.ReadAllLines(trainingTextPaths[i]).Select(line => line.Replace(" ", "").ToArray()).ToList(); var results = TrainOnImage(trainingImagePaths[i], correctText, xOffset); results.SelectMany(list => list).ToList().ForEach(t => characters.Add(t)); } var groupedChars = characters.GroupBy(t => t.Character); //Get max widths Console.WriteLine("\nFinding max widths"); var maxWidths = new Dictionary <char, int>(); groupedChars.ToList().ForEach(g => maxWidths[g.Key] = g.Max(t => t.Width)); //Turn all pixel lists into arrays of max width Console.WriteLine("Converting lists to padded arrays"); var groupedCharArrays = groupedChars.Select(g => { Console.Write("\rLooking at: " + g.Key); return(g.Select(t => { var arr = new float[maxWidths[t.Character], 36]; for (int x = 0; x < maxWidths[t.Character] && x < t.Width; x++) { for (int y = 0; y < 36; y++) { arr[x, y] = t.Mask[x, y]; } } return new { t.Character, Mask = arr }; })); }).Select(i => i).SelectMany(i => i).GroupBy(t => t.Character).ToList(); //Get pixel counts Console.WriteLine("\nDeterming pixel counts"); var pixelCounts = groupedCharArrays.Select(g => { Console.Write("\rLooking at: " + g.Key); var arr = new float[maxWidths[g.Key], 36]; g.ToList().ForEach(t => { for (int x = 0; x < maxWidths[g.Key]; x++) { for (int y = 0; y < 36; y++) { arr[x, y] += t.Mask[x, y]; } } }); return(new { Character = g.Key, PixelCounts = arr, SampleCount = g.Count() }); }).ToList(); Console.WriteLine("\nConverting pixels into visualization"); var grayscalePixels = pixelCounts.Select(i => { var arr = new byte[i.PixelCounts.GetLength(0), i.PixelCounts.GetLength(1)]; for (int x = 0; x < arr.GetLength(0); x++) { for (int y = 0; y < arr.GetLength(1); y++) { arr[x, y] = (byte)(((float)i.PixelCounts[x, y] / (float)i.SampleCount) * byte.MaxValue); } } return(new { i.Character, Pixels = arr }); }).ToList(); var c = new ImageCleaner(); grayscalePixels.ForEach(i => c.MakeGreyscaleImageFromArray(outputDir, i.Character, i.Pixels)); }