126 lines
5.1 KiB
C#
126 lines
5.1 KiB
C#
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]));
|
|
Point position = new Point(Convert.ToInt32(data[1]), Convert.ToInt32(data[2]));
|
|
Size size = new Size(Convert.ToInt32(data[3]) - Convert.ToInt32(data[1]), Convert.ToInt32(data[4]) - Convert.ToInt32(data[2]));
|
|
Point correctedPosition = new Point(position.X, inputBmp.Height - position.Y - size.Height);
|
|
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));
|
|
g.DrawRectangle(new Pen(Brushes.Red, 3), new Rectangle(correctedPosition, 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);
|
|
ZoneData = inputBmp;
|
|
Image<Bgr, byte> emguImage = inputBmp.ToImage<Bgr, byte>();
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|