Files
TrackTrendsDoc/temp_annexes/Code/ConfigurationTool.md
T
2023-05-11 15:55:47 +02:00

8.1 KiB

ConfigurationTool.cs

/// Author : Maxime Rohmer
/// Date : 08/05/2023
/// File : ConfigurationTool.cs
/// Brief : Class that contains all the methods needed to create a config file for the OCR
/// Version : 0.1

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tesseract;
using System.IO;

namespace Test_Merge
{
    public class ConfigurationTool
    {
        public Zone MainZone;
        public const int NUMBER_OF_DRIVERS = 20;
        public const int NUMBER_OF_ZONES = 9;
        public const string CONFIGS_FOLDER_NAME = "./Presets/";

        public ConfigurationTool(Bitmap fullImage, Rectangle mainZoneDimensions)
        {
            MainZone = new Zone(fullImage, mainZoneDimensions,"Main");
            AutoCalibrate();
        }
        public void ResetMainZone()
        {
            MainZone.ResetZones();
        }
        public void ResetWindows()
        {
            MainZone.ResetWindows();
        }
        public void SaveToJson(List<string> drivers, string configName)
        {
            string JSON = "";

            JSON += "{" + Environment.NewLine;
            JSON += MainZone.ToJSON() + "," + Environment.NewLine;
            JSON += "\"Drivers\":[" + Environment.NewLine;

            for (int i = 0; i < drivers.Count; i++)
            {
                JSON += "\"" + drivers[i] + "\"";
                if (i < drivers.Count - 1)
                    JSON += ",";
                JSON += Environment.NewLine;
            }

            JSON += "]" + Environment.NewLine;

            JSON += "}";

            if (!Directory.Exists(CONFIGS_FOLDER_NAME))
                Directory.CreateDirectory(CONFIGS_FOLDER_NAME);

            string path = CONFIGS_FOLDER_NAME + configName;

            if (File.Exists(path + ".json"))
            {
                //We need to create a new name
                int count = 2;
                while (File.Exists(path + "_" + count + ".json"))
                {
                    count++;
                }
                path += "_" + count + ".json";
            }
            else
            {
                path += ".json";
            }

            File.WriteAllText(path, JSON);
        }
        public void AddWindows(List<Rectangle> rectangles)
        {
            foreach (Zone driverZone in MainZone.Zones)
            {
                Bitmap zoneImage = driverZone.ZoneImage;

                for (int i = 1; i <= rectangles.Count; i++)
                {
                    switch (i)
                    {
                        case 1:
                            //First zone should be the driver's Position
                            driverZone.AddWindow(new DriverPositionWindow(driverZone.ZoneImage, rectangles[i - 1], false));
                            break;
                        case 2:
                            //First zone should be the Gap to leader
                            driverZone.AddWindow(new DriverGapToLeaderWindow(driverZone.ZoneImage, rectangles[i - 1], false));
                            break;
                        case 3:
                            //First zone should be the driver's Lap Time
                            driverZone.AddWindow(new DriverLapTimeWindow(driverZone.ZoneImage, rectangles[i - 1], false));
                            break;
                        case 4:
                            //First zone should be the driver's DRS status
                            driverZone.AddWindow(new DriverDrsWindow(driverZone.ZoneImage, rectangles[i - 1], false));
                            break;
                        case 5:
                            //First zone should be the driver's Tyre's informations
                            driverZone.AddWindow(new DriverTyresWindow(driverZone.ZoneImage, rectangles[i - 1], false));
                            break;
                        case 6:
                            //First zone should be the driver's Name
                            driverZone.AddWindow(new DriverNameWindow(driverZone.ZoneImage, rectangles[i - 1], false));
                            break;
                        case 7:
                            //First zone should be the driver's First Sector
                            driverZone.AddWindow(new DriverSectorWindow(driverZone.ZoneImage, rectangles[i - 1], 1, false));
                            break;
                        case 8:
                            //First zone should be the driver's Second Sector
                            driverZone.AddWindow(new DriverSectorWindow(driverZone.ZoneImage, rectangles[i - 1], 2, false));
                            break;
                        case 9:
                            //First zone should be the driver's Position Sector
                            driverZone.AddWindow(new DriverSectorWindow(driverZone.ZoneImage, rectangles[i - 1], 3, false));
                            break;
                    }
                }
            }
        }
        public void AutoCalibrate()
        {
            List<Rectangle> detectedText = new List<Rectangle>();
            List<Zone> zones = new List<Zone>();

            TesseractEngine engine = new TesseractEngine(Window.TESS_DATA_FOLDER.FullName, "eng", EngineMode.Default);
            Image image = MainZone.ZoneImage;
            var tessImage = Pix.LoadFromMemory(Window.ImageToByte(image));

            Page page = engine.Process(tessImage);
            using (var iter = page.GetIterator())
            {
                iter.Begin();
                do
                {
                    Rect boundingBox;
                    if (iter.TryGetBoundingBox(PageIteratorLevel.Word, out boundingBox))
                    {
                        //var text = iter.GetText(PageIteratorLevel.Word).ToUpper();
                        //We remove all the rectangles that are definitely too big
                        if (boundingBox.Height < image.Height / NUMBER_OF_DRIVERS)
                        {
                            //Now we add a filter to only get the boxes in the right because they are much more reliable in size
                            if (boundingBox.X1 > image.Width / 2)
                            {
                                //Now we check if an other square box has been found roughly in the same y axis
                                bool match = false;
                                //The tolerance is roughly half the size that a window will be
                                int tolerance = (image.Height / NUMBER_OF_DRIVERS) / 2;

                                foreach (Rectangle rect in detectedText)
                                {
                                    if (rect.Y > boundingBox.Y1 - tolerance && rect.Y < boundingBox.Y1 + tolerance)
                                    {
                                        //There already is a rectangle in this line
                                        match = true;
                                    }
                                }
                                //if nothing matched we can add it
                                if (!match)
                                    detectedText.Add(new Rectangle(boundingBox.X1, boundingBox.Y1, boundingBox.Width, boundingBox.Height));
                            }
                        }
                    }
                } while (iter.Next(PageIteratorLevel.Word));
            }
            //DEBUG
            int i = 1;
            foreach (Rectangle Rectangle in detectedText)
            {
                Rectangle windowRectangle;
                Size windowSize = new Size(image.Width, image.Height / NUMBER_OF_DRIVERS);
                Point windowLocation = new Point(0, (Rectangle.Y + Rectangle.Height / 2) - windowSize.Height / 2);
                windowRectangle = new Rectangle(windowLocation, windowSize);
                //We add the driver zones
                Zone driverZone = new Zone(MainZone.ZoneImage, windowRectangle, "DriverZone");
                MainZone.AddZone(driverZone);

                driverZone.ZoneImage.Save("Driver" + i+".png");
                i++;
            }
        }
    }
}