From 0efeb44acf172f9d0eb12eca6799583203ea3153 Mon Sep 17 00:00:00 2001 From: maxluli Date: Wed, 7 Jun 2023 11:05:34 +0200 Subject: [PATCH] Added some more paralel processing --- TrackTrends/Form1.cs | 2 + TrackTrends/OcrImage.cs | 96 +++++++++++++++++++++++------------------ 2 files changed, 57 insertions(+), 41 deletions(-) diff --git a/TrackTrends/Form1.cs b/TrackTrends/Form1.cs index ac612b9..598ce42 100644 --- a/TrackTrends/Form1.cs +++ b/TrackTrends/Form1.cs @@ -106,6 +106,8 @@ namespace TrackTrends tbxGpUrl.Text = GpUrl; + this.DoubleBuffered = true; + oldSize = this.Size; oldRankingSize = gpbxRanking.Size; oldLapTimesSize = gpbxLapTimes.Size; diff --git a/TrackTrends/OcrImage.cs b/TrackTrends/OcrImage.cs index ce966c6..9640be8 100644 --- a/TrackTrends/OcrImage.cs +++ b/TrackTrends/OcrImage.cs @@ -19,6 +19,8 @@ namespace TrackTrends //Any color that has any of its R,G or B channel higher than the treshold will be considered as being usefull information public static Color F1TV_BACKGROUND_TRESHOLD = Color.FromArgb(0x50, 0x50, 0x50); Bitmap InputBitmap; + + Random rnd = new Random(); public enum WindowType { LapTime, @@ -71,7 +73,7 @@ namespace TrackTrends case WindowType.LapTime: //outputBitmap.Save(Window.LAPTIME_DEBUG_FOLDER + @"\raw_" + id + ".png"); - outputBitmap = Tresholding(outputBitmap,185); + outputBitmap = Tresholding(outputBitmap, 185); //outputBitmap.Save(Window.LAPTIME_DEBUG_FOLDER + @"\Treshold_" + id + ".png"); outputBitmap = SobelEdgeDetection(outputBitmap); @@ -108,42 +110,53 @@ namespace TrackTrends public static Bitmap Grayscale(Bitmap inputBitmap) { Rectangle rect = new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height); - BitmapData bmpData = inputBitmap.LockBits(rect, ImageLockMode.ReadWrite, inputBitmap.PixelFormat); + BitmapData bmpData = inputBitmap.LockBits(rect, ImageLockMode.ReadOnly, inputBitmap.PixelFormat); int bytesPerPixel = Bitmap.GetPixelFormatSize(inputBitmap.PixelFormat) / 8; + Bitmap resultBitmap = new Bitmap(inputBitmap.Width, inputBitmap.Height); + unsafe { - byte* ptr = (byte*)bmpData.Scan0.ToPointer(); - for (int y = 0; y < inputBitmap.Height; y++) + byte* inputPtr = (byte*)bmpData.Scan0.ToPointer(); + byte* resultPtr = (byte*)resultBitmap.LockBits(rect, ImageLockMode.WriteOnly, resultBitmap.PixelFormat).Scan0.ToPointer(); + + Parallel.For(0, inputBitmap.Height, y => { - byte* currentLine = ptr + (y * bmpData.Stride); + byte* currentLine = inputPtr + (y * bmpData.Stride); + byte* resultLine = resultPtr + (y * resultBitmap.Width * bytesPerPixel); + for (int x = 0; x < inputBitmap.Width; x++) { - byte* pixel = currentLine + (x * bytesPerPixel); + byte* inputPixel = currentLine + (x * bytesPerPixel); + byte* resultPixel = resultLine + (x * bytesPerPixel); - byte blue = pixel[0]; - byte green = pixel[1]; - byte red = pixel[2]; + byte blue = inputPixel[0]; + byte green = inputPixel[1]; + byte red = inputPixel[2]; //Those a specific values to correct the weights so its more pleasing to the human eye int gray = (int)(red * 0.3 + green * 0.59 + blue * 0.11); //This is not a proper treshold method but it is helping the sobel edge detection - if(gray <= F1TV_BACKGROUND_TRESHOLD.R) + if (gray <= F1TV_BACKGROUND_TRESHOLD.R) { - pixel[0] = pixel[1] = pixel[2] = 0; + resultPixel[0] = resultPixel[1] = resultPixel[2] = 0; } else { - pixel[0] = pixel[1] = pixel[2] = (byte)gray; + resultPixel[0] = resultPixel[1] = resultPixel[2] = (byte)gray; } } - } + }); + + resultBitmap.UnlockBits(resultBitmap.LockBits(rect, ImageLockMode.WriteOnly, resultBitmap.PixelFormat)); } + inputBitmap.UnlockBits(bmpData); - return inputBitmap; + return resultBitmap; } + /// /// Method that uses the Sobel Edge detection to outline the edges of the characters to help with the OCR /// @@ -161,6 +174,7 @@ namespace TrackTrends // Apply the Sobel operators and normalize the gradients // NOTE: I dont know how easy or hard it would be to make this paralel but it could be a good idea to do so if possible. + //Parallel.For(1, grayscaleImage.Height - 1, y => for (int y = 1; y < grayscaleImage.Height - 1; y++) { for (int x = 1; x < grayscaleImage.Width - 1; x++) @@ -175,7 +189,7 @@ namespace TrackTrends edgesImage.SetPixel(x, y, Color.FromArgb(gradient, gradient, gradient)); } - } + }//); return edgesImage; } @@ -206,39 +220,37 @@ namespace TrackTrends /// Method that is used to whiten an image. Ignore the funny name. Its used to prevent colored text to trouble the OCR when it uses grayscaling /// /// The bitmap to vanish - /// - public static Bitmap VanishOxyAction(Bitmap inputBitmap) + /// + public Bitmap VanishOxyAction(Bitmap inputBitmap) { - Rectangle rect = new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height); - BitmapData bmpData = inputBitmap.LockBits(rect, ImageLockMode.ReadWrite, inputBitmap.PixelFormat); - int bytesPerPixel = Bitmap.GetPixelFormatSize(inputBitmap.PixelFormat) / 8; - unsafe { - //Note : MAKE THIS PARALELL OMG WY DID I LEFT IT LIKE THAT - byte* ptr = (byte*)bmpData.Scan0.ToPointer(); - for (int y = 0; y < inputBitmap.Height; y++) - { - byte* currentLine = ptr + (y * bmpData.Stride); - for (int x = 0; x < inputBitmap.Width; x++) - { - byte* pixel = currentLine + (x * bytesPerPixel); + BitmapData bitmapData = inputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height), ImageLockMode.ReadWrite, inputBitmap.PixelFormat); - int blue = (int)pixel[0]; - int green = (int)pixel[1]; - int red = (int)pixel[2]; + int bytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(inputBitmap.PixelFormat) / 8; + int heightInPixels = bitmapData.Height; + int widthInBytes = bitmapData.Width * bytesPerPixel; + byte* PtrFirstPixel = (byte*)bitmapData.Scan0; + + Parallel.For(0, heightInPixels, y => + { + byte* currentLine = PtrFirstPixel + (y * bitmapData.Stride); + for (int x = 0; x < widthInBytes; x = x + bytesPerPixel) + { + int blue = currentLine[x]; + int green = currentLine[x + 1]; + int red = currentLine[x + 2]; int max = Math.Max(Math.Max(blue, green), red); if (max > 255 / 3) max = 255; - pixel[0] = pixel[1] = pixel[2] = (byte)max; + currentLine[x] = currentLine[x + 1] = currentLine[x + 2] = (byte)max; } - } + }); + inputBitmap.UnlockBits(bitmapData); } - inputBitmap.UnlockBits(bmpData); - return inputBitmap; } /// @@ -294,10 +306,12 @@ namespace TrackTrends unsafe { byte* ptr = (byte*)bmpData.Scan0.ToPointer(); - for (int y = 0; y < inputBitmap.Height; y++) + int bmpHeight = inputBitmap.Height; + int bmpWidth = inputBitmap.Width; + Parallel.For(0, bmpHeight, y => { byte* currentLine = ptr + (y * bmpData.Stride); - for (int x = 0; x < inputBitmap.Width; x++) + for (int x = 0; x < bmpWidth; x++) { byte* pixel = currentLine + (x * bytesPerPixel); @@ -308,7 +322,7 @@ namespace TrackTrends if (R <= F1TV_BACKGROUND_TRESHOLD.R && G <= F1TV_BACKGROUND_TRESHOLD.G && B <= F1TV_BACKGROUND_TRESHOLD.B) pixel[0] = pixel[1] = pixel[2] = 0; } - } + }); } inputBitmap.UnlockBits(bmpData); @@ -401,7 +415,7 @@ namespace TrackTrends int G = pixel[1]; int R = pixel[2]; - if (R >= F1TV_BACKGROUND_TRESHOLD.R +25|| G >= F1TV_BACKGROUND_TRESHOLD.G +25|| B >= F1TV_BACKGROUND_TRESHOLD.B +25) + if (R >= F1TV_BACKGROUND_TRESHOLD.R + 25 || G >= F1TV_BACKGROUND_TRESHOLD.G + 25 || B >= F1TV_BACKGROUND_TRESHOLD.B + 25) { pixel[0] = 0xFF; pixel[1] = 0xFF; @@ -458,7 +472,7 @@ namespace TrackTrends } inputBitmap.UnlockBits(bmpData); - return Color.FromArgb(255,Math.Min(Convert.ToInt32((float)totR / (float)totPixels),255), Math.Min(Convert.ToInt32((float)totG / (float)totPixels),255), Math.Min(Convert.ToInt32((float)totB / (float)totPixels),255)); + return Color.FromArgb(255, Math.Min(Convert.ToInt32((float)totR / (float)totPixels), 255), Math.Min(Convert.ToInt32((float)totG / (float)totPixels), 255), Math.Min(Convert.ToInt32((float)totB / (float)totPixels), 255)); } /// /// This method simply inverts all the colors in a Bitmap