Added some more paralel processing

This commit is contained in:
2023-06-07 11:05:34 +02:00
parent 69ecab841f
commit 0efeb44acf
2 changed files with 57 additions and 41 deletions
+2
View File
@@ -106,6 +106,8 @@ namespace TrackTrends
tbxGpUrl.Text = GpUrl; tbxGpUrl.Text = GpUrl;
this.DoubleBuffered = true;
oldSize = this.Size; oldSize = this.Size;
oldRankingSize = gpbxRanking.Size; oldRankingSize = gpbxRanking.Size;
oldLapTimesSize = gpbxLapTimes.Size; oldLapTimesSize = gpbxLapTimes.Size;
+55 -41
View File
@@ -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 //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); public static Color F1TV_BACKGROUND_TRESHOLD = Color.FromArgb(0x50, 0x50, 0x50);
Bitmap InputBitmap; Bitmap InputBitmap;
Random rnd = new Random();
public enum WindowType public enum WindowType
{ {
LapTime, LapTime,
@@ -71,7 +73,7 @@ namespace TrackTrends
case WindowType.LapTime: case WindowType.LapTime:
//outputBitmap.Save(Window.LAPTIME_DEBUG_FOLDER + @"\raw_" + id + ".png"); //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.Save(Window.LAPTIME_DEBUG_FOLDER + @"\Treshold_" + id + ".png");
outputBitmap = SobelEdgeDetection(outputBitmap); outputBitmap = SobelEdgeDetection(outputBitmap);
@@ -108,42 +110,53 @@ namespace TrackTrends
public static Bitmap Grayscale(Bitmap inputBitmap) public static Bitmap Grayscale(Bitmap inputBitmap)
{ {
Rectangle rect = new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height); 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; int bytesPerPixel = Bitmap.GetPixelFormatSize(inputBitmap.PixelFormat) / 8;
Bitmap resultBitmap = new Bitmap(inputBitmap.Width, inputBitmap.Height);
unsafe unsafe
{ {
byte* ptr = (byte*)bmpData.Scan0.ToPointer(); byte* inputPtr = (byte*)bmpData.Scan0.ToPointer();
for (int y = 0; y < inputBitmap.Height; y++) 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++) 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 blue = inputPixel[0];
byte green = pixel[1]; byte green = inputPixel[1];
byte red = pixel[2]; byte red = inputPixel[2];
//Those a specific values to correct the weights so its more pleasing to the human eye //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); 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 //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 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); inputBitmap.UnlockBits(bmpData);
return inputBitmap; return resultBitmap;
} }
/// <summary> /// <summary>
/// Method that uses the Sobel Edge detection to outline the edges of the characters to help with the OCR /// Method that uses the Sobel Edge detection to outline the edges of the characters to help with the OCR
/// </summary> /// </summary>
@@ -161,6 +174,7 @@ namespace TrackTrends
// Apply the Sobel operators and normalize the gradients // 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. // 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 y = 1; y < grayscaleImage.Height - 1; y++)
{ {
for (int x = 1; x < grayscaleImage.Width - 1; x++) for (int x = 1; x < grayscaleImage.Width - 1; x++)
@@ -175,7 +189,7 @@ namespace TrackTrends
edgesImage.SetPixel(x, y, Color.FromArgb(gradient, gradient, gradient)); edgesImage.SetPixel(x, y, Color.FromArgb(gradient, gradient, gradient));
} }
} }//);
return edgesImage; 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 /// 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
/// </summary> /// </summary>
/// <param name="inputBitmap">The bitmap to vanish</param> /// <param name="inputBitmap">The bitmap to vanish</param>
/// <returns></returns> /// <returns></returns>
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 unsafe
{ {
//Note : MAKE THIS PARALELL OMG WY DID I LEFT IT LIKE THAT BitmapData bitmapData = inputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height), ImageLockMode.ReadWrite, inputBitmap.PixelFormat);
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);
int blue = (int)pixel[0]; int bytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(inputBitmap.PixelFormat) / 8;
int green = (int)pixel[1]; int heightInPixels = bitmapData.Height;
int red = (int)pixel[2]; 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); int max = Math.Max(Math.Max(blue, green), red);
if (max > 255 / 3) if (max > 255 / 3)
max = 255; 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; return inputBitmap;
} }
/// <summary> /// <summary>
@@ -294,10 +306,12 @@ namespace TrackTrends
unsafe unsafe
{ {
byte* ptr = (byte*)bmpData.Scan0.ToPointer(); 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); 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); 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) if (R <= F1TV_BACKGROUND_TRESHOLD.R && G <= F1TV_BACKGROUND_TRESHOLD.G && B <= F1TV_BACKGROUND_TRESHOLD.B)
pixel[0] = pixel[1] = pixel[2] = 0; pixel[0] = pixel[1] = pixel[2] = 0;
} }
} });
} }
inputBitmap.UnlockBits(bmpData); inputBitmap.UnlockBits(bmpData);
@@ -401,7 +415,7 @@ namespace TrackTrends
int G = pixel[1]; int G = pixel[1];
int R = pixel[2]; 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[0] = 0xFF;
pixel[1] = 0xFF; pixel[1] = 0xFF;
@@ -458,7 +472,7 @@ namespace TrackTrends
} }
inputBitmap.UnlockBits(bmpData); 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));
} }
/// <summary> /// <summary>
/// This method simply inverts all the colors in a Bitmap /// This method simply inverts all the colors in a Bitmap