Added a lot to main doc
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 586 B |
|
After Width: | Height: | Size: 616 B |
|
After Width: | Height: | Size: 643 B |
|
After Width: | Height: | Size: 616 B |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 817 B |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 562 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 947 B |
|
After Width: | Height: | Size: 930 B |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 446 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 491 B |
|
After Width: | Height: | Size: 719 KiB |
@@ -0,0 +1,3 @@
|
||||
[ZoneTransfer]
|
||||
LastWriterPackageFamilyName=Microsoft.Windows.Photos_8wekyb3d8bbwe
|
||||
ZoneId=3
|
||||
@@ -335,13 +335,15 @@ J'ai mis une durée arbitraire de deux jours, mais je ne sais pas vraiment combi
|
||||
|
||||
[A remplir au fur et à mesure que les features sont développées]
|
||||
|
||||
### Récupération des images
|
||||
|
||||
### OCR
|
||||
|
||||
Ici je vais parler du processus de reconnaissance de data sur une image du feed DATA de la F1TV.
|
||||
|
||||
C'est je pense la partie qui a demandé le plus tests et de refactor.
|
||||
|
||||
Toute la partie OCR a été développée dans un projet à part avant d'être intègrée dans le projet final.
|
||||
Toute la partie OCR a été développée dans un projet à part avant d'être intégrée dans le projet final.
|
||||
|
||||
Il faut savoir que la reconnaissance est différente celon ce que l'on cherche. Je vais donc décomposer cette partie du document en sous rubriques selon les données recherchées.
|
||||
|
||||
@@ -362,7 +364,7 @@ Dans l'exemple ci dessus on peut voir 3 zones mais on aurait également pu compr
|
||||
|
||||
Ces 4 zones sont très différentes et contiennent d'autres informations. Pour ce travail de diplôme je ne m'occupe que de la zone principale. Mais je pense que le titre et les infos de circuit ne prendrait pas tant de temps que ca à implémenter.
|
||||
|
||||
J'ai utilisé le mot "Zone" plus haut et ca n'est pas juste un mot en l'air. C'est le nom de l'objet que j'utilise pour les représenter dans mon programme. Mais comme c'est important de bien comprendre ce concept avant de continuer je vais vous l'expliquer.
|
||||
J'ai utilisé le mot "Zone" plus haut et ca n'est pas juste un mot utilisé au hasard. C'est le nom de l'objet que j'utilise pour les représenter dans mon programme. Mais comme c'est important de bien comprendre ce concept avant de continuer je vais vous l'expliquer.
|
||||
|
||||
ZONE :
|
||||
|
||||
@@ -403,17 +405,204 @@ Pour visualiser encore un peu mieux comment ce découpage prend forme voici ce q
|
||||
|
||||
Main Zone :
|
||||
|
||||

|
||||
|
||||
Driver Zone :
|
||||
|
||||

|
||||
|
||||
Driver Position Window :
|
||||
|
||||
Driver Name Name Window :
|
||||

|
||||
|
||||
Driver name Window :
|
||||
|
||||

|
||||
|
||||
Driver LapTime Window :
|
||||
|
||||

|
||||
|
||||
Driver Tyre Window :
|
||||
|
||||
### Récupération des images
|
||||

|
||||
|
||||
Il existe d'autres types de Window mais ce sont les principaux.
|
||||
|
||||
On se rend assez facilement compte que chacunes de ces windows va avoir besoin d'un traitement spécifique car la manière de reconnaitre le pneu utilisé et le temps au tour ne peut pas être la même.
|
||||
|
||||
Pour résumer, on a un programme qui prend en entrée un fichier de configuration, qui prend des images de la F1TV et les découpe dans des ZONES qui elles même sont découpées en WINDOWS pour qu'on puisse plus facilement les décoder.
|
||||
|
||||
Maintenant qu'on a une liste de différent types de zones on peut commencer à chercher ce qu'il y a marqué dessus.
|
||||
|
||||
Pour cela il faut dabord comprendre un petit peu comment l'OCR fonctionne et comment des libraries comme Tesseract fonctionnent pour donner du texte en partant d'une image.
|
||||
|
||||
Pour faire très simple, nous avons un modèle qui est entrainé. C'est à dire que on donne à un programme un très grand nombre de mots ou de lettres en lui disant ce que contiennent chaques images. Ensuite le programme va créer des matrices de convolutions pour chaque lettre avec comme objectif de detecter les points communs entre les lettres pour créer un alpphabet.
|
||||
|
||||
Par exemple la matric de la lettre 'H' donnerait un poids important à des lignes verticales connectées par une ligne centrale. Et si on fournis assez de données de bonne qualité au modèle, les matrices peuvent être très efficace à detecter si une lettre est un H ou un M.
|
||||
|
||||
Il y a pleins d'autres methodes comme l'utilisation d'un dictionnaire de mots de la langue pour permettre la reconnaissance de mots même si une lettre au milieu n'est pas comprise ou en ajoutant d'autres informations sur le contexte mais ca ne nous intéresse pas ici.
|
||||
|
||||
C'est important de comprendre comment cette reconnaissance de caractères avec des matrices fonctionne car cela va nous aider à préparer nos données pour lui rendre la vie facile et augmenter la précision de nos résultats.
|
||||
|
||||
##### Filtres et traitement
|
||||
|
||||
On peut essayer de donner toutes nos images directement à Tesseract pour qu'il reconnaisse tout le texte qu'il y voit mais on risque de se retrouver avec des résultats au mieux inconsistents.
|
||||
|
||||
Dans notre cas, le soucis est que les chiffres et lettres sont beaucoup trop petits. Ils ne font parfoisd que 10 pixels de haut et cela fait que il n'est pas forcément facile de toujours les différencier. De plus, comme ils sont petits, les artéfacts d'aliasing sont assez violents et peuvent grandement déformer une lettre ou un chiffre.
|
||||
|
||||
Exemple :
|
||||
|
||||
Prenons le chiffre 9. Dans l'image il peut être représenté de cette manière :
|
||||
|
||||

|
||||
|
||||
On peut voir qu'il est flou, pour nous cela ne pose pas de problème et je pense que à peu près nimporte qui peut dire que c'est un 9.
|
||||
|
||||
Cependant comme les contours sont flous et même si on essaie de retirer le background :
|
||||
|
||||

|
||||
|
||||
On voit que le 9 n'est pas clairement définit. En effet on pourrait le comprendre comme :
|
||||
|
||||

|
||||
|
||||
Ou comme :
|
||||
|
||||

|
||||
|
||||
Voire même simplement comme :
|
||||
|
||||

|
||||
|
||||
Et on se rend bien compte que les performances de detection ne sont pas les mêmes dans ces trois cas.
|
||||
|
||||
Il faut donc faire un certain post traitement des images pour supprimer les éléments parasites, les couleurs, et augmenter la visibilité des contours importants.
|
||||
|
||||
Mais chaque type de donnée va avoir des methodes de post traitement différents.
|
||||
|
||||
Donc voici les différents types de reconnaissance et leur post traitements :
|
||||
|
||||
TEXTE :
|
||||
|
||||
Alors ce type de reconnaissance est utilisé par la WINDOW du nom de pilote et de la position du pilote.
|
||||
|
||||
C'est je pense la plus simple de toutes car Tesseract est particulièrement bien entrainé pour.
|
||||
|
||||
Cette reconnaissance concerne donc des lettres qui font des mots ou des noms.
|
||||
|
||||
Voici un exemple de la WINDOW nom de pilote en entrée :
|
||||
|
||||

|
||||
|
||||
Ce texte peut paraitre bon, cependant quand on le lance dans Tesseract, il ne va pas toujours donner un résultat parfait. Il faut aussi savoir qu'il y a des noms pas mal plus pénibles que Tesseract a plus de mal à reconnaitres, soit à cause des lettres utilisées, soit car le nom est un nom d'une autre région et qui ne veut rien dire en anglais ce qui empêche l'utilisation de dictionnaire (Ex : Tsunoda est un nom japonais et parfois il est difficile pour Tesseract de le reconnaitre car si une lettre pose problême il ne peut pas trouver de contexte qui puisse l'aider).
|
||||
|
||||
Donc pour le rendre plus facilement lisible et augmenter les chances que toutes les lettres soient découvertes, voici les étapes que j'ai mis en place.
|
||||
|
||||
1 : J'inverse les couleurs. Je me suis rendu compte que il était souvent plus facile de trouver un noir sur blanc que blanc sur noir. Je ne suis pas sur que cette étape soit capitale cependant.
|
||||
|
||||

|
||||
|
||||
2 : Je fais un Treshhold * de 165 car avec moins le texte parfois prend trop du background et avec plus les lettres sont trop fines.
|
||||
|
||||

|
||||
|
||||
3 : Je fais un Resize * de l'image pour avoir une meilleure résolution et permettre une meilleure détection. J'augmente la hauteur et la largeur par un facteur 2. J'ai trouvé cette valeur suffisante et aller plus haut consomme beaucoup de ressources.
|
||||
|
||||

|
||||
|
||||
4: Je fais une très rapide Dilatation * du texte pour retirer le flou amené par la methode de Resize. Je n'utilise qu'une valeur de 1 car je ne veux pas trop changer comment le texte est modelé je veux juste retirer le flou.
|
||||
|
||||

|
||||
|
||||
Voila pour ce qui est du post processing. Je ne dis pas que ce sont les meilleurs paramêtres possibles mais dans mes tests ce sont ceux qui ont le mieux marchés.
|
||||
|
||||
C'est aussi les premières methodes que j'ai pu développer alors forcément elles n'ont pas le niveau de détails de certaines autres.
|
||||
|
||||
Mais comme même avec ce traitement il n'est pas rare que je me retrouve avec une ou deux lettres pas justes, il faut un moyen d'être sûr que c'est le bon nom qui est trouvé. Ce qu'il y a de pratique avec les noms de pilotes c'est que on sait déja comment ils s'appellent avant le Grand Prix.
|
||||
|
||||
En effet dans le fichier de configuration de la reconnaissance, il y a une liste de noms de pilotes. Cela veut dire que au lieu de chercher à trouver parfaitement les bonnes lettres, on peut simplement essayer de trouver quel nom de pilote ressemble le plus au nom trouvé sur l'image.
|
||||
|
||||
Pour ce faire j'ai utilisé une methode appelée la distance de Levenshtein. Pour faire simple c'est une methode qui va calculer les distances de lettres pour determiner entre des strings laquelle ressemble le plus à une autre.
|
||||
|
||||
Pour résumer le fonctionnement dans lordre :
|
||||
|
||||
- On prend l'image on la traite
|
||||
- On envoie l'image traitée à Tesseract
|
||||
- On trouve quel nom de pilote ressemble le plus à ce résultat
|
||||
- On renvoie le nom du pilote
|
||||
|
||||
*(Explication des methodes précises plus bas)
|
||||
|
||||
CHIFFRES :
|
||||
|
||||
Cette methode en réalité utilise simplement la même methode que celle qui va récupèrer le texte sur une image. Cependant, la, on envoie à Tesseract l'information qu'il ne peut trouver que des chiffres sur l'image ce qui lui permet d'être beaucoup plus précis et de ne pas confondre un 9 avec un P ou un 11 avec un H PAR EXEMPLE (non pas que ca me soit arrivé très régulièrement et que ca me soit resté dans la gorge évidemment)
|
||||
|
||||
L'avantage c'est que cette methode ne demande même pas de traitement de la donnée en sortie de Tesseract. On éspère simplement que le post traitement aura suffit.
|
||||
|
||||
TEMPS :
|
||||
|
||||
Cette methode regroupe la détection de temps au tour. Il y a trois grands types de WINDOW qui sont concernées :
|
||||
|
||||
- La WINDOW du temps au tour
|
||||
- La WINDOW du retard sur le leader
|
||||
- La WINDOW des secteurs
|
||||
|
||||
La grande différence ce sont les ordres de grandeur. Les temps au tour sont en général entre 50 secondes et 2 minutes. Tandis que les secteurs sont entre 20 et 30 secondes alors que le retard sur le leader peut-être de plusieurs minutes.
|
||||
|
||||
Cependant, tous ces temps possèdent le même type de post-traitement avant d'être envoyés à Tesseract.
|
||||
|
||||
Voici un exemple de temps au tour avant toute transformation :
|
||||
|
||||

|
||||
|
||||
On peut avoir l'impression que ce texte est tout à fait lisible et facile à décoder surtout quand on le voit de loin comme ca. Cependant, il faut imaginer que ces chiffres font 13 pixels de haut en comptant le flou et comme expliqué plus haut ce flou dans ces echelles est terrible.
|
||||
|
||||

|
||||
|
||||
Si on donne cette image à Tesseract, les '3' deviennent des '9', des '9' deviennent des '8', des '2' deviennent eux aussi des '9', le tout parfois inversement et de manière complêtement imprévisible. Ca n'est simplement pas utilisable.
|
||||
|
||||
Cette partie est un peu plus complexe car si la detection n'est pas fiable les chiffres sont simplement inutilisables. Si à tout moment un temps au tour de 1:39.106 devient 1:32.108 c'est juste pas possible.
|
||||
|
||||
Voici donc les étapes de post-traitement que j'ai mis en place pour leur détection :
|
||||
|
||||
1: J'applique un Treshold* de 185 pour enlever les ambiguités d'alisaising et avoir une image en noir et blanc claire. La valeur de 185 est assez élevée car le but est de vraiment garder uniquement les contours. Comme les chiffres se ressemlent beaucoup plu que les lettres, il faut tenter le plus possible de conserver leur formes spécifiques. Je me suis rendu compte que cette valeur était une de celles qui marchent le mieux.
|
||||
|
||||

|
||||
|
||||
2: J'applique un Resize* de 2 pour augmenter la résolution des chiffres et permettre une meilleure détection. Le but est d'avoir plus de pixels et donc de permettre à Tesseract de mieux utiliser ses matrices de convolution.
|
||||
|
||||

|
||||
|
||||
3: Comme le Resize* amène du flou, j'utilise une methode de Dilatation* qui me permet de retirer ce flou et de remplir un peu plus certaines parties qui ont été un peu laissée par le Resize*;
|
||||
|
||||

|
||||
|
||||
4: Contrairement aux mots plus haut, la rondeur ajoutée par la dilatation n'est pas vraiment désirée. En effet, elle peut rendre confuse certains chiffres et empêcher Tesseract de bien trouver le chiffre. Alors j'applique une Erosion* qui me permet de contrecarrer en partie les rondeurs ajoutées par la dilatation et retrouver des chiffres bien formées. Pour l'Erosion* et la Dilatation* j'ai utilisé une valeur de 1 car je ne voulais pas trop changer les chiffres.
|
||||
|
||||

|
||||
|
||||
Et avec ce post processing on retrouve de plutôts bon résultats qui demandent peu de traitement.
|
||||
|
||||
Le traitement dépend du type de WINDOW cependant.
|
||||
|
||||
- Pour les secteurs on indique à Tesseract que les caractères autorisés sont : "0123456789."
|
||||
- Pour les temps au tour on autorise plutôt "0123456789.:"
|
||||
- Et pour les écarts on autorise "0123456789.+"
|
||||
|
||||
Ensuite on récupère une liste de chiffres qui'il va falloir transformer en milisecondes pour faciliter le stockage et l'envoi.
|
||||
|
||||
Le programme nettoie un peu la chaine avant de la convertir. Par exemple parfois le ':' de 1:34.456 est compris comme un '1' ou un '2' et il faut faire attention à detecter quand ca arriver.
|
||||
|
||||
Je passe les détails du reste du nettoyage car c'est vraiment du cas par cas mais quand on a finit de nettoyer la chaine on peut transformer les chaines de minutes secondes et milisecondes en un total de milisecondes.
|
||||
|
||||
Pour résumer le fonctionnement dans l'ordre :
|
||||
|
||||
- On prend l'image et on lui applique une série de
|
||||
|
||||
*(Explication des methodes précises plus bas)
|
||||
|
||||
PNEUS :
|
||||
|
||||
### Lecture des images
|
||||
|
||||
|
||||
@@ -1679,4 +1679,44 @@ J'ai tenté de le faire aparaitre en bougeant la souris, en cliquant à un endro
|
||||
|
||||
Puis j'ai eu l'idée de mettre pause en envoyant un appui sur la touche Espace et ca a permit de découvrir le bouton et permettre qu'on clique dessus.
|
||||
|
||||
Ca peut paraitre tout bête mais rien que ca, ca m'a pris un temps considérable.
|
||||
Ca peut paraitre tout bête mais rien que ca, ca m'a pris un temps considérable.
|
||||
|
||||
Bon pour ce qui est du timecode de la vidéo. Je pense qu'il serait trop complexe de faire en sorte que selenium change le slider de progression de la vidéo. Alors j'ai fait quelques tests et apparemment, si on quitte la F1TV sur un timecode de la vidéo que on donne au programme, comme il récupère tous les cookies de la F1TV il commencera de la.
|
||||
|
||||
Donc si on veut utiliser le programme avec des Grand Prix ayant déja eu lieu, on peut le faire, seulement il faudra juste au préalable avoir choisit le bon timecode dans le page de la F1TV avant de le lancer.
|
||||
|
||||
Ce qui est intéressant c'est que la page de la F1TV ressemble à ca au départ :
|
||||
|
||||

|
||||
|
||||
Je pense qu'une bonne idée serait de dire au programme que c'est la grille de départ et ensuite dès qu'il détecte un secteur il sait que la course a commencé.
|
||||
|
||||
## Lundi 24 Avril 2023
|
||||
|
||||
Aujourd'hui c'est jour de documentation.
|
||||
|
||||
J'ai pas mal travaillé pendant les vacances mais je n'ai pas encore pu faire de vraie documentation correcte du fonctionnement. Du coup je vais m'en charger aujourd'hui et peut-être un peu demain.
|
||||
|
||||
Ok normalement je ne devrais faire que de la documentation mais je ne peux pas passer à coté de ca... Le problème que j'ai avec les pneus ou parfois il détecte un H au lieu d'un '11' et ce genre de choses c'est à cause de ma methode "RemoveBG" Qui va retirer tous les pixels plus sombres que le background. Sauf que cela va aussi retirer des pixels dans le chiffre lui même et qui va donc defigurer les 11 :
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
J'ai réussi à les changer en :
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
Mais au final cela n'a pas augmenté la précision de la reconnaissance. Je pense que je vais donc devoir encore changer.
|
||||
|
||||
Je pense que une bonne facon de trouver serait dabord de trouver la couleur du pneu. Et si il n'y a pas assez de couleur alors c'est que le pneu contient une lettre. Le but est d'arrêter de chercher des lettres ou des chiffres. Comme ca les 11 arrêteront d'être pris pour des 'H'
|
||||
|
||||
En fait on peut faire encore plus simple que ca.
|
||||
|
||||
On peut simplement regarder la couleur dominante et determiner le pneu. En effet même si il y a une lettre sur fond noir pour décrire le pneu, mon methode de récupèration de la couleur dominante ommet les pixels trop noirs alors il est quand même possible de determiner le type de pneus.
|
||||
|
||||
Et tout simplement si il n'arrive pas à lire le chiffre c'est que c'est une lettre et que donc on est à 0 tours. Cela marche plutôt bien et cela simplifie pas mal le processing.
|
||||
|
||||
Voila, la je vais me remettre à la documentation sinon je vais encore prendre du retard.
|
||||