diff --git a/ReadMe.md b/ReadMe.md index 7273529..8e82080 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -24,4 +24,6 @@ Voici les liens Git vers les autres sous projets [Sandbox OCR](https://gitea.parano.ch/Maxluli/Test_OCR) -[Tests OCR](https://gitea.parano.ch/Maxluli/OCR_TEST) \ No newline at end of file +[Tests OCR](https://gitea.parano.ch/Maxluli/OCR_TEST) + +[Decode OCR](https://gitea.parano.ch/Maxluli/OCR_Decode) \ No newline at end of file diff --git a/docs/Images/Screens/CenteredDriver.png b/docs/Images/Screens/CenteredDriver.png new file mode 100644 index 0000000..120361f Binary files /dev/null and b/docs/Images/Screens/CenteredDriver.png differ diff --git a/docs/Images/Screens/ImageDecoding1.png b/docs/Images/Screens/ImageDecoding1.png new file mode 100644 index 0000000..d1710f3 Binary files /dev/null and b/docs/Images/Screens/ImageDecoding1.png differ diff --git a/docs/Images/Screens/JsonDecodeResult.png b/docs/Images/Screens/JsonDecodeResult.png new file mode 100644 index 0000000..7a1b0e1 Binary files /dev/null and b/docs/Images/Screens/JsonDecodeResult.png differ diff --git a/docs/Images/Screens/UncenteredDriver.png b/docs/Images/Screens/UncenteredDriver.png new file mode 100644 index 0000000..230f515 Binary files /dev/null and b/docs/Images/Screens/UncenteredDriver.png differ diff --git a/docs/Images/Screens/VerstappenFolder2.png b/docs/Images/Screens/VerstappenFolder2.png new file mode 100644 index 0000000..a8723b8 Binary files /dev/null and b/docs/Images/Screens/VerstappenFolder2.png differ diff --git a/docs/jdb.md b/docs/jdb.md index c392620..345f3d3 100644 --- a/docs/jdb.md +++ b/docs/jdb.md @@ -280,7 +280,7 @@ Maintenant avec un temps au tour : !["Reconnaissance du timing au tour"](./Images/Screens/TimingRecognition2.png) -On arrive sans rien changer aux paramêtres à isoler minutes secondes et milisecondes. +On arrive sans rien changer aux paramêtres à isoler minutes secondes et milisecondes. Il semble que la reconnaissance de chiffre soit bien plus efficace que la reconnaissance de lettres. Il va falloir faire un test à plus grande échelle avec plus d'image pour se rendre compte de la precision. @@ -308,7 +308,7 @@ J'ai essayé de découper l'image pour que cela soit plus clair : Ici on peut voir que l'image est découpée en plusieurs grandes zones. Dans un premier temps on ne s'occupe que de la première. -Ensuite : +Ensuite : !["Driver zone #1"](./Images/Figma/WindowZoneExplanation2.png) @@ -773,3 +773,177 @@ Maintenant je vais m'attaquer au décodage. Demain je dois finir le décodage du JSON et je dois commencer à implémenter la reconnaissance des textes. Voire même des pneus etc si j'y arrive. +## Mercredi 5 Avril + +Bon la il faut vraiment que je finisse assez vite la lecture du JSON et la reconstruction des zones pour commencer la reconnaissance. + +J'ai pris beaucoup de temps à faire le programme de calibration mais je pense que c'est essentiel de prendre ce temps maintenant. (BTW il faudra quand même retourner faire une plus jolie version par ce que la ca marche mais c'est tout) + +Bon après pas mal de boulot je pense avoir réussi. Dans le nouveau programme on arrive à récupèrer les différentes zones : + +!["JSON decode result"](./Images/Screens/JsonDecodeResult.png) + +Un conseil de notre professeur M.Bonvin a été de créer des Releases de versions qui ne fonctionnent pas ou pas très bien. J'ai donc publié une première release de l'OCR_TEST qui fonctionne vite fait. + +J'ai seulement un petit soucis, comme je recrée complêtement la structure des driver zones avec seulement la première, il y a un petit décalage car entre les zones il y avait un gap. + +Ce qui fait que si la première zone est parfaitement centrée : + +!["Centered driver"](./Images/Screens/CenteredDriver.png) + +La vingtième ne l'est plus exactement : + +!["Uncentered Driver"](./Images/Screens/UncenteredDriver.png) + +Pour ca j'ai essayé de mettre un espacement arbitraire mais c'est complexe. Je vais plutôt tenter de faire une différence entre la taille de la zone complête et de la taille additionnée de toutes les fenêtre et diviser le resultat entre toutes les fenêtres. + +Ca n'est pas parfait mais au moins maintenant les données ne touchent plus les bords de la fenêtre. + +Et voila ! + +Maintenant avec le fichier de configuration en Json on arrive à récupèrer toutes les infos comme si elles avaient été envoyées directement depuis l'app de calibration mais sans le processing time ! + +!["Verstappen folder 2](./Images/Screens/VerstappenFolder2.png) + +On peut donc ENFIN passer au décodage de ces FICHUES données. + +Je vais pouvoir implémenter ce que j'ai fait dans le projet de test de décodage. + +Grâce à mon découpage initial qui m'a pris du temps à implémenter on a enfin un truc qui marche même si je n'ai implémenté que la reconnaissance de noms. + +!["Image reconnaissance propre"](./Images/Screens/ImageDecoding1.png) + +Si on se rappelle du système de window et de zones dans le diagramme plus haut, c'est assez facile de comprendre comment je m'y suis pris. + +En gros on des listes et des listes de listes de zones, c'est la partie un peu plus technique car il y a des zones qui peuvent contenir d'autres zones etc. + +Je vais commencer par la reconnaissance de noms. + +Voici le tableau de pilotes de 2023 + +```JSON +"Drivers": [ + "Leclerc", + "Verstappen", + "Hamilton", + "Alonso", + "Russel", + "Gasly", + "Stroll", + "Sainz", + "Hulkenberg", + "Norris", + "Tsunoda", + "Piastri", + "Zhou", + "Ocon", + "Magnussen", + "Perez", + "Sargeant", + "De Vries", + "Bottas", + "Albon" + ] +``` + +ET voici le tableau de pilotes de 2022 : + +```Json +"Drivers": [ + "Leclerc", + "Verstappen", + "Sainz", + "Perez", + "Hamilton", + "Russel", + "Magnussen", + "Gasly", + "Ocon", + "Alonso", + "Tsunoda", + "Bottas", + "Zhou", + "Albon", + "Stroll", + "Schumacher", + "Hulkenberg", + "Norris", + "Latifi", + "Ricciardo" + ] +``` + +Je les notes ici car J'ai souvent besoin de changer selon le dataset que j'utilise. + +Dans le futur je ferai sûrement un grand dataset qui prend des pilotes de reserves et des pilotes juniors pour que dans le cas ou un pilote est remplacé dans l'année il n'y a pas besoin de tout recalibrer avec l'application. + +Après une discussion avec M.Bonvin j'ai décidé de tester 3 valeurs de convertion en noir et blanc et si je ne trouve pas un match exact je prend le nom le plus proche. + +Pour trouver la string la plus proche je pense que je vais utiliser quelque chose qui s'appelle la technique de Levenshtein. De ce que j'ai compris c'est un algorythme qui permet de donner une metric de différence entre deux strings. + +Bon et évidemment il ne faut pas se tromper dans la liste des pilotes GENRE NE PAS OUBLIER QUE GEORGE RUSSELL COMPORTE DEUX WFNEWIEWV DE "L" A LA FIN DE SON NOM CE QUI POURRAIT ENGRANGER 2H DE DEBUGGING POUR RIEN ASK ME HOW I KNOW *joker laugh* + +J'ai vraiment un soucis avec Tsunoda, Il a trop tendeance à le confondre avec "TSUNDDA" et pour des raisons obscures, quand j'applique l'algorythme de Levenshtein le plus proche n'est pas "Tsunoda" mais "Sainz" iniuvbwdiucbiubisc POURQUOI !!??!! + +Je pense que cela demande moins de changements de lettres enfin bon c'est quand même pas idéal. Il va falloir que je trouve un moyen de le repondérer. C'est dommage par ce que cela marche super avec Alonso Verstappen et Albon. + +J'ai un peu modifié la methode et j'ai fait en sorte d'envoyer tous les noms en majuscules en me disant que cela pourrait réduire le nombre de changements. Et ca a marché !! Cela va sûrement demander plus de tests pour être bien sûr que tout fonctionne nikel, cependant pour le moment ca marche parfaitement avec les pilotes de 2022. + +Pour ce qui est de la reconnaissance de chiffres, j'ai déja fait une partie du boulot le premier jour alors je vais juste reprendre à partir de là. + +Je récupère une string de ce type "1:35.123" le soucis c'est que les : se transforment parfois en . ou inversement mais bon ca devrait pas être trop dur à gèrer. + +Il faut que je transforme cette string en nombre de milisecondes (Du moins je pense que c'est le meilleur moyen pour ensuite pouvoir facilement comparer et stocker l'information). + +Cela fait que 1:35:123 en milisecondes donne : + +- 1 * 1000 * 60 => 60'000 +- 35 * 1000 => 35'000 +- 123 => 123 + +Total : 60'000+35'000+123 => 95'123ms + +Et pour l'affichage : + +- Minutes = ms / 60'000 +- secondes = (ms - (minutes/60'000))/1000 +- ms = ms - ((minutes 60'000) + (secondes * 1000)) + +Et on se retrouve avec 1:35:123 + +Maintenant après un peu de temps pour nettoyer la string etc on se retrouve avec un résultat comme le suivant : + +```Text +Position : 0 +Gap to leader : 0:0:0 +Lap time : 2:15:123 +DRS : False +Tyre : Undefined laps with the tyre : 0 +Driver name : LECLERC +Sector 1 : 0:31:323 +Sector 2 : 0:42:340 +Sector 3 : 0:0:0 +``` + +Evidemment pareil pour les autres pilotes +Et je me rend compte que j'ai encore tout cassé car le laptime ne devrait pas être 2:15 mais 1:35... + +Voila après une heure de debugging et des ajouts pour nettoyer les chaines on se retrouve avec : + +```Text +Position : 0 +Gap to leader : 0:0:0 +Lap time : 1:35:123 +DRS : False +Tyre : Undefined laps with the tyre : 0 +Driver name : LECLERC +Sector 1 : 0:31:323 +Sector 2 : 0:42:340 +Sector 3 : 0:0:0 +``` + +Note: le traitement commence à devenir long, il serait peut-être intéressant d'utiliser un seul Tesseract Engine ou de voir ce qui prend autant de temps, on dépasse la seconde de traitement ce qui est un peu ma limite. + +Après on peut toujours tester de rajouter du multicore processing mais c'est pour une autre fois. + +Demain je m'occupe de règler les soucis que j'ai avec la prescision de ces temps au tour et j'éspère pouvoir m'occuper aussi de la position des pneus et du DRS. J'aimerais finir tout ca cette semaine.