Updated doc

This commit is contained in:
2023-04-10 13:14:45 +02:00
parent aafdffceb5
commit dabdef0f0f
+162
View File
@@ -1256,3 +1256,165 @@ J'ai donc pu retirer le round autour du chiffre et cela m'a permit de pouvoir d
!["Super M"](./Images/Screens/RecognisedM.png) !["Super M"](./Images/Screens/RecognisedM.png)
Maintenant je pense qu'il ne reste "plus qu'à" nettoyer un peu tout ce code qui traine de partout pour tout faire fonctionner et implémenter un peu de parrallel processing ainsi que de l'asynchrone pour ne pas bloquer le reste du programme. Maintenant je pense qu'il ne reste "plus qu'à" nettoyer un peu tout ce code qui traine de partout pour tout faire fonctionner et implémenter un peu de parrallel processing ainsi que de l'asynchrone pour ne pas bloquer le reste du programme.
Par ce qu'il faut savoir que en l'étât, le programme met 25 secondes à démarrer et consomme presque 2GB de Ram. Certes cela ne veut pas dire que la reconnaissance à elle seule prend 25 secondes car au démarrage il y a aussi la lecture du fichier de config et la création des window etc..
En réalité la partie strictement OCR prend dans les 12s si on en croit la fonction stopWatch de C#.
Et quand on change d'image la reconnaissance prend 9s.
Dans tout les cas c'est BEAUCOUP trop.
J'aurais eu comme objectif de faire une reconnaissance toutes les secondes. Je ne sais pas bien si cela va être possible mais en tout cas le but va être de s'en rapprocher.
Pour être plus exact et permettre une comparaison, voici les stats exactes
Avec un fichier d'images vide :
- Loading - 11.8s
- Splitting d'images - 90ms
- OCR - 12.5s
Avec un fichier d'images plein :
- Loading - 10.8s
- Splitting d'images - 80ms
- Ocr - 11.6s
En passant d'une image à l'autre :
- Loading - NaN
- Splitting d'images - 50ms
- Ocr - 8.8s
Donc on peut voir que les deux endroits ou le programme prend le plus de temps c'est au premier démarrage quand il faut lire le fichier et setup les windows etc...
Et l'OCR qui prend un temps fou.
Ce qui est pratique c'est que les presque 2gb de ram sont utilisés que au lancement et ensuite l'application n'en utilise que quelques centaines de mb.
Le processeur lui tourne entre 10 et 20% ce qui ne va pas durer :)
Je vais m'occuper dabord du loading.
J'ai essayé d'utiliser un Parrallel.For au moment de la création des windows, le problème c'est que visiblement les objets windows sont beaucoup trops complexes et utilisent trop de ressources partagées pour être vraiment thread Safe. J'éspère que je n'aurais pas trop de soucis avec ca qu'en j'en viendrai à l'optimisation de l'OCR...
Ce qui me rend fou c'est que cette boucle toute nulle prend plus de dix secondes à s'executer et je ne comprend pas bien pourquoi.
```Csharp
for (int i = 0; i < NUMBER_OF_DRIVERS; i++)
{
Point tmpPos = new Point(0, FirstZonePosition.Y + i * FirstZoneSize.Height - Convert.ToInt32(i * offset) /*- (i* (FirstZoneSize.Height / 32))*/);
Zone newDriverZone = new Zone(MainZoneImage, new Rectangle(tmpPos, FirstZoneSize));
Bitmap zoneImg = newDriverZone.ZoneImage;
newDriverZone.AddWindow(new DriverPositionWindow(zoneImg, new Rectangle(driverPositionPosition, driverPositionArea)));
newDriverZone.AddWindow(new DriverGapToLeaderWindow(zoneImg, new Rectangle(driverGapToLeaderPosition, driverGapToLeaderArea)));
newDriverZone.AddWindow(new DriverLapTimeWindow(zoneImg, new Rectangle(driverLapTimePosition, driverLapTimeArea)));
newDriverZone.AddWindow(new DriverDrsWindow(zoneImg, new Rectangle(driverDrsPosition, driverDrsArea)));
newDriverZone.AddWindow(new DriverTyresWindow(zoneImg, new Rectangle(driverTyresPosition, driverTyresArea)));
newDriverZone.AddWindow(new DriverNameWindow(zoneImg, new Rectangle(driverNamePosition, driverNameArea)));
newDriverZone.AddWindow(new DriverSector1Window(zoneImg, new Rectangle(driverSector1Position, driverSector1Area)));
newDriverZone.AddWindow(new DriverSector2Window(zoneImg, new Rectangle(driverSector2Position, driverSector2Area)));
newDriverZone.AddWindow(new DriverSector3Window(zoneImg, new Rectangle(driverSector3Position, driverSector3Area)));
MainZone.AddZone(newDriverZone);
}
```
Alors que Zone.AddWindow c'est simplement :
```Csharp
public virtual void AddWindow(Window window)
{
Windows.Add(window);
}
```
Et windows est simplement une liste. Donc ca ne peut pas être ca qui prend du temps.
Et les windows que je créé ont ca comme code :
```Csharp
public DriverPositionWindow(Bitmap image, Rectangle bounds) : base(image, bounds)
{
Name = "Position";
}
```
Sachant que le constructeur de base d'une Window c'est :
```Csharp
public Window(Bitmap image, Rectangle bounds)
{
Image = image;
Bounds = bounds;
Engine = new TesseractEngine(TESS_DATA_FOLDER.FullName, "eng", EngineMode.Default);
Engine.DefaultPageSegMode = PageSegMode.SingleLine;
}
```
Sachant que TesseractEngine est en statique et que donc il ne devrait... OHLLALALALALALALALALA je suis un imbécile...
J'ai juste à changer ce constructeur avec ca:
```Csharp
if (Engine == null)
{
Engine = new TesseractEngine(TESS_DATA_FOLDER.FullName, "eng", EngineMode.Default);
Engine.DefaultPageSegMode = PageSegMode.SingleLine;
}
```
ET le loading ne prend plus que 2-300 ms...
Bon c'est une très belle amélioration pour pas très chèr mais bon c'est un peu bête...
Bon je pense que 2-300ms c'est une durée correcte surtout que ca n'est appelé qu'une fois pour le lancement. On peut passer à la suite maintenant.
Alors il y a un grand soucis avec la parallellisation de l'OCR... Tesseract n'est pas par défaut une classe "Thread safe" ce qui veut dire que je ne peut utiliser de parallell.Foreach sur mes windows pour accèlèrer le traitement drastiquement.
Je pourrais par exemple avoir une instance de Tesseract par window sauf que cela fait 20 pilotes * 9 windows chacuns ce qui donne 180 instances ce qui n'est tout simplement pas raisonnable.
Je vais donc essayer de voir avec l'utilisation de methodes asynchrones qui me permettraient de faire un genre de flux tendu de reconnaissance. J'avoue que la je navigue un peu à vue, je me base sur différentes infos que je trouve sur des sites un peu perdus et sur chatGPT, j'espère que j'arriverai à trouver une solution car 10 secondes de reconnaissance c'est vraiment beaucoup trop.
Alors le soucis avec un Engine unique entre toutes les windows c'est qu'il n'est pas possible de process plusieurs images à la fois.
Je vais donc retirer l'engine unique pour voir si en créer un par window me permet de passer en multithreading.
La grande question sera : Est-ce que les ressources supplémentaires que vont prendre la création de tous ces engines va compenser entièrement le temps gagné avec la paralellisation.
Pour stocker les données dans un premier temps je vais créer un objet DriverData. Ce qu'il y a de pratique avec ca, c'est que je pourrais ajouter du code de vérification de certaines données directement dedans avant de les donner à la suite du programme.
Et on peut même imaginer une implémentation d'une liste de DriverData pour avoir l'historique.
Ce qui serait cool ca serait de grouper toutes ces data avec un numéro de tour. Placer ensuite la liste de Data dans une DB serait ainsi super simple. Mais il va falloir savoir quoi mettre, quelles infos sont redondantes et prendre en compte le fait que un tour affiché sur la page de la F1TV n'est accompli que par certains des premiers pilotes. D'autres pilotes peuvent être dans des tours précédents si ils ont du retard.
Il faudra réfléchir à cela quand je viendrai au modèle.
Bon pour y arriver j'ai du faire de gros changements et le résultat n'est peut-être pas aussi cool que ce que j'aurais voulut...
Voici un petit point sur les performances maintenant
J'ai également désactivé le dump d'images.
Pour le moment j'ai tout mis en commentaire mais cela pourrait être intéressant de faire en sorte de pouvoir l'activer en changeant une ou deux variables
Au démarrage :
- Loading - 113ms
- Splitting d'images - 14ms
- Ocr - 7s
En passant d'une image à l'autre :
- Loading - 113ms
- Splitting d'images - 13ms
- Ocr - 5s
Alors clairement les stats montrent qu'il y a eu un changement mesurable mais bon je pensais pouvoir en gagner un peu plus...
Je soupconne la création d'engines d'être à l'origine de ces performances presque décevantes.
Autre soucis, il semble que plus je change d'image plus la detection est lente et plus je consomme de RAM.
Il va falloir que je travaille encore un peu.