diff --git a/TestVideo/EnumExtensions.cs b/TestVideo/EnumExtensions.cs
new file mode 100644
index 0000000..5076047
--- /dev/null
+++ b/TestVideo/EnumExtensions.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TestVideo
+{
+ public static class EnumExtensions
+ {
+ ///
+ /// Gets all items for an enum value.
+ ///
+ ///
+ /// The value.
+ ///
+ public static IEnumerable GetAllItems(this Enum value)
+ {
+ foreach (object item in Enum.GetValues(typeof(T)))
+ {
+ yield return (T)item;
+ }
+ }
+
+ ///
+ /// Gets all items for an enum type.
+ ///
+ ///
+ /// The value.
+ ///
+ public static IEnumerable GetAllItems() where T : struct
+ {
+ foreach (object item in Enum.GetValues(typeof(T)))
+ {
+ yield return (T)item;
+ }
+ }
+
+ ///
+ /// Gets all combined items from an enum value.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// Displays ValueA and ValueB.
+ ///
+ /// EnumExample dummy = EnumExample.Combi;
+ /// foreach (var item in dummy.GetAllSelectedItems())
+ /// {
+ /// Console.WriteLine(item);
+ /// }
+ ///
+ ///
+ public static IEnumerable GetAllSelectedItems(this Enum value)
+ {
+ int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);
+
+ foreach (object item in Enum.GetValues(typeof(T)))
+ {
+ int itemAsInt = Convert.ToInt32(item, CultureInfo.InvariantCulture);
+
+ if (itemAsInt == (valueAsInt & itemAsInt))
+ {
+ yield return (T)item;
+ }
+ }
+ }
+
+ ///
+ /// Determines whether the enum value contains a specific value.
+ ///
+ /// The value.
+ /// The request.
+ ///
+ /// true if value contains the specified value; otherwise, false.
+ ///
+ ///
+ ///
+ /// EnumExample dummy = EnumExample.Combi;
+ /// if (dummy.Contains(EnumExample.ValueA))
+ /// {
+ /// Console.WriteLine("dummy contains EnumExample.ValueA");
+ /// }
+ ///
+ ///
+ public static bool Contains(this Enum value, T request)
+ {
+ int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);
+ int requestAsInt = Convert.ToInt32(request, CultureInfo.InvariantCulture);
+
+ if (requestAsInt == (valueAsInt & requestAsInt))
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/TestVideo/Extraction.cs b/TestVideo/Extraction.cs
new file mode 100644
index 0000000..6cd4758
--- /dev/null
+++ b/TestVideo/Extraction.cs
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace TestVideo
+{
+ internal class Extraction
+ {
+ private List _zones;
+ private Screen _currentScreen;
+ private Bitmap _screenPreview;
+
+ public Screen CurrentScreen { get => _currentScreen; set => _currentScreen = value; }
+ public List Zones { get => _zones; private set => _zones = value; }
+ public Bitmap ScreenPreview { get => _screenPreview; set => _screenPreview = value; }
+
+ public Extraction(Screen screen)
+ {
+ CurrentScreen = screen;
+ }
+ public Extraction(List zones)
+ {
+ Zones = zones;
+ }
+
+ public void UpdateZones()
+ {
+ ScreenPreview = ScreenShot();
+ DrawZones();
+ foreach (Zone zone in Zones)
+ {
+ Bitmap bmpData = ScreenPreview.Clone(zone.ZoneArea, ScreenPreview.PixelFormat);
+ zone.Update(bmpData);
+ }
+ }
+ public void ChangeScreen(Screen newScreen)
+ {
+ if (newScreen != CurrentScreen)
+ CurrentScreen = newScreen;
+
+ //This makes sure that if you go from a screen with smaller dimensions only the zones that are valid for it stays
+ List newZones = new List();
+ foreach (Zone zone in newZones)
+ {
+ if (IsZoneInBounds(zone.ZoneArea))
+ newZones.Add(zone);
+ }
+ Zones = newZones;
+
+ ScreenPreview = ScreenShot();
+ }
+ public List GetZonesNames()
+ {
+ List zoneNames = new List();
+ foreach (Zone zone in Zones)
+ {
+ zoneNames.Add(zone.Name);
+ }
+ return zoneNames;
+ }
+ public void AddZone(Rectangle zoneArea,Zone.ZoneType type,string name)
+ {
+ if (!IsZoneInBounds(zoneArea))
+ throw new ArgumentException("Rectangle is outside the screen");
+
+ Zones.Add(new Zone(zoneArea,type,name));
+ }
+ public void RemoveZone(int idZone)
+ {
+ Zones.RemoveAt(idZone);
+ }
+
+ public Rectangle GetZoneArea(int idZone)
+ {
+ return Zones[idZone].ZoneArea;
+ }
+
+ public Bitmap GetZoneData(int idZone)
+ {
+ return Zones[idZone].ZoneData;
+ }
+
+ public string GetZoneRawText(int idZone)
+ {
+ return Zones[idZone].RawText;
+ }
+ public string[] GetZonesCleanText(int idZone)
+ {
+ return Zones[idZone].CleanText;
+ }
+ private Bitmap ScreenShot()
+ {
+ Bitmap screenshot;
+ screenshot = new Bitmap(CurrentScreen.Bounds.Width, CurrentScreen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+ // Create a graphics object from the bitmap
+ Graphics gfxScreenshot = Graphics.FromImage(screenshot);
+ // Take the screenshot from the upper left corner to the right bottom corner
+ gfxScreenshot.CopyFromScreen(
+ CurrentScreen.Bounds.X,
+ CurrentScreen.Bounds.Y,
+ 0,
+ 0,
+ CurrentScreen.Bounds.Size,
+ CopyPixelOperation.SourceCopy);
+ return screenshot;
+ }
+ public void DrawZones()
+ {
+ using (Graphics g = Graphics.FromImage(ScreenPreview))
+ {
+ foreach (Zone zone in Zones)
+ {
+ g.DrawRectangle(new Pen(Color.Red,3),zone.ZoneArea);
+ }
+ }
+ }
+ private string SaveScreenshot(Bitmap image)
+ {
+ //This method is now quite old. If you plan to use it I would recommand rewriting it
+ string path = "";
+ string directory = AppDomain.CurrentDomain.BaseDirectory + "Screens";
+ path = directory + "\\Screenshot" + DateTime.Now.ToString("yyyy_MM_dd-hh_mm_ss") + ".png";
+ if (Directory.Exists(directory))
+ {
+ image.Save(path, ImageFormat.Png);
+ }
+ else
+ {
+ Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + "\\Screens");
+ }
+ return path;
+ }
+ private bool IsZoneInBounds(Rectangle zoneArea)
+ {
+ bool result = true;
+ //Check that the position of the zone is possible
+ if (zoneArea.X < 0 || zoneArea.X >= CurrentScreen.Bounds.Width)
+ result = false;
+ if (zoneArea.Y < 0 || zoneArea.Y >= CurrentScreen.Bounds.Width)
+ result = false;
+ //Check that the zone does'nt go outside the bounds of the Screen
+ if (zoneArea.X + zoneArea.Width >= CurrentScreen.Bounds.Width)
+ result = false;
+ if (zoneArea.Y + zoneArea.Height >= CurrentScreen.Bounds.Height)
+ result = false;
+
+ return result;
+ }
+ }
+}
diff --git a/TestVideo/Form1.Designer.cs b/TestVideo/Form1.Designer.cs
index 3d5310b..600f646 100644
--- a/TestVideo/Form1.Designer.cs
+++ b/TestVideo/Form1.Designer.cs
@@ -35,6 +35,15 @@
this.tmrScreenshots = new System.Windows.Forms.Timer(this.components);
this.lsbScreens = new System.Windows.Forms.ListBox();
this.tbxResult = new System.Windows.Forms.TextBox();
+ this.lsbZones = new System.Windows.Forms.ListBox();
+ this.btnCreateZone = new System.Windows.Forms.Button();
+ this.button2 = new System.Windows.Forms.Button();
+ this.lsbZoneTypes = new System.Windows.Forms.ListBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.label2 = new System.Windows.Forms.Label();
+ this.label3 = new System.Windows.Forms.Label();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.label4 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.pbxInput)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pbxOutput)).BeginInit();
this.SuspendLayout();
@@ -43,14 +52,15 @@
//
this.pbxInput.Location = new System.Drawing.Point(12, 12);
this.pbxInput.Name = "pbxInput";
- this.pbxInput.Size = new System.Drawing.Size(480, 270);
+ this.pbxInput.Size = new System.Drawing.Size(960, 540);
this.pbxInput.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pbxInput.TabIndex = 0;
this.pbxInput.TabStop = false;
+ this.pbxInput.Click += new System.EventHandler(this.pbxInput_Click);
//
// pbxOutput
//
- this.pbxOutput.Location = new System.Drawing.Point(12, 288);
+ this.pbxOutput.Location = new System.Drawing.Point(978, 12);
this.pbxOutput.Name = "pbxOutput";
this.pbxOutput.Size = new System.Drawing.Size(480, 270);
this.pbxOutput.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
@@ -59,11 +69,11 @@
//
// btnStart
//
- this.btnStart.Location = new System.Drawing.Point(495, 245);
+ this.btnStart.Location = new System.Drawing.Point(818, 425);
this.btnStart.Name = "btnStart";
- this.btnStart.Size = new System.Drawing.Size(157, 37);
+ this.btnStart.Size = new System.Drawing.Size(154, 37);
this.btnStart.TabIndex = 2;
- this.btnStart.Text = "Start";
+ this.btnStart.Text = "Start recording";
this.btnStart.UseVisualStyleBackColor = true;
this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
//
@@ -76,32 +86,123 @@
//
this.lsbScreens.FormattingEnabled = true;
this.lsbScreens.ItemHeight = 16;
- this.lsbScreens.Location = new System.Drawing.Point(498, 12);
+ this.lsbScreens.Location = new System.Drawing.Point(818, 468);
this.lsbScreens.Name = "lsbScreens";
- this.lsbScreens.Size = new System.Drawing.Size(154, 228);
+ this.lsbScreens.Size = new System.Drawing.Size(154, 84);
this.lsbScreens.TabIndex = 3;
this.lsbScreens.SelectedIndexChanged += new System.EventHandler(this.lsbScreens_SelectedIndexChanged);
//
// tbxResult
//
- this.tbxResult.Location = new System.Drawing.Point(498, 288);
+ this.tbxResult.Location = new System.Drawing.Point(12, 581);
this.tbxResult.Multiline = true;
this.tbxResult.Name = "tbxResult";
this.tbxResult.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
- this.tbxResult.Size = new System.Drawing.Size(147, 270);
+ this.tbxResult.Size = new System.Drawing.Size(480, 190);
this.tbxResult.TabIndex = 4;
//
+ // lsbZones
+ //
+ this.lsbZones.FormattingEnabled = true;
+ this.lsbZones.ItemHeight = 16;
+ this.lsbZones.Location = new System.Drawing.Point(978, 304);
+ this.lsbZones.Name = "lsbZones";
+ this.lsbZones.Size = new System.Drawing.Size(225, 100);
+ this.lsbZones.TabIndex = 5;
+ this.lsbZones.SelectedIndexChanged += new System.EventHandler(this.lsbZones_SelectedIndexChanged);
+ //
+ // btnCreateZone
+ //
+ this.btnCreateZone.Location = new System.Drawing.Point(978, 410);
+ this.btnCreateZone.Name = "btnCreateZone";
+ this.btnCreateZone.Size = new System.Drawing.Size(482, 37);
+ this.btnCreateZone.TabIndex = 6;
+ this.btnCreateZone.Text = "Create Zone";
+ this.btnCreateZone.UseVisualStyleBackColor = true;
+ this.btnCreateZone.Click += new System.EventHandler(this.btnCreateZone_Click);
+ //
+ // button2
+ //
+ this.button2.Location = new System.Drawing.Point(978, 453);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(482, 37);
+ this.button2.TabIndex = 7;
+ this.button2.Text = "Delete Zone";
+ this.button2.UseVisualStyleBackColor = true;
+ //
+ // lsbZoneTypes
+ //
+ this.lsbZoneTypes.FormattingEnabled = true;
+ this.lsbZoneTypes.ItemHeight = 16;
+ this.lsbZoneTypes.Location = new System.Drawing.Point(1233, 304);
+ this.lsbZoneTypes.Name = "lsbZoneTypes";
+ this.lsbZoneTypes.Size = new System.Drawing.Size(225, 100);
+ this.lsbZoneTypes.TabIndex = 8;
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(978, 285);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(45, 16);
+ this.label1.TabIndex = 9;
+ this.label1.Text = "Zones";
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(1230, 285);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(74, 16);
+ this.label2.TabIndex = 10;
+ this.label2.Text = "Zone types";
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(12, 555);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(69, 16);
+ this.label3.TabIndex = 11;
+ this.label3.Text = "Raw result";
+ //
+ // textBox1
+ //
+ this.textBox1.Location = new System.Drawing.Point(492, 581);
+ this.textBox1.Multiline = true;
+ this.textBox1.Name = "textBox1";
+ this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+ this.textBox1.Size = new System.Drawing.Size(480, 190);
+ this.textBox1.TabIndex = 12;
+ //
+ // label4
+ //
+ this.label4.AutoSize = true;
+ this.label4.Location = new System.Drawing.Point(489, 555);
+ this.label4.Name = "label4";
+ this.label4.Size = new System.Drawing.Size(104, 16);
+ this.label4.TabIndex = 13;
+ this.label4.Text = "Computed result";
+ //
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(657, 565);
+ this.ClientSize = new System.Drawing.Size(1472, 783);
+ this.Controls.Add(this.label4);
+ this.Controls.Add(this.textBox1);
+ this.Controls.Add(this.label3);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.lsbZoneTypes);
+ this.Controls.Add(this.button2);
+ this.Controls.Add(this.btnCreateZone);
+ this.Controls.Add(this.lsbZones);
this.Controls.Add(this.tbxResult);
this.Controls.Add(this.lsbScreens);
this.Controls.Add(this.btnStart);
this.Controls.Add(this.pbxOutput);
this.Controls.Add(this.pbxInput);
- this.Enabled = false;
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.pbxInput)).EndInit();
@@ -119,6 +220,15 @@
private System.Windows.Forms.Timer tmrScreenshots;
private System.Windows.Forms.ListBox lsbScreens;
private System.Windows.Forms.TextBox tbxResult;
+ private System.Windows.Forms.ListBox lsbZones;
+ private System.Windows.Forms.Button btnCreateZone;
+ private System.Windows.Forms.Button button2;
+ private System.Windows.Forms.ListBox lsbZoneTypes;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.TextBox textBox1;
+ private System.Windows.Forms.Label label4;
}
}
diff --git a/TestVideo/Form1.cs b/TestVideo/Form1.cs
index 9adb5e8..1b25412 100644
--- a/TestVideo/Form1.cs
+++ b/TestVideo/Form1.cs
@@ -18,15 +18,21 @@ namespace TestVideo
public partial class Form1 : Form
{
public Screen[] screens;
- Screen currentScreen;
List screenNames;
+ Extraction extraction;
+ int currentZoneIndex;
+
+ List zoneTypes;
+ bool creatingZone;
+ Point[] newZonePoints;
- Image displayedImage = null;
public Form1()
{
InitializeComponent();
screens = Screen.AllScreens;
- currentScreen = screens[0];
+ extraction = new Extraction(screens[0]);
+ currentZoneIndex = -1;
+
screenNames = new List();
foreach (Screen scr in screens)
{
@@ -34,150 +40,110 @@ namespace TestVideo
}
lsbScreens.DataSource = screenNames;
- //TESTING TESSERACT
-
- //string path = AppDomain.CurrentDomain.BaseDirectory + "Screens\\Baneer.png";
- //string path = AppDomain.CurrentDomain.BaseDirectory + "Screens\\Test.png";
- //string path = AppDomain.CurrentDomain.BaseDirectory + "Screens\\Standings.png";
- //string path = AppDomain.CurrentDomain.BaseDirectory + "Screens\\Gaps.png";
- //string path = AppDomain.CurrentDomain.BaseDirectory + "Screens\\SectorTimes.png";
- string path = AppDomain.CurrentDomain.BaseDirectory + "Screens\\Standings2.png";
-
- tbxResult.Text = DecodeTessereactResults(testTesseract((Bitmap)Image.FromFile(path)), Image.FromFile(path), pbxOutput);
- }
- private Bitmap PrepareImage(Bitmap inputImage)
- {
- for (int y = 0; y < inputImage.Height; y++)
+ zoneTypes = new List();
+ foreach (object type in Enum.GetValues(typeof(Zone.ZoneType)))
{
- for (int x = 0; x < inputImage.Width; x++)
- {
- //We will apply a filter to put the image first in grayScale
- //Then if the pixel is more white than black it will be fully white and same for black
-
- //Grayscale = 0.299R + 0.587G + 0.114B
- Color color = inputImage.GetPixel(x, y);
- int grayScaleValue = Convert.ToInt32(0.299 * (float)color.R + 0.587 * (float)color.G + 0.114 * (float)color.B);
- int finalValue = 0;
- if (grayScaleValue > 255 / 2)
- finalValue = 255;
- inputImage.SetPixel(x, y, Color.FromArgb(finalValue, finalValue, finalValue));
- }
+ zoneTypes.Add((Zone.ZoneType)type);
}
- //inputImage.Save("C:/TEST/test.png",ImageFormat.Png);
- return inputImage;
- }
- private string DecodeTessereactResults(string tesseractResult, Image inputImage, PictureBox resultPbx)
- {
- MessageBox.Show(tesseractResult);
- string result = "";
- string[] lettersData = tesseractResult.Split('\n');
- using (Graphics g = Graphics.FromImage(inputImage))
- {
- foreach (string letterData in lettersData)
- {
- string[] data = letterData.Split(' ');
- //This data is in a format that we cant process
- if (data.Length != 6)
- break;
-
- string letter = data[0];
- Point position = new Point(Convert.ToInt32(data[1]), Convert.ToInt32(data[2]));
- Size size = new Size(Convert.ToInt32(data[3]), Convert.ToInt32(data[4]));
- int unknownData = Convert.ToInt32(data[5]);
-
- //A neat post processing Idea would be to separate letters that have a unusually big difference in X or Y axis to try and recognise words
-
- //Use the data
- result += letter;
- g.DrawRectangle(new Pen(Brushes.Red, 5), new Rectangle(position, size));
- }
- }
-
- resultPbx.Image = inputImage;
-
- return result;
+ lsbZoneTypes.DataSource = zoneTypes;
+
+ newZonePoints = new Point[2] {new Point(-1,-1), new Point(-1,-1)};
}
+
private void btnStart_Click(object sender, EventArgs e)
{
if (tmrScreenshots.Enabled)
{
tmrScreenshots.Enabled = false;
- btnStart.Text = "Start";
+ btnStart.Text = "Start recording";
}
else
{
tmrScreenshots.Enabled = true;
- btnStart.Text = "Stop";
+ btnStart.Text = "Stop recording";
}
}
- private Bitmap ScreenShot()
- {
- Bitmap screenshot;
- screenshot = new Bitmap(currentScreen.Bounds.Width, currentScreen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
- // Create a graphics object from the bitmap
- Graphics gfxScreenshot = Graphics.FromImage(screenshot);
- // Take the screenshot from the upper left corner to the right bottom corner
- gfxScreenshot.CopyFromScreen(
- currentScreen.Bounds.X,
- currentScreen.Bounds.Y,
- 0,
- 0,
- currentScreen.Bounds.Size,
- CopyPixelOperation.SourceCopy);
- //testTesseract(screenshot);
- //SaveScreenshot(screenshot);
- MessageBox.Show(testTesseract(screenshot));
- return screenshot;
- }
- private string SaveScreenshot(Bitmap image)
+ public void RefreshUi()
{
- string path = "";
- string directory = AppDomain.CurrentDomain.BaseDirectory + "Screens";
- path = directory + "\\Screenshot" + DateTime.Now.ToString("yyyy_MM_dd-hh_mm_ss") + ".png";
- if (Directory.Exists(directory))
- {
- image.Save(path, ImageFormat.Png);
- }
- else
- {
- Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + "\\Screens");
- }
- return path;
- }
- //http://leonwoo-tech.blogspot.com/2018/06/tip-how-to-properly-setup-opencv-ocr-to.html
- private string testTesseract(Bitmap inputBmp)
- {
- string result = "";
- //To use this toImage you need : NuGet\Install-Package Emgu.CV.Bitmap -Version 4.5.5.4823
- inputBmp = PrepareImage(inputBmp);
- Image emguImage = inputBmp.ToImage();
-
- using (var image = emguImage)
- {
- using (Tesseract tesseractOcrProvider = new Tesseract(AppDomain.CurrentDomain.BaseDirectory + "\\Data", "eng", OcrEngineMode.Default))
- {
- tesseractOcrProvider.SetImage(image);
- tesseractOcrProvider.Recognize();
- result = tesseractOcrProvider.GetBoxText().TrimEnd();
- }
- }
- //File.Delete(filePath);
- return result;
+ lsbZones.DataSource = extraction.GetZonesNames();
+ extraction.DrawZones();
+ //extraction.UpdateZones();
+ pbxInput.Image = extraction.ScreenPreview;
}
+
+
private void tmrScreenshots_Tick(object sender, EventArgs e)
{
- //pbxInput.Image.Dispose();
- Image img = ScreenShot();
- pbxInput.Image = img;
+ extraction.UpdateZones();
+ pbxInput.Image = extraction.ScreenPreview;
+ if(currentZoneIndex != -1)
+ tbxResult.Text = extraction.GetZoneRawText(currentZoneIndex);
+ //This is to prevent Ram from exploding
GC.Collect();
- //img.Dispose();
}
private void lsbScreens_SelectedIndexChanged(object sender, EventArgs e)
{
- currentScreen = screens[lsbScreens.SelectedIndex];
+ extraction.ChangeScreen(screens[lsbScreens.SelectedIndex]);
+ pbxInput.Image = extraction.ScreenPreview;
}
+ private void pbxInput_Click(object sender, EventArgs e)
+ {
+ if (creatingZone)
+ {
+ //Convert coordinates to image coordinates
+ Rectangle screenSize = extraction.CurrentScreen.Bounds;
+ float xRatio = (float)screenSize.Width / (float)pbxInput.Width;
+ float yRatio = (float)screenSize.Height / (float)pbxInput.Height;
+ Point tmpPoint = pbxInput.PointToClient(MousePosition);
+ Point newPoint = new Point(Convert.ToInt32((float)tmpPoint.X * xRatio),Convert.ToInt32((float)tmpPoint.Y * yRatio));
+
+ if (newZonePoints[0] == new Point(-1,-1))
+ {
+ //Its the first point
+ newZonePoints[0] = newPoint;
+ btnCreateZone.Text = "Creating Zone 1/2 points selected";
+ }
+ else
+ {
+ //Its the second point
+ newZonePoints[1] = newPoint;
+ btnCreateZone.Text = "Create Zone";
+
+ Zone.ZoneType newZoneType = zoneTypes[lsbZoneTypes.SelectedIndex];
+ Random rnd = new Random();
+ Point p1 = newZonePoints[0];
+ Point p2 = newZonePoints[1];
+ Size newSize = new Size(Math.Max(p1.X,p2.X) - Math.Min(p1.X, p2.X),Math.Max(p1.Y,p2.Y) - Math.Min(p1.Y, p2.Y));
+ extraction.AddZone(new Rectangle(newZonePoints[0],newSize),newZoneType,"Coucou");
+
+ newZonePoints = new Point[2] { new Point(-1, -1), new Point(-1, -1) };
+ creatingZone = false;
+ RefreshUi();
+ }
+ }
+ }
+ private void btnCreateZone_Click(object sender, EventArgs e)
+ {
+ creatingZone = !creatingZone;
+ if (creatingZone)
+ {
+ btnCreateZone.Text = "Creating Zone 0/2 points selected";
+ }
+ else
+ {
+ btnCreateZone.Text = "Create Zone";
+ }
+ }
+
+ private void lsbZones_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (extraction.GetZonesNames().Any() && lsbZones.SelectedIndex >= 0)
+ {
+ currentZoneIndex = lsbZones.SelectedIndex;
+ }
+ }
}
}
diff --git a/TestVideo/TestVideo.csproj b/TestVideo/TestVideo.csproj
index fe2c034..3947705 100644
--- a/TestVideo/TestVideo.csproj
+++ b/TestVideo/TestVideo.csproj
@@ -67,6 +67,8 @@
+
+
Form
@@ -75,6 +77,7 @@
+
Form1.cs
diff --git a/TestVideo/Zone.cs b/TestVideo/Zone.cs
new file mode 100644
index 0000000..7796571
--- /dev/null
+++ b/TestVideo/Zone.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Drawing;
+using Emgu.CV.Structure;
+using Emgu.CV;
+using Emgu.CV.OCR;
+
+namespace TestVideo
+{
+ internal class Zone
+ {
+ [Flags]
+ public enum ZoneType { Standings, Gaps, LastLapPace }
+
+ private ZoneType _type;
+ private Rectangle _zoneArea;
+ private Bitmap _zoneData;
+ private string _rawText;
+ private string[] _cleanText;
+ private string _name;
+ private ZoneType Type { get => _type; set => _type = value; }
+ public Rectangle ZoneArea { get => _zoneArea; private set => _zoneArea = value; }
+ public Bitmap ZoneData { get => _zoneData; private set => _zoneData = value; }
+ public string RawText { get => _rawText; private set => _rawText = value; }
+ public string[] CleanText { get => _cleanText; private set => _cleanText = value; }
+ public string Name { get => _name; private set => _name = value; }
+
+ public Zone(Rectangle area, ZoneType type, string name)
+ {
+ ZoneArea = area;
+ Type = type;
+ Name = name;
+ }
+ public void Update(Bitmap data)
+ {
+ ZoneData = data;
+ RawText = GetRawText(ZoneData);
+ CleanText = GetCleanText(RawText);
+ }
+ //Original method : http://leonwoo-tech.blogspot.com/2018/06/tip-how-to-properly-setup-opencv-ocr-to.html
+ private string GetRawText(Bitmap inputBmp)
+ {
+ string result = "";
+
+ string tesseractResult = Tesseract(inputBmp);
+ string[] lettersData = tesseractResult.Split('\n');
+ using (Graphics g = Graphics.FromImage(inputBmp))
+ {
+ foreach (string letterData in lettersData)
+ {
+ string[] data = letterData.Split(' ');
+ //This data is in a format that we cant process
+ if (data.Length != 6)
+ break;
+
+ string letter = data[0];
+ Point position = new Point(Convert.ToInt32(data[1]), Convert.ToInt32(data[2]));
+ Size size = new Size(Convert.ToInt32(data[3]), Convert.ToInt32(data[4]));
+ int unknownData = Convert.ToInt32(data[5]);
+
+ //A neat post processing Idea would be to separate letters that have a unusually big difference in X or Y axis to try and recognise words
+
+ //Use the data
+ result += letter;
+ g.DrawRectangle(new Pen(Brushes.Red, 5), new Rectangle(position, size));
+ }
+ }
+
+ return result;
+ }
+ private string[] GetCleanText(string rawText)
+ {
+ //TODO
+
+ return new string[] { rawText };
+ }
+
+ private string Tesseract(Bitmap inputBmp)
+ {
+ string result = "";
+ //To use this toImage you need : NuGet\Install-Package Emgu.CV.Bitmap -Version 4.5.5.4823
+ inputBmp = PrepareImage(inputBmp);
+ Image emguImage = inputBmp.ToImage();
+
+ using (var image = emguImage)
+ {
+ using (Tesseract tesseractOcrProvider = new Tesseract(AppDomain.CurrentDomain.BaseDirectory + "\\Data", "eng", OcrEngineMode.Default))
+ {
+ tesseractOcrProvider.SetImage(image);
+ tesseractOcrProvider.Recognize();
+ result = tesseractOcrProvider.GetBoxText().TrimEnd();
+ }
+ }
+ return result;
+ }
+ private Bitmap PrepareImage(Bitmap inputImage)
+ {
+ for (int y = 0; y < inputImage.Height; y++)
+ {
+ for (int x = 0; x < inputImage.Width; x++)
+ {
+ //We transform the RGB image into a Grayscale one
+ //Grayscale = 0.299R + 0.587G + 0.114B
+ Color color = inputImage.GetPixel(x, y);
+ int grayScaleValue = Convert.ToInt32(0.299 * (float)color.R + 0.587 * (float)color.G + 0.114 * (float)color.B);
+ int finalValue = 0;
+ //Then we make it boolean, either black or white
+ if (grayScaleValue > 255 / 2)
+ finalValue = 255;
+ inputImage.SetPixel(x, y, Color.FromArgb(finalValue, finalValue, finalValue));
+ }
+ }
+ //inputImage.Save("C:/TEST/test.png",ImageFormat.Png);
+ return inputImage;
+ }
+ }
+}