62 KiB
Rapport Track Trends V1.0
Rohmer Maxime Travail de diplôme Technicien ES 2023
Introduction
Résumé
Track Trends est un outil de récupération et d'analyse de données de courses de Formule 1.
Pour le contexte, en dehors des cours, j'exerce différentes activités dont celle de Live Ticker F1 pour le 20 minutes. Pour m'aider dans ce travail, j'utilise actuellement la F1TV à laquelle je suis abonné qui me propose non seulement un feed vidéo de meilleure qualité avec des commentaires plus pertinents que ceux de la RTS mais qui aussi me permet d'accéder à un feed vidéo très important : la chaine data.
Ce dernier ressemble à cela :
(Attention ce n'est pas un joli tableau HTML, mais bien une vidéo qui contient un tableau.)
Sauf que toutes les informations sont étalées pêle-mêle sans hiérarchie ce qui fait que cela me prendrait trop de temps de tout déchiffrer à chaque fois, ce qui me fait rater des choses intéressantes.
Le but du projet est donc de fournir un outil qui hiérarchise et affiche différemment les données pour faciliter leur lecture et me permettre de faire de meilleurs commentaires.
Abstract
Track Trends is a Formula 1 data and analysis tool.
To understand everything, a little bit of context. In my free time I have multiple activities and one is to be the Live Ticker F1 for the local journal "20 minutes". to help me in this work I'm currently using the F1TV to which I'm currently subscribed because it provides me with a better video feed with better commentary than the ones from the RTS (in my opinion) but also because it gives me access to a very important video feed : the data channel
See the screenshot above to see what it looks like.
[note: It's a pretty HTML table but a full on video feed that contains a table (probably, so you can't access data directly)]
You can see a lot of data all well and good BUT! All the data is displayed the same in a big table which make it really hard to read totally in a hurry, which means that I miss a lot of useful information.
The point of the project then is to provide with a tool that can display those data by taking into account their relevance. That would help me not miss any and provide a better commentary by never missing out battles, and be able to better write with the time I saved by using it.
Description du besoin
Comme expliqué dans le résumé, je suis Live Ticker F1. Mais pour mieux comprendre le besoin que j'ai, je pense qu'il est pertinent de comprendre comment je travaille.
Pendant un Grand Prix de Formule 1 j'ai plusieurs tâches à effectuer :
- Suivre les différents évènements du Grand Prix
- Changer le titre et la photo de titre du Live
- Chercher des Tweets ou des Images à intégrer
- Ecrire les commentaires en faisant attention à dire ce qu'il se passe mais aussi l’expliquer, ce que cela implique, mais aussi ce que cela veut dire pour le reste de la course.
- Comprendre et expliquer les stratégies
Tout cela toutes les cinq minutes max...
Cela veut dire que je dois être le plus rapide possible quand je cherche des informations. Et comme le tableau en comporte trop et bien, je suis obligé de le lire en diagonale.
Par exemple dans le tableau, les infos que je cherche le plus sont :
- Le nombre de places gagnées (surtout au départ)
- Les écarts entre les pilotes (surtout ceux qui sont en dessous de deux secondes).
- Les pneus de chaque pilote et combien de tours, ils ont fait dessus
- Les temps d'arrêts aux stands
- Les temps au tour (surtout pour la stratégie)
Mais pleins d'autres informations existent si on les recoupe sur plusieurs tours.
Un outil qui permettrait de mettre en évidence les informations importantes serait donc une très grosse plus-value pour mon travail et s'il est facile à installer et à utiliser, il se pourrait qu'il devienne indispensable.
Cahier des charges
Il s'agit d'une version coupée du cahier des charges qui ne contient pas l'explication du contexte. Mais l'original est disponible sur ce site également. Il est toutefois normal d'y voir des choses répétées ou légèrement différentes, en effet, il n'a pas été écrit en même temps que le reste de ce document.
Projet
Un outil de style compagnon sous forme d'application C# Windows Form qui récupère en temps réel les informations de la course et affiche les informations les plus importantes. Le but est non seulement de faciliter mon job, mais aussi faire en sorte d'améliorer la plus-value de mon travail en me permettant de fournir des commentaires qui ne sont pas disponibles pour le tout venant qui regarde simplement le flux RTS.
Exemples :
- Les pilotes qui sont proches (moins de 1-2 secondes qui sont donc en train de se battre).
- Les pilotes qui améliorent leur temps au tour et ceux qui perdent le plus de temps
- Le classement pondéré tenant compte des futurs arrêts au stand
Maintenant afficher différemment les infos, c'est sympa, mais cela serait encore mieux de traiter ces data et de permettre des petites prédictions.
Exemples :
- Prédire les arrêts aux stands en prenant en compte les baisses de performances des pneus
- Prédire le pneu que le pilote va chausser s'il rentre aux stands dans le prochain tour
- Prédire dans combien de tour tel pilote va rattraper tel autre pilote
- Prédire combien de temps le pilote va perdre dans les stands en fonctions des arrêts précédents
Réalisation
Malheureusement, la Formula 1 Management ne propose aucune API publique qui puisse nous permettre de faire ce projet "simplement". La raison la plus probable étant qu'Amazon avec son service AWS propose exactement ce genre de services pour le flux télévisé et il doit y avoir un contrat d'exclusivité.
Il existe des API "Pirates" faites par la communauté, le problème est qu'elles ne sont pas forcément des plus pratiques à utiliser.
Mais comme je possède un abonnement premium ++ à la F1TV, j'ai accès pour chaque grand prix à un flux vidéo nommé : DATA F1 CHANNEL
Qui ressemble à ça :
Donc la seule façon que je vois de récupérer ces données est de les prendre directement sur ce feed.
Même si le but final de l'application est de faire pleins de choses super avec les datas, le gros du projet va surtout être la récupération des données et leur stockage.
Les données viennent du flux vidéo et ainsi dans un premier temps, il va falloir récupérer d'une manière ou d'une autre des images qui viennent d'un grand prix en direct ou en rediffusion.
Ensuite, dans un second temps, il faut lire les informations directement sur l'image en utilisant une librairie prévue pour (exemple Tesseract) et vérifier l'intégrité de ces dernières pour qu'on puisse ensuite les stocker.
Dans un troisième temps, il faut stocker toutes ces données dans une forme qui permette d'aller facilement faire des requêtes de récupération et déjà préparer des méthodes qui permettent de récupérer des infos importantes (ex : la moyenne des cinq derniers tours, le temps moyen d'arrêt etc.) pour faciliter la dernière étape
Quand tout cela est fait, on peut ensuite s'amuser un peu avec les Data.
La dernière étape est donc l'affichage. L'idée est de créer une Windows Form qui contienne toutes ces informations dans un format beaucoup plus lisible et avec laquelle on pourrait interagir pour permettre de plus facilement commenter les Grands Prix. (exemple plus bas avec un croquis de ce à quoi l'application pourrait ressembler)
Voici la liste des données qui pourraient être affichées (Non contractuel, simplement des idées).
- Les pilotes qui sont proches (moins de 1-2 secondes qui sont donc en train de se battre).
- Les pilotes qui améliorent leur temps au tour et ceux qui perdent le plus de temps
- Le classement pondéré tenant compte des futurs arrêts au stand
- La moyenne de temps que les pilotes perdent dans les stands
- La performance moyenne des 5 types de pneus
- La moyenne de temps de chaque pilote sur le pneu actuel
- Le nombre de points que chaque pilote gagnerait selon sa position
- Le classement de la course
Voire même si c'est possible :
- Prédire les arrêts aux stands en prenant en compte les baisses de performances des pneus
- Prédire le pneu que le pilote va chausser s'il rentre aux stands dans le prochain tour
- Prédire dans combien de tour tel pilote va rattraper tel autre pilote
- Prédire combien de temps le pilote va perdre dans les stands en fonctions des arrêts précédents
- Prédire les temps au tour de chaque pilote selon l'usure des pneus
Voici un exemple d'interface possible pour une page :
Cas d'utilisation
'*'On va considérer que tous les user ont un abonnement F1 TV PRO
Un user veut récupérer les data :
- Il ouvre son navigateur et lance la page DATA de la F1 TV
- Il calibre la capture des data via le programme (pour la première utilisation).
- Il confirme que les données initiales sont bonnes (pour la première utilisation).
- Il regarde tranquille son Grand Prix
Le programme récupère les data :
- Il récupère des images depuis la F1TV
- Il utilise Tesseract (ou autre) pour en récupérer les infos.
- Il met ces infos dans un Objet Pilote, dans un Objet course avec un attribut tour pour hiérarchiser les data
Pour ce qui est de l'affichage, l'idée est de faire une application C# comme on l'a appris à l'école, mais avec assez de style pour qu'elle puisse être agréable à utiliser.
Quand le programme affiche les data :
- Il prend les données venant directement de la F1TV.
- Il affiche différemment les données pour permettre une meilleure lisibilité
- Il interprète avec des règles plutôt simples certaines data pour faire des miniprédictions ou aider à la lecture
- Il récupère des infos d'autres courses pour les comparer et proposer des prédictions plus intéressantes
Difficultés techniques
- Récupérer un flux vidéo plutôt propre malgré les contres mesures de la F1 TV pour en empêcher la lecture par un logiciel
- Si on doit passer par une capture d'écran, trouver un moyen de stocker les données de manière à prévoir que parfois un tour pourrait avoir plus de données qu'un autre, que le user peut mettre pause, ou même qu’il revienne en arrière.
- Développer des algorithmes pour récupérer les données comme les différents pneus utilisés ou l'activation du DRS ainsi que développer des moyens de nettoyer les résultats de l'OCR (Par exemple utiliser différents champs redondants pour comparer les résultats)
- Stocker les données sur une base pour les traiter plus tard tout en prévoyant un moyen de voir les stats live
- Développer des algorithmes de prédiction qui prennent en compte d'anciennes courses pour tenter de prédire des choses comme les arrêts aux stands par exemple.
Différences sur le cahier des charges
[À remplir dans les dernières semaines du travail de diplôme]
Planning prévisionnel
Mes suiveurs m'ont demandé un planning de type GANTT pour ce travail de diplôme
Je n'ai pas utilisé un logiciel particulier pour faire ce dernier, mais je me suis inspiré des principes fondamentaux d'un diagramme de ce type.
Comme l'original a été fait sur Excel, je ne peux pas vraiment l'insérer de manière lisible ici, mais il est disponible dans le dossier Planning.
Mais voici un résumé de son contenu :
Tâches
J'ai décidé de décomposer mon planning en trois grands types de tâches.
- Programmation
- Documentation
- Tests
L'idée est de permettre une meilleure lisibilité et de me permettre à moi de me faire plus facilement à l'idée de ce qu'il m'attend.
Voici la liste des tâches par rubrique :
PT
Cette rubrique contient les tâches qui n'ont pas leur place dans les trois catégories principales.
PT1 / préparation au travail de diplôme (2)
Cette tâche est un peu hors catégorie, mais c'est normal, c'est une supertâche qui regroupe beaucoup de choses. C'est une tâche qui est planifiée pour deux jours et qui normalement devrait être faite les deux premiers jours du travail.
Le but est de préparer tout ce qui peut être préparé en avance niveau documentation et mise en place pour ne pas avoir besoin de s'en soucier ensuite.
DT
Rubrique documentation qui contient toutes les tâches en rapport de près ou de loin avec la documentation du projet.
DT1 Création du poster (1)
Cette tâche consiste à faire une version numérique du poster qui soit en accord avec les consignes qu'on nous a données. Le but est aussi et surtout de faire poster dont je sois fier et que je sois content de montrer.
Il y a déjà des croquis de poster et j'ai clairement prévu de travailler sur ça pendant les vacances alors, je n'ai mis qu'un jour et je l'ai placé juste avant le rendu de ce dernier.
DT2 Documentation Analyse de l'existant (2)
Cette tâche est dédiée à l'écriture de la documentation et plus précisément de l'analyse de l'existant.
Comme il y a pas mal de technologies utilisées dans mon projet, j'aimerais faire correctement un vrai debrief de pourquoi j'ai utilisé l'une ou l'autre alors, j'ai assigné deux jours dessus.
DT3 Documentation Analyse organique (5)
Cette tâche est la plus grosse dans la catégorie documentation. Il s'agit de documenter comment l'application fonctionne.
J'y ai mis cinq jours et je pense que c'est un minimum car c'est dans cette tâche que je vais devoir détailler exactement comment fonctionne chaque partie du projet.
Ces cinq jours sont éparpillés sur le projet en général à la fin du développement de chaque grande partie de projet. Le but est de ne rien oublier et de ne pas avoir à tout faire en même temps.
DT4 Documentation Analyse fonctionnelle (2)
Cette tâche est déjà moins grosse, elle consiste à documenter le fonctionnement de l'application et comment utiliser les composants que j'ai développés.
Je l'ai mis en fin de projet, car comme j'ai l'habitude de faire des analyses fonctionnelles plutôt précises, le moindre changement dans l'UI peut tout rendre obsolète.
J'y ai mis deux jours, car j'aimerais correctement documenter avec de bonnes photos et scénarios pour qu'on puisse voir toutes les possibilités de l'application.
DT5 Documentation Tests (1)
Cette tâche est un peu plus petite qu'elle ne le devrait. Elle concerne la documentation des différents tests. Je n'y ai mis qu'un seul jour, car en réalité les différentes tâches de tests contiennent aussi beaucoup de documentation,
DT6 Documentation Reste (2)
Cette tâche est une tâche un peu vague. Elle contient toutes les actions autres que j'aurai besoin de faire (Mise au propre, orthographe, génération de PDF ...). J'y ai mis deux jours pour avoir un peu de marge, car ce sont toujours des tâches qui paraissent faciles, mais qui à la fin prennent beaucoup de temps si on les fait bien.
PT
Rubrique programmation qui contient toutes les tâches qui touchent à la programmation et au développement de l'application.
PT1 Programmation récupération des images (3)
Cette tâche est estimée à seulement trois jours, il ne faut pas s'y méprendre, c'est une des tâches les plus dures et lourdes niveaux documentation en explications. Cependant, un POC (Proof Of Concept) assez avancé a déjà été fait et donc cela permet de n'envisager que trois jours, car il suffit de l'implémenter et de la paufinner.
Cette tâche consiste à prendre en entrée un lien de Grand Prix et de sortir une image tous les x secondes de la page DATA. Cela peut sembler simple, mais pour le faire sans prendre d'espace d'écran et ne demandant pas à l'utilisateur de copier-coller quoi que ce soit où de donner ses identifiants F1TV c'est un challenge.
Cela peut paraitre curieux alors de mettre cette tâche loin dans le planning même si c'est la première étape du projet. Encore une fois cela s'explique avec le fait qu'il y a déjà un POC qui fonctionne à peu près et que donc préfère commencer avec des tâches plus incertaines dans le cas où elles prendraient plus de temps que prévu.
PT2 Programmation OCR (5)
Cette tâche consiste à développer la partie qui reconnait le texte sur les images. C'est très certainement la tâche qui risque le plus de déborder car c'est celle qui est la plus complexe techniquement puisqu'elle demande non seulement la lecture sur image, mais aussi le développement d'algorithmes de traitement de cette donnée pour être sûr qu'elle a bien été lue.
J'y ai ainsi alloué cinq jours, mais j'espère que j'arriverai à gagner du temps sur les autres pour y allouer plus dans le planning effectif, car je suis convaincu que plus, on y passe du temps, meilleur sera le résultat.
PT3 Programmation, stockage et modèle (5)
Cette partie est moins technique, mais concerne le stockage des données que nous retourne la lecture des images. Mais elle va demander de la réflexion et de l'intelligence de programmation, car il faut que cette partie anticipe les besoins de la vue et prépare un terrain fertile qui ne demande pas un refactor quand on passera au développement de la vue.
C'est pour cela que je lui ai aussi assigné cinq jours de travail et elle doit absolument être commencée après la lecture.
PT4 Programmation Vue de l'APP (5)
Cette partie peut être horrible comme très facile, cela dépend complètement de la qualité du travail avant. Si le modèle est parfait et que les données sont intègres, cela devrait être plutôt simple de les afficher de manière intéressante. Cependant, cette partie débordera sûrement un peu, car tout le temps gagné avec de bonnes données sera utilisé pour tenter de faire de la prédiction.
Pour ces raisons, je lui ai assigné également cinq jours de travail et elle doit absolument être faite après le modèle.
PT5 Programmation mise en commun (3)
Cette tâche est aussi un petit peu spéciale, car elle regroupe plusieurs choses. En gros, chaque partie de programmation sera sûrement assez indépendante et il faudra à un moment faire un seul projet C# qui contient tout.
Il est difficile d'estimer à quel point cela va être compliqué alors, j'ai été conservateur et j'ai mis trois jours.
TT
Cette rubrique contient les tâches qui sont uniquement des tests. La plupart des tâches de programmations contiennent déjà des tests, mais certaines demandent une attention particulière.
TT1 Tests OCR (2)
Cette tâche est une des tâches les plus importantes. Son but est de faire un protocole de tests complet qui permette de comparer les différents algorithmes de reconnaissance de texte.
Je l'ai mise après la reconnaissance, mais même maintenant en écrivant ces lignes, je me dis que dans le planning effectif, elle sera faite pendant la tâche de programmation. En effet, comment savoir si mon tout nouvel algorithme est réellement mieux que le précédent.
Je prévois deux jours, car je pense que faire le dataset va prendre beaucoup de temps, il faut prévoir un certain nombre d'images et de texte qui pourront ensuite être données sous forme de tests. C'est certes une tâche de test, mais c'est aussi de la programmation.
TT2 Tests finaux (2)
Cette tâche de tests est un peu vague, elle regroupe les différents tests pour vérifier que les données sont bien affichées correctement. Ce qui serait cool si j'ai du temps en fin de travail de diplôme serait de faire un système de test qui permet d'entrainer le programme à mieux reconnaitre certaines choses comme des arrêts aux stands si on lui donne les trois dernières années de grands Prix.
J'ai mis une durée arbitraire de deux jours, mais je ne sais pas vraiment combien de temps cela va vraiment durer. Elle est évidemment à effectuer une fois que tout est à peu près terminé.
Planning effectif et différences
[A remplir dans les dernières semaines du travail de diplôme]
Analyse fonctionnelle
[A remplir au fur et à mesure dans la seconde moitié du travail de diplôme]
Analyse Organique
[A remplir au fur et à mesure que les features sont développées]
Récupération des images
Voici la première grande étape du projet.
Pour rappel, Amazon héberge directement le site de la F1TV et possède les droits sur les données de la F1. C'est sous le nom de AWS (le service d'hébergement d'Amazon) que la firme apparait en tant que sponsor.
On peut voir ce nom apparaître assez souvent quand on regarde un Grand Prix car comme ils ont la main-mise sur les données ils peuvent insèrer des bandeaux d'informations sur le flux public sur ce qu'il se passe voir même faire des prédictions (Bien qu'un peu bancales)
Ce service s'appelle F1 Insights (Oui c'est un meilleur nom de projet que F1 Companion mais bon) et c'est, je pense, la raison pour laquelle on ne voit aucune API publique qui permette de correctement se renseigner en donées en direct pendant un Grand Prix. Ils ont du dégotter un juteux contrat pour s'occuper de toute l'infrastructure digitale de la F1 (du moins publique) en échange d'une exclusivité totale sur certaines choses comme les Data
Evidemment je ne fais que conjecturer et ce que j'ai dit n'est pas à prendre au pied de la lettre mais c'est une explication possible je pense de pourquoi il est si difficile de trouver des données sur la F1 facilement en temps réel.
Il existe bien quelques API un peu bancales publiques, mais le problème c'est qu'elles ne sont vraiment pas suffisante et je ne peux pas leur faire confiance quand je commente. Ce qu'il m'aurait fallut c'est une API publique et officielle qui me permette d'être sur que les données sont les bonnes et qu'elles arrivent le plus vite possible.
On pourrait croire que c'est impossible car cela n'existe pas comme je l'ai dit MAIS ! Ce n'est pas complêtement vrai. En effet depuis que je possède un abonnement à la F1TV, il existe une source d'informations très précieuse qui m'aide énormément dans mon quotidien de commentateur de Formule 1. La "DATA CHANNEL".
La Data Channel est une page de la F1TV qui permet, pour chaque Grand Prix, de visualiser, sous la forme d'un flux vidéo, différentes informations capitales sur la course.
Le problème, c'est que comme je viens de le dire, ces données ne sont pas accessibles comme un tableau HTML ou un flux RSS ou un tableau JSON. C'est un flux vidéo. Il faut savoir qu'entretenir une diffusion de flux vidéo en 1080P pendant deux heures accessible par des milliers d'abonnés est EXTRÊMENT cher surtout quand on le compare à simplement afficher les données dans un tableau. Ce qui veut dire que ce choix est délibéré et a un sens au niveau économique. Je pense donc que c'est justement pour éviter que des petits malins puissent simplement venir scraper l'intégralité des données qu'ils proposent et fasse sa propre API. (C'est d'ailleurs un des sites avec la meilleure protection anti bot du monde)
MAIS ce n'est pas par ce que les données ne sont pas facile à avoir qu'elles sont IMPOSSIBLE à avoir. Et c'est la que ce projet entre en jeu. Mais pour décoder les données d'une image il faut dabord ... (roulement de tambours) ... Avoir des images !
Et c'est la que vient se glisser cette partie du projet.
Comment faire ?
Le but de ce segment est de se concentrer sur la récupèration et la mise à disposition pour le reste du programme, des images en direct de la F1TV dans la meilleure qualité possible et dans les meilleurs délais.
Pour ce faire il y a plusieurs solutions :
- Reverse engeneer la F1TV pour accèder directement au flux sans passer par la plateforme internet et pouvoir prendres images à volonté.
- Avoir tout simplement une page de la F1TV ouverte sur un écran et prendres des screenshots à intervals réguliers.
- Simuler un navigateur internet sans qu'il soit affiché et le contrôler automatiquement pour qu'il prenne des captures.
La première option aurait été la plus élégante mais lors d'un POC que je tentais de réaliser je me suis rendu compte que cela serait un peu trop compliqué et long à faire. Sans compter le fait que les rediffusions de Grand Prix ne sont pas gèrées de la même manière que les diffusions en live. Et que pour faire des Tests en live il faudrait attendre à chaque fois un weekend de Grand Prix et le faire en plus du commentaire que je dois produire.
Pour toutes ces raisons et bien d'autres je l'ai rangée dans la case "Trop dur, Trop chiant, Sûrement illégal" (Oui je sais c'est une catégorie bien spécifique mais c'est ma documentation je fais ce que je veux)
La troisième option aurait été la plus simple (et moins drôle) et je suis presque sûr que je peux implémenter cette dernière en moins d'une après-midi. Sauf qu'elle apporte de gros soucis.
- On ne peux pas garantir l'intégrité et la continuité des données si l'utilisateur avance ou fait pause même par simple inadvertance.
- La moindre fenêtre qui s'afficherait devant ruinerait toute la reconnaissance de caractères.
- On ne peut pas contrôler la qualité du flux et on est obligé de faire confiance en l'utilisateur
- On ne peut pas vraiment automatiser quoi que ce soit niveau tests ou même pour faire du scrapping auto pour remplir une base de donnée.
- Et finalement le pire inconvénient : C'EST NUL ! Je ne pourrais jamais utiliser un projet qui fonctionne de cette facon, je ne peux pas me permettre d'avoir un écran inutilisable quand je commente et auquel je dois constamment faire attention pour ne pas perturber la reconnaissance. Pour moi cette option aurait été celle à choisir en cas d'extrême urgence et en dernier recours car le projet deviendrait inutile.
J'ai donc décidé de m'occuper de la seconde option : Simuler un navigateur.
Cette option bien que complexe et difficile à implémenter propose une solution à tous les problême et permet une récupèration quasi sans compromis.
Simuler un navigateur ?
Simuler un navigateur internet n'est pas forcément très difficile. Chromium par exemple offre une panoplie d'outils natifs et énormément de librairies existent permettant de facilement et en quelques lignes simuler un Google Chrome et le contrôler sans afficher son UI.
{: style="height:150px;width:150px"}
Cependant. La F1TV n'utilise pas simplement un player HTML5 basique. Elle utilise un service de streaming BitMovin qui permet de fournir un stream de bonne qualité et surtout qui implémente les DRM (Digital Right Management)
Cela veut dire que quand on ouvre un flux de la F1TV sur chrome et que l'on essaie de prendre une capture d'écran, le player se met en noir et ne permet pas de voir quoi que ce soit (Certaines version de Chrome le permettent pendant quelques semaines avant de bloquer à nouveau). Ce qui dans notre cas est un immense problème. Mais Firefox ne nous bloque pas de cette facon et il est donc assez facile de passer outre.
L'explication sans trop rentrer dans les détails est la suivante :
Dans chrome, le player par défaut utilise une technologie appellée "PCP" ou "Protected Content Playback" qui leur permet de bloquer au moins une partie des techniques de récupèration du flux vidéo et audio.
Cependant Firefox de pas sa nature Open Source utilise "OpenH264" pour lire ces mêmes flux soumis à des DRM et OpenH264 n'implémente pas les mêmes restrictions.
Sauf que Firefox n'est pas aussi facilement émulé que chrome et cela réduit notre choix de librairies à ... Une seule... Qui est Selenium. (Il existe aussi Pupetteer C# mais j'ai rencontré énormément de soucis avec cette dernière dès que je voulais lancer une vidéo)
{: style="height:150px;width:150px"}
Mais même si la documentation est plutôt maigre parfois, c'est une bonne librairie qui permet de très bien contrôler une instance de chrome ou de Firefox.
Contrôler le navigateur
Maintenant que l'on sait quel navigateur simuler et avec quelle technologie, on peut passer à la réalisation.
Ce qu'il y a de bien avec Selenium, c'est qu'on a un certain nombre de commandes très haut niveau qui nous permettent de contrôler un navigateur de manière plutôt précise.
Je vais décrire ici la procédure habituelle utilisée sous une forme de recette de cuisine pour que l'on puisse facilement comprendre ce qu'il se passe.
Durant cette explication je vais parler à un moment de Cookies, ne vous en faites pas c'est le sous chapitre suivant qui va vous en parler.
Recette de cuisine pour récupèrer des images de la F1TV :
- Démarrer une instance de navigateur avec les bons arguments
- Ajouter les bons paramêtres pour ne pas se faire flag comme un bot
- Naviguer sur la page de la F1TV
- Ajouter les cookies de connexion pour avoir accès au contenu de la page
- Naviguer sur la page du Grand Prix demandé
- Attendre un peu que la page se charge
- Cliquer sur l'invite de cookies
- Attendre cinq secondes le temps que la page se reload
- Cliquer sur le bouton qui permet de passer du feed live à la DATA CHANNEL
- Appuyer sur Espace pour faire apparaitre le bouton d'accès au paramêtres
- Cliquer sur le menu déroulant des résolution
- Trouver l'option 1080P et la selectionner
- Cliquer sur le bouton qui met la vidéo en plein écran
- Prendre de screenshots à intervales réguliers
Pour faire toutes ces actions on doit récupèrer les éléments selon leur ID ou leur classe.
Voici un exemple qui récupère le bouton de plein écran et qui clique dessus :
IWebElement fullScreenButton = Driver.FindElement(By.ClassName("bmpui-ui-fullscreentogglebutton"));
fullScreenButton.Click();
Ca peut paraître plutôt simple dit comme ca et quand tout fonctionne ca l'est mais la difficulté vient du fait que à peu près nimporte laquelle de ces étapes peut rater et qu'il faut donc faire un bon système de gestion d'erreurs qui puisse aider l'utilisateur en cas de problème.
Il faut dire aussi que les sites ne sont pas forcément très content de voir des bots passer car cela peut être un risque de DDOS et de Scraping (Comme moi) et donc ils mettent en place des systèmes pour nous empêcher de faire ce que l'on veut
On peut utiliser différntes techniques pour passer outre ces restrictions comme :
- Changer son UserAgent
- Changer sa résolution
- Ne pas avoir des patterns trop prévisibles
- Avoir un historique
- Ne pas cliquer pile sur le milieu des boutons
- Ne pas cliquer trop vite
- Passer par un proxy pour ne pas se faire flag
- Utiliser des librairies plus discrètes
J'ai eu l'occasion de tester toutes ces methodes pour tenter de passer derrière les radars de la F1TV et visiblement j'ai réussi pour les pages principales mais pas pour les pages de Login.
Il faut savoir que la bataille entre bots et propriétaires de sites est un grand jeu du chat et de la souris et que les plateformes innovent constamment leur sécurité. Et il se trouve que la partie login de la F1TV est hebergée autre part que le reste du site chez Amazon et que elle possède les meilleures sécurités que j'aie pu voir. Aucunes des methodes que j'ai citées et d'autres encore que j'ai essayé n'ont réussi à fourvoyer le système.
J'ai donc été obligé de faire appel à la connexion par Cookies pour pouvoir accèder au reste du site internet.
Récupèrer les cookies ?
Alors, on va mettre de côté toutes les questions de sécurité et de violation de la vie privée et de protection des données des utilisateurs pour ce chapitre. Car pour faire simple, je siphonne TOUS les cookies de la persone qui utilise mon app.
[FINIR CETTE EXPLICATIOn]
Calibration
[AJOUTER EXPLICATION]
OCR
Ici je vais parler de la seconde partie du projet qui parle 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.
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.
Mais avant ca je dois expliquer certains concepts qui seront importants.
Fonctionnement général
Voici un screenshot de la page DATA de la F1TV que le programme va recevoir :
Si on regarde de loin on peut se dire que la structure est plutôt simple mais c'est loin d'être le cas. On peut y voir au moins 4 zones contenant de l'information dans un format différent.
Dans l'exemple ci dessus on peut voir 3 zones mais on aurait également pu comprendre la zone de position des pilotes autour du circuit pour faire 4.
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 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 :
L'objet "Zone" parent est un objet qui est une zone d'image. Je m'explique, le but d'une zone est d'être un morceau d'une image plus grande.
Le but d'une Zone est de contenir une liste de plus petites Zones ou bien une liste de "Window" (j'explique ce que c'est juste après). Elle contient la portion d'image qui la concerne et ses propres dimensions.
Le parent zone ne prévoit que de pouvoir ajouter ou supprimer des éléments des listes de zones ou de windows ainsi qu'une methode qui permet d'aller chercher toutes informations des livres qu'elle contient.
L'intérêt d'une zone est de pouvoir compartimenter une image dans des parties intéressantes au niveau de la reconnaissance mais pas de traiter d'information.
WINDOW :
L'objet "Window" est un objet qui peut ressembler beaucoup à l'objet "Zone". En effet elle aussi est une partie d'une image plus grande et contient ses dimensions, mais elle se distingue en deux points importants.
- Elle ne contient pas d'autres Zones ou Windows
- Elle peut retourner les informations écrites sur son image.
Toutes les Window qui héritent du parent Window peuvent implémenter une methode qui permet de renvoyer ce qui peut être décodé sur son image. Les enfants peuvent aussi aller piocher dans les nombresues methodes de récupèration de données contenues dans le parent Window. Mieux vaut réutiliser le plus possible que de réinventer la roue pour chaque Window.
Une analogie un peu bancale pourrait se présenter comme la suivante :
La zone est une armoire ou une bibliotèque. Si c'est une zone qui contient d'autres zones c'est une bibliotèque et chacune de ces sous-zones sont des armoires. Leur unique but est de contenir de manière ordonnée des objets qui eux contiennent de l'information.
Les livres ici sont les Windows. Ils contiennet de l'information et sont stockés dans des armoires et on y accède en allant dans la bonne bibliotèque et en allant dans la bonne armoire.
Dernières choses pour comprendre le diagramme:
- Il existe une Main Zone qui est une des 4 grandes zones dont je parlais dans la décomposition de l'image.
- Il existe aussi des "Driver Zone" qui sont de plus petites zones contenues dans la Main Zone qui et qui ne contiennent que les informations d'un pilote.
- L'objet Window n'est quasi jamais utilisé, c'est presque tout le temps des enfants de Window plus spécifiques qui sont utilisés, le but est que chaque type d'information sur l'image aie son type de window.
Voila donc un petit diagramme qui montre le découpage du programme :
Pour visualiser encore un peu mieux comment ce découpage prend forme voici ce que chaque zone et Window contient.
Main Zone :
Driver Zone :
Driver Position Window :
Driver name Window :
Driver LapTime Window :
Driver Tyre Window :
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.
Explication des methodes précises plus bas
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
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.
Explication des methodes précises plus bas
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 filtres
- On envoie l'image filtrée à Tesseract
- On nettoie le résultat Tesseract pour compenser certains biais
- On convertis le résultat en milisecondes
Pneus
La on arrive sur la partie la plus pénible.
Pour comprendre la problématique il faut d'abord faire un petit point sur comment les pneus fonctionnent en Formule 1.
Depuis 2019 en Formule 1 nous avons 5 grandes familles de pneus :
- Les pneus tendres
- Les pneus medium
- Les pneus durs
- Les pneus intermédiaires
- Les pneus pluie
Les trois premiers pneus sont des pneus faits pour piste sèche, le pneu intermédiaire pour piste humide et le neu pluie pour la pluie.
Chaque pneu a sa durée de vie et son niveau de performance propre mais je ne vais pas rentrer dans le détail ici. Tout ce qu'il faut savoir ce que savoir sur quel pneu chaque pilote est et depuis combien de temps il les chausse est une information très importante.
Chaque pneu a une couleur donnée qui permet de les différencier.
Voici un exemple de ce à quoi une WINDOW de pneus peut ressembler :
Mais cette zone peut aussi ressembler à ca :
Mais aussi à ca :
Voire même ca :
Je pense que vous pouvez tout de suite comprendre la difficulté que représente la tâche de récupèration de données à partir de cette image.
En gros le fonctionnement de cette zone d'information est assez simple.
- Au fur et à mesure que la course avance, le trait fait de même.
- Le chiffre dans le round tout à droite indique le nombre de tour que le pilote a passé sur ce pneu.
- La couleur indique le type de pneu.
- Si il y a une lettre à la place d'un chiffre c'est que c'est le premier tour sur ce pneu. La lettre indique le type de pneu.
Et pas besoin de dire que si on essaie simplement de donner l'image à Tesseract on ne récupère ni les chiffres ni les lettres correctement si ce n'est pas du tout.
Il faut donc utiliser une methode qui permette d'isoler le rond le plus à droite, lui appliquer un traitement qui permette à Tesseract de lire ce qu'il y a marqué et qui puisse determiner quel pneu est en train d'être utilisé.
J'ai décidé de m'occuper dans un premier temps de trouver ce rond avant d'appliquer les filtres car plus l'image est petite plus les filtres sont rapides.
Le programme va tirer un trait depuis le bord droit de la zone, et il va avancer vers la gauche jusqu'à trouver un obstacle. Je détecte un obstacle si le pixel sur lequel est mon trait possède une valeur de plus de 0x50 dans le channel R,G ou B. J'ai trouvé en faisant des tests que les couleurs de background de la F1TV ne dépassaient jamais ces valeurs.
Ensuite après avoir trouvé le premier obstacle, je récupère une zone qui doit englober le cercle.
Voici un exemple avec cette image en entrée :
Elle est automatiquement coupée de cette facon :
Cela me permet d'isoler uniquement ce qui m'intéresse ce qui est très pratique pour Tesseract et pour la detection de couleur.
Ensuite avec cette image je peux commencer le processus de reconnaissance.
Je commence par faire une moyenne de tous les pixels de l'image en excluant les pixels trop sombres qui font sûrement partie du background ou du chiffre.
Ensuite j'utilise une methode qui calcule la différence entre la couleur obbtenue et la liste de couleurs possible.
Il y a cinq couleurs des pneus possibles :
"#ff0000" pneu tendre/soft
"#f5bf00" pneu medium
"#a4a5a8" pneu dur/hard
"#00a42e" pneu inter
"#2760a6" pneu pluie/wet
Ce qui est pratique c'est que même dans les cas ou il n'y a pas beaucoup de couleur comme celui la :
On arrive à une couleur moyenne de :
Et il est donc assez facile de determiner le type de pneu en question.
Attention, les résultats peuvent être très vite dérangés par la couleur du pneu précédent si le découpage de la fenêtre n'a pas été assez précis.
Ensuite il "suffit" de lire le chiffre dans le rond et si on arrive pas à le lire alors c'est que c'est une lettre et on sait que le nombre de tours est donc de 0.
Maintenant vient le moment très sympatique de la lecture du chiffre.
Vous saurez que Tesseract en plus de detester les grandes images et les images avec des couleurs, deteste également les formes dans une image. Donc dans notre cas, le round de couleur autour du chiffre, même si il n'est pas complet, il interfère avec la reconnaissance et empêche de bien lire le chiffre.
Il faut donc retirer le background et ensuite la couleur. Sauf que comme le chiffre est de la couleur du background, si on retire le background et ensuite la couleur il ne reste plus rien. Il faut donc retirer le background AUTOUR du rond, et ensuite si on retire la couleur il devrait rester le chiffre sur fond blanc.
Pour se faire, j'ai tiré des traits depuis les bords de l'image jusqu'à ce qu'ils rencontrent le rond. Ensuite je retire tous les pixels entre le rond et les bords de l'image ce qui nous donne ceci :
Ensuite on peu retirer les pixels qui ont une valeur dans un channel RGB plus haute qu'un certain seuil :
Et la on a ce que l'on veut !
A partir de la c'est les filtres que l'on connait qui sont utilisés pour en faire une image plus facile à utiliser par Tesseract.
1 : On effectue un Resize de facteur 4 (oui c'est beaucoup mais en même temps le chiffre est vraiment petit à la base) qui permet d'avoir une image d'une bien meilleure résolution.
2: On fait une Dilatation de facteur 1 pour retirer tout le flou de l'image pour aider Tesseract
Et on a un chiffre qui est utilisable par Tesseract !
Explication des methodes précises plus bas
Pour résumer :
- On prend l'image de la zone et on la crop pour ne garder que la partie essentielle
- On détermine le type de pneu avec la couleur moyenne de la zone
- On retire le background autour de cette zone
- On retire la couleur qui reste pour ne garder que le chiffre
- On augmente la résolution du chiffre
- On rend ce chiffre net
- On envoie l'image traitée et filtrée à Tesseract
- On détermine le nombre de tours que le pilote a fait avec ses pneus avec le résultat de Tesseract
DRS
Bon ca c'était plutôt simple j'ai simplement vérifié si la moyenne de vert dépassait une certaine valeur et puis voila.
Filtres et methodes sur les images
Dans ce projet on a du utiliser différentes methodes d'édition d'image que ce soit sous forme de filtres ou de modification de l'image directement. Voici un sommaire des methodes utilisées et comment elles fonctionnent.
Tresholding
Cette methode sert à passer d'une image en couleurs à une image binaire noir blanc. C'est une étape très importante pour l'OCR car elle permet (si bien faite) d'isoler du texte de son background.
Un exemple ici :
Le fonctionnement est assez simple mais il peut être fait de différentes manières mais dans mon cas voici comment l'algorythme fonctionne sachant qu'il demande en entrée la Bitmap que l'on veut modifier ainsi que la valeur de Treshold :
- On parcours chaque pixel de l'image
- On convertir la couleur du pixel en une valeur de gris pour avoir la même valeur en R,G et B (Formule utilisée : grey = R x 0.3 + G x 0.59 + B x 0.11)
- Si le résultat de la valeur de gris est au dessus de la valeur de treshold, le pixel est passé en blanc complet et dans le cas contraire il est passé en noir complet
- On retourne la Bitmap modifiée
Un algorythme pas forcément complexe mais qui peut augmenter de manière titanesque les chances de réussir une OCR
Resize
Cette methode sert à augmenter la résolution d'une image pour améliorer la précision de l'algorythme de Tesseract. En effet, avec trop peu de pixels, la matrice de convolution n'est pas toujours aussi efficace.
Il ne faut pas confondre cette methode d'augmentation de la taille avec une simple interpolation. En effet une augmentation de taille interpolée ne vas pas vraiment changer la résolution, l'image sera toujours aussi pixelisée, seulement, les pixels seront composées de plus de pixels comme dans l'exemple ci dessous :
Dans mon projet j'utilise de l'interpolation bicubique qui va créer de l'information pour tenter de combler le vide et produire une image réellement plus grande et avec plus de details mais en ajoutant du flou.
Le but est d'aller chercher dans les pixels alentours les couleurs qui sont déja présente et de jouer avec des poids pour tenter de faire une prédiction de ce que ce pixel aurait été si l'image avait plus de detail.
Voici un exemple assez parlant :
On pourrait croire que c'est inutile mais dans le contexte de Tesseract ajouter des détails pour tenter de simuler une meilleure résolution même en créant du flou est intéressant pour mieux remplir la matrice de convolution.
Mais il est possible de réduire ce flou avec d'autres méthodes également.
(Dans mon code je n'ai pas utilisé du code fait main mais j'utilise une librairie qui me permet de le faire)
Il faut simplement faire attention car c'est un procédé assez lourd en performances.
Dilatation et Erosion
Cette methode et la suivante font partie des methodes de transformation morphologiques.
Ces methodes sont utilisées pour accentuer les formes et les epaissir ou les réduire et les affiner. Elles possèdent l'aventage également de retirer le flou d'une image ce qui est très pratique si utilisé après l'utilisation de methodes comme Resize.
Je ne vais pas trop rentrer dans les détails de ces methodes car leur fonctionnement est un peu plus lourd en math si on veut faire une véritable explication du pourquoi et du comment ca marche aussi bien. Pour notre projet je dirais que l'important est de savoir que ce sont deux outils très pratiques pour changer la morphologie des lettres et des chiffres et qu'on peut les utiliser pour corriger du flou et/ou des artéfacts apparus lors de la binarisation de l'image ou de la suppression de fond.
Remove Background
Cette methode est assez simple et est juste une methode qui va passer en revue tous les pixels de l'image et si la couleur d'un pixel s'apparente à celle d'un pixel de fond il est passé en noir total ou en blanc total. Le but est de permettre au reste du programme de fonctionner avec des couleurs moins ambigues.
Une variante spécialisée pour la reconnaissance des pneus appelée affectueusement Remove Useless cherche à atteindre le même bu mais est bien plus soffistiquée et spécialisée pour retirer le background autour d'un cercle de couleur pour ensuite retirer la couleur et qu'il ne reste qu'un chiffre. Pour plus de details voir la detection de pneus.
Il y aussi d'autre methodes comme un filtre Gaussien ou Highlight countour que j'ai du développer mais que je n'ai pas utilisé donc je ne vais pas en parler ici.
Interprétation des données
Stockage des données
Affichage des données
Prédictions
Tests
[A remplir au fur et à mesure de la création des tests]
Résumé des difficultés techniques
[A remplir au fur et à mesure dans la seconde moitié du travail de diplôme]
Optimisation du programme
[A remplir à la fin du projet pour parler des différentes methodes d'optimisation]
Ethique du projet
[A remplir à la fin du projet pour parler des questions ethiques du projet (Ex: Utilisation potentiellement abusive de la F1Tv ou L'histoire des cookies)]
Améliorations futures
[A remplir dans les dernières semaines du travail de diplôme]
Conclusion
[A remplir la dernière semaine du travail de diplôme]




















































