diff --git a/OCR_Decode/DriverNameWindow.cs b/OCR_Decode/DriverNameWindow.cs index 58d12f9..b4d0bf1 100644 --- a/OCR_Decode/DriverNameWindow.cs +++ b/OCR_Decode/DriverNameWindow.cs @@ -18,108 +18,25 @@ namespace OCR_Decode public override object DecodePng(List DriverList) { string result = ""; - int[] recommendedTresholds = new int[] { 100, 125, 150, 175, 200 }; + result = GetStringFromPng(); - int index = 0; - while (!IsADriver(DriverList, result)) + if (!IsADriver(DriverList, result)) { - if(index >= recommendedTresholds.Length -1) - { - //150 is usually the safest bet - result = GetStringFromPng(150); - //I put everything in uppercase to try to lower the chances of bad answers - result = FindClosestMatch(DriverList.ConvertAll(d => d.ToUpper()), result.ToUpper()); - break; - } - result = GetStringFromPng(recommendedTresholds[index]); - index++; - } - //rawData.Save(Reader.DEBUG_DUMP_FOLDER + result + "_Before" + ".png"); - return result; - } - private string GetStringFromPng(int BlackAndWhiteTresholh) - { - string result = ""; - - Bitmap rawData = WindowImage; - rawData = Window.ConvertToBlackAndWhite(rawData, 150); - - TesseractEngine engine = new TesseractEngine(TESS_DATA_FOLDER.FullName, "eng", EngineMode.Default); - var tessImage = Pix.LoadFromMemory(ImageToByte(WindowImage)); - - Page page = engine.Process(tessImage); - Graphics g = Graphics.FromImage(rawData); - // Get the iterator for the page layout - using (var iter = page.GetIterator()) - { - // Loop over the elements of the page layout - iter.Begin(); - do - { - Rect boundingBox; - // Get the bounding box for the current element - if (iter.TryGetBoundingBox(PageIteratorLevel.Word, out boundingBox)) - { - g.DrawRectangle(Pens.Red, new Rectangle(boundingBox.X1, boundingBox.Y1, boundingBox.Width, boundingBox.Height)); - } - // Get the text for the current element - result += iter.GetText(PageIteratorLevel.Word); - } while (iter.Next(PageIteratorLevel.Word)); + //I put everything in uppercase to try to lower the chances of bad answers + result = FindClosestMatch(DriverList.ConvertAll(d => d.ToUpper()), result.ToUpper()); } return result; } - //This method has been gnerated using ChatGPT - public static string FindClosestMatch(List array, string target) + private static bool IsADriver(List drivers, string potentialDriver) { - var closestMatch = ""; - var closestDistance = int.MaxValue; - - foreach (var item in array) + bool result = false; + //I cant use drivers.Contains because it has missmatched cases and all + foreach (string name in drivers) { - var distance = LevenshteinDistance(item, target); - if (distance < closestDistance) - { - closestMatch = item; - closestDistance = distance; - } + if (name.ToUpper() == potentialDriver.ToUpper()) + result = true; } - - return closestMatch; - } - - public static int LevenshteinDistance(string s1, string s2) - { - if (string.IsNullOrEmpty(s1)) - { - return string.IsNullOrEmpty(s2) ? 0 : s2.Length; - } - - if (string.IsNullOrEmpty(s2)) - { - return string.IsNullOrEmpty(s1) ? 0 : s1.Length; - } - - var d = new int[s1.Length + 1, s2.Length + 1]; - for (var i = 0; i <= s1.Length; i++) - { - d[i, 0] = i; - } - - for (var j = 0; j <= s2.Length; j++) - { - d[0, j] = j; - } - - for (var i = 1; i <= s1.Length; i++) - { - for (var j = 1; j <= s2.Length; j++) - { - var cost = (s1[i - 1] == s2[j - 1]) ? 0 : 1; - d[i, j] = Math.Min(Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1), d[i - 1, j - 1] + cost); - } - } - - return d[s1.Length, s2.Length]; + return result; } } } diff --git a/OCR_Decode/OcrImage.cs b/OCR_Decode/OcrImage.cs index 1a9b047..a6a088a 100644 --- a/OCR_Decode/OcrImage.cs +++ b/OCR_Decode/OcrImage.cs @@ -22,12 +22,10 @@ namespace OCR_Decode { Bitmap result = (Bitmap)InputImage.Clone(); result = Grayscale(result); - result = Tresholding(result, 200); result = InvertColors(result); + result = Tresholding(result, 100); result = Resize(result); - //result = Resize(result); - //result = Dilatation(result, 5); - //result = Erode(result,3); + result = Dilatation(result, 1); return result; } public static Bitmap Grayscale(Bitmap input) diff --git a/OCR_Decode/Window.cs b/OCR_Decode/Window.cs index 5f898b7..68c7858 100644 --- a/OCR_Decode/Window.cs +++ b/OCR_Decode/Window.cs @@ -16,6 +16,7 @@ namespace OCR_Decode private Rectangle _bounds; private Bitmap _image; private string _name; + protected static TesseractEngine Engine; public Rectangle Bounds { get => _bounds; private set => _bounds = value; } public Bitmap Image { get => _image; set => _image = value; } public string Name { get => _name; protected set => _name = value; } @@ -36,14 +37,17 @@ namespace OCR_Decode { Image = image; Bounds = bounds; + + Engine = new TesseractEngine(TESS_DATA_FOLDER.FullName, "eng", EngineMode.Default); + Engine.DefaultPageSegMode = PageSegMode.SingleLine; } public virtual Object DecodePng() { - return " "; + return "NaN"; } public virtual Object DecodePng(List drivers) { - return " "; + return "NaN"; } public static byte[] ImageToByte(Image img) { @@ -53,58 +57,17 @@ namespace OCR_Decode return stream.ToArray(); } } - public static bool IsADriver(List drivers,string potentialDriver) - { - bool result = false; - //I cant use drivers.Contains because it has missmatched cases and all - foreach (string name in drivers) - { - if (name.ToUpper() == potentialDriver.ToUpper()) - result = true; - } - return result; - } - public static Bitmap ConvertToBlackAndWhite(Bitmap inputBmp, int Treshold = 165) - { - Bitmap result = new Bitmap(inputBmp.Width, inputBmp.Height); - - for (int y = 0; y < inputBmp.Height; y++) - { - for (int x = 0; x < inputBmp.Width; x++) - { - Color pixelColor = inputBmp.GetPixel(x, y); - if (pixelColor.R <= Treshold && pixelColor.G <= Treshold && pixelColor.B <= Treshold) - { - pixelColor = Color.FromArgb(0, 0, 0); - } - else - { - pixelColor = Color.FromArgb(255, 255, 255); - } - result.SetPixel(x, y, pixelColor); - } - } - return result; - } public static int GetTimeFromPng(Bitmap wImage) { //returns milliseconds string rawResult = ""; - int treshold = 100; int result = 0; - //Bitmap rawData = wImage; - - OcrImage rawData = new OcrImage(wImage); - Bitmap enhancedImage = rawData.Enhance(); - - TesseractEngine engine = new TesseractEngine(TESS_DATA_FOLDER.FullName, "eng", EngineMode.Default); - engine.DefaultPageSegMode = PageSegMode.SingleLine; - engine.SetVariable("tessedit_char_whitelist", "0123456789.:+-LEADRPleadrp"); + Bitmap enhancedImage = new OcrImage(wImage).Enhance(); var tessImage = Pix.LoadFromMemory(ImageToByte(enhancedImage)); - Page page = engine.Process(tessImage); + Page page = Engine.Process(tessImage); Graphics g = Graphics.FromImage(enhancedImage); // Get the iterator for the page layout using (var iter = page.GetIterator()) @@ -113,12 +76,6 @@ namespace OCR_Decode iter.Begin(); do { - Rect boundingBox; - // Get the bounding box for the current element - if (iter.TryGetBoundingBox(PageIteratorLevel.Word, out boundingBox)) - { - //g.DrawRectangle(Pens.Red, new Rectangle(boundingBox.X1, boundingBox.Y1, boundingBox.Width, boundingBox.Height)); - } // Get the text for the current element try { @@ -136,6 +93,7 @@ namespace OCR_Decode List rawNumbers; //Removes all non digit chars except for the important ones + //We will need to change this when trying to see the Leader and Lap texts string cleanedResult = Regex.Replace(rawResult, "[^0-9.:]", ""); //Splits into minuts seconds miliseconds @@ -176,8 +134,79 @@ namespace OCR_Decode } } } - + page.Dispose(); return result; } + protected string GetStringFromPng() + { + string result = ""; + + Bitmap rawData = WindowImage; + Bitmap enhancedImage = new OcrImage(rawData).Enhance(); + + Page page = Engine.Process(enhancedImage); + using (var iter = page.GetIterator()) + { + iter.Begin(); + do + { + result += iter.GetText(PageIteratorLevel.Word); + } while (iter.Next(PageIteratorLevel.Word)); + } + page.Dispose(); + return result; + } + //This method has been gnerated using ChatGPT + protected static string FindClosestMatch(List array, string target) + { + var closestMatch = ""; + var closestDistance = int.MaxValue; + + foreach (var item in array) + { + var distance = LevenshteinDistance(item, target); + if (distance < closestDistance) + { + closestMatch = item; + closestDistance = distance; + } + } + return closestMatch; + } + //This is a tool to be able to compare strings + protected static int LevenshteinDistance(string s1, string s2) + { + if (string.IsNullOrEmpty(s1)) + { + return string.IsNullOrEmpty(s2) ? 0 : s2.Length; + } + + if (string.IsNullOrEmpty(s2)) + { + return string.IsNullOrEmpty(s1) ? 0 : s1.Length; + } + + var d = new int[s1.Length + 1, s2.Length + 1]; + for (var i = 0; i <= s1.Length; i++) + { + d[i, 0] = i; + } + + for (var j = 0; j <= s2.Length; j++) + { + d[0, j] = j; + } + + for (var i = 1; i <= s1.Length; i++) + { + for (var j = 1; j <= s2.Length; j++) + { + var cost = (s1[i - 1] == s2[j - 1]) ? 0 : 1; + d[i, j] = Math.Min(Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1), d[i - 1, j - 1] + cost); + } + } + + return d[s1.Length, s2.Length]; + } } }