diff --git a/OCR_Decode/OCR_Decode.csproj b/OCR_Decode/OCR_Decode.csproj
index ab8c0d7..32805f1 100644
--- a/OCR_Decode/OCR_Decode.csproj
+++ b/OCR_Decode/OCR_Decode.csproj
@@ -35,6 +35,30 @@
4
+
+ ..\packages\Accord.3.8.0\lib\net462\Accord.dll
+
+
+ ..\packages\Accord.Imaging.3.8.0\lib\net462\Accord.Imaging.dll
+
+
+ ..\packages\Accord.Math.3.8.0\lib\net462\Accord.Math.dll
+
+
+ ..\packages\Accord.Math.3.8.0\lib\net462\Accord.Math.Core.dll
+
+
+ ..\packages\Accord.Statistics.3.8.0\lib\net462\Accord.Statistics.dll
+
+
+ ..\packages\AForge.2.2.5\lib\AForge.dll
+
+
+ ..\packages\AForge.Imaging.2.2.5\lib\AForge.Imaging.dll
+
+
+ ..\packages\AForge.Math.2.2.5\lib\AForge.Math.dll
+
..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll
@@ -97,6 +121,7 @@
Form1.cs
+
@@ -135,5 +160,7 @@
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
\ No newline at end of file
diff --git a/OCR_Decode/OcrImage.cs b/OCR_Decode/OcrImage.cs
new file mode 100644
index 0000000..1a9b047
--- /dev/null
+++ b/OCR_Decode/OcrImage.cs
@@ -0,0 +1,253 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using Accord.Imaging.Filters;
+
+namespace OCR_Decode
+{
+ //AT LEAST PART OF THIS CLASS HAVE BEEN CREATED USING CHATGPT
+ //Just so you know
+ internal class OcrImage
+ {
+ Bitmap InputImage;
+ public OcrImage(Bitmap inputImage)
+ {
+ InputImage = inputImage;
+ }
+ public Bitmap Enhance()
+ {
+ Bitmap result = (Bitmap)InputImage.Clone();
+ result = Grayscale(result);
+ result = Tresholding(result, 200);
+ result = InvertColors(result);
+ result = Resize(result);
+ //result = Resize(result);
+ //result = Dilatation(result, 5);
+ //result = Erode(result,3);
+ return result;
+ }
+ public static Bitmap Grayscale(Bitmap input)
+ {
+ Bitmap output = new Bitmap(input.Width, input.Height);
+
+ for (int y = 0; y < input.Height; y++)
+ {
+ for (int x = 0; x < input.Width; x++)
+ {
+ Color pixel = input.GetPixel(x, y);
+ int gray = (int)(pixel.R * 0.3 + pixel.G * 0.59 + pixel.B * 0.11);
+ output.SetPixel(x, y, Color.FromArgb(gray, gray, gray));
+ }
+ }
+
+ return output;
+ }
+ public static Bitmap Tresholding(Bitmap input, int threshold)
+ {
+ Bitmap output = new Bitmap(input.Width, input.Height);
+
+ for (int y = 0; y < input.Height; y++)
+ {
+ for (int x = 0; x < input.Width; x++)
+ {
+ Color pixel = input.GetPixel(x, y);
+ int gray = (int)(pixel.R * 0.3 + pixel.G * 0.59 + pixel.B * 0.11);
+ int value = gray < threshold ? 0 : 255;
+ output.SetPixel(x, y, Color.FromArgb(value, value, value));
+ }
+ }
+
+ return output;
+ }
+ public static Bitmap InvertColors(Bitmap input)
+ {
+ Bitmap output = new Bitmap(input.Width, input.Height);
+
+ for (int y = 0; y < input.Height; y++)
+ {
+ for (int x = 0; x < input.Width; x++)
+ {
+ Color pixel = input.GetPixel(x, y);
+ int red = 255 - pixel.R;
+ int green = 255 - pixel.G;
+ int blue = 255 - pixel.B;
+ output.SetPixel(x, y, Color.FromArgb(red, green, blue));
+ }
+ }
+
+ return output;
+ }
+ public static Bitmap ApplyGaussianBlur(Bitmap input, int radius)
+ {
+ GaussianBlur filter = new GaussianBlur(radius);
+ Bitmap output = filter.Apply(input);
+ return output;
+ }
+ public static Bitmap Resize(Bitmap sourceBitmap)
+ {
+ // Create a new Bitmap object to hold the resized image
+ var resultBitmap = new Bitmap(sourceBitmap.Width * 2, sourceBitmap.Height * 2);
+
+ // Create a Graphics object to draw the resized image
+ using (var graphics = Graphics.FromImage(resultBitmap))
+ {
+ // Set the interpolation mode to high-quality bicubic
+ graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
+
+ // Draw the resized image using the Graphics object
+ graphics.DrawImage(sourceBitmap, new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height));
+ }
+
+ return resultBitmap;
+ }
+ public static Bitmap HighlightContours(Bitmap input)
+ {
+ Bitmap output = new Bitmap(input.Width, input.Height);
+
+ Bitmap grayscale = Grayscale(input);
+ Bitmap thresholded = Tresholding(grayscale, 128);
+ Bitmap dilated = Dilatation(thresholded, 3);
+ Bitmap eroded = Erode(dilated, 3);
+
+ for (int y = 0; y < input.Height; y++)
+ {
+ for (int x = 0; x < input.Width; x++)
+ {
+ Color pixel = input.GetPixel(x, y);
+ Color dilatedPixel = dilated.GetPixel(x, y);
+ Color erodedPixel = eroded.GetPixel(x, y);
+
+ int gray = (int)(pixel.R * 0.3 + pixel.G * 0.59 + pixel.B * 0.11);
+ int threshold = dilatedPixel.R;
+
+ if (gray > threshold)
+ {
+ output.SetPixel(x, y, Color.FromArgb(255, 255, 255));
+ }
+ else if (gray <= threshold && erodedPixel.R == 0)
+ {
+ output.SetPixel(x, y, Color.FromArgb(255, 0, 0));
+ }
+ else
+ {
+ output.SetPixel(x, y, Color.FromArgb(0, 0, 0));
+ }
+ }
+ }
+
+ return output;
+ }
+ public static Bitmap Erode(Bitmap input, int kernelSize)
+ {
+ Bitmap output = new Bitmap(input.Width, input.Height);
+
+ int[,] kernel = new int[kernelSize, kernelSize];
+
+ for (int i = 0; i < kernelSize; i++)
+ {
+ for (int j = 0; j < kernelSize; j++)
+ {
+ kernel[i, j] = 1;
+ }
+ }
+
+ for (int y = kernelSize / 2; y < input.Height - kernelSize / 2; y++)
+ {
+ for (int x = kernelSize / 2; x < input.Width - kernelSize / 2; x++)
+ {
+ bool flag = true;
+
+ for (int i = -kernelSize / 2; i <= kernelSize / 2; i++)
+ {
+ for (int j = -kernelSize / 2; j <= kernelSize / 2; j++)
+ {
+ Color pixel = input.GetPixel(x + i, y + j);
+ int gray = (int)(pixel.R * 0.3 + pixel.G * 0.59 + pixel.B * 0.11);
+
+ if (gray >= 128 && kernel[i + kernelSize / 2, j + kernelSize / 2] == 1)
+ {
+ flag = false;
+ break;
+ }
+ }
+
+ if (!flag)
+ {
+ break;
+ }
+ }
+
+ if (flag)
+ {
+ output.SetPixel(x, y, Color.FromArgb(255, 255, 255));
+ }
+ else
+ {
+ output.SetPixel(x, y, Color.FromArgb(0, 0, 0));
+ }
+ }
+ }
+
+ return output;
+ }
+
+ public static Bitmap Dilatation(Bitmap input, int kernelSize)
+ {
+ Bitmap output = new Bitmap(input.Width, input.Height);
+
+ int[,] kernel = new int[kernelSize, kernelSize];
+
+ for (int i = 0; i < kernelSize; i++)
+ {
+ for (int j = 0; j < kernelSize; j++)
+ {
+ kernel[i, j] = 1;
+ }
+ }
+
+ for (int y = kernelSize / 2; y < input.Height - kernelSize / 2; y++)
+ {
+ for (int x = kernelSize / 2; x < input.Width - kernelSize / 2; x++)
+ {
+ bool flag = false;
+
+ for (int i = -kernelSize / 2; i <= kernelSize / 2; i++)
+ {
+ for (int j = -kernelSize / 2; j <= kernelSize / 2; j++)
+ {
+ Color pixel = input.GetPixel(x + i, y + j);
+ int gray = (int)(pixel.R * 0.3 + pixel.G * 0.59 + pixel.B * 0.11);
+
+ if (gray < 128 && kernel[i + kernelSize / 2, j + kernelSize / 2] == 1)
+ {
+ flag = true;
+ break;
+ }
+ }
+
+ if (flag)
+ {
+ break;
+ }
+ }
+
+ if (flag)
+ {
+ output.SetPixel(x, y, Color.FromArgb(0, 0, 0));
+ }
+ else
+ {
+ output.SetPixel(x, y, Color.FromArgb(255, 255, 255));
+ }
+ }
+ }
+
+ return output;
+ }
+
+ }
+}
diff --git a/OCR_Decode/Window.cs b/OCR_Decode/Window.cs
index 2e113cd..5f898b7 100644
--- a/OCR_Decode/Window.cs
+++ b/OCR_Decode/Window.cs
@@ -7,6 +7,7 @@ using System.Drawing;
using System.IO;
using Tesseract;
using System.Text.RegularExpressions;
+using System.Drawing.Drawing2D;
namespace OCR_Decode
{
@@ -89,17 +90,22 @@ namespace OCR_Decode
{
//returns milliseconds
string rawResult = "";
- int treshold = 165;
+ int treshold = 100;
int result = 0;
- Bitmap rawData = wImage;
- rawData = Window.ConvertToBlackAndWhite(rawData, treshold);
+ //Bitmap rawData = wImage;
+
+ OcrImage rawData = new OcrImage(wImage);
+ Bitmap enhancedImage = rawData.Enhance();
TesseractEngine engine = new TesseractEngine(TESS_DATA_FOLDER.FullName, "eng", EngineMode.Default);
- var tessImage = Pix.LoadFromMemory(ImageToByte(wImage));
+ engine.DefaultPageSegMode = PageSegMode.SingleLine;
+ engine.SetVariable("tessedit_char_whitelist", "0123456789.:+-LEADRPleadrp");
+
+ var tessImage = Pix.LoadFromMemory(ImageToByte(enhancedImage));
Page page = engine.Process(tessImage);
- Graphics g = Graphics.FromImage(rawData);
+ Graphics g = Graphics.FromImage(enhancedImage);
// Get the iterator for the page layout
using (var iter = page.GetIterator())
{
@@ -111,7 +117,7 @@ namespace OCR_Decode
// 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));
+ //g.DrawRectangle(Pens.Red, new Rectangle(boundingBox.X1, boundingBox.Y1, boundingBox.Width, boundingBox.Height));
}
// Get the text for the current element
try
@@ -125,18 +131,17 @@ namespace OCR_Decode
} while (iter.Next(PageIteratorLevel.Word));
}
+ enhancedImage.Save(Reader.DEBUG_DUMP_FOLDER + Regex.Replace(rawResult, "[^0-9A-Za-z]", "") + ".png");
+
List rawNumbers;
//Removes all non digit chars except for the important ones
string cleanedResult = Regex.Replace(rawResult, "[^0-9.:]", "");
+
//Splits into minuts seconds miliseconds
rawNumbers = cleanedResult.Split('.', ':').ToList();
//removes any empty cells (tho this usually sign of a really bad OCR implementation tbh will have to be fixed higher in the chian)
- for (int i = 0; i < rawNumbers.Count;i++)
- {
- if (rawNumbers[i] == "")
- rawNumbers.RemoveAt(i);
- }
+ rawNumbers.RemoveAll(x => ((string)x) == "");
if (rawNumbers.Count == 3)
{
@@ -154,8 +159,6 @@ namespace OCR_Decode
{
if (rawNumbers.Count == 1)
{
- //ss
- //if (rawNumbers[0] == "LEADER")
try
{
result = Convert.ToInt32(rawNumbers[0]);
diff --git a/OCR_Decode/packages.config b/OCR_Decode/packages.config
index cd49cd2..3a24cbb 100644
--- a/OCR_Decode/packages.config
+++ b/OCR_Decode/packages.config
@@ -1,5 +1,12 @@
+
+
+
+
+
+
+