Files
TrackTrendsDoc/docs/jdb.md
T

12 KiB

Journal de bord

Avant de commencer pour de bon je veux être certain d'utiliser la bonne methode d'OCR

Je vais tester IronOcr

Source : https://www.c-sharpcorner.com/article/ocr-using-tesseract-in-C-Sharp/ Doc : https://ironsoftware.com/csharp/ocr/docs/ Examples : https://ironsoftware.com/csharp/ocr/examples/simple-csharp-ocr-tesseract/

Avant d'utiliser la librairie je me demande si je dois utiliser un peu de post processing pour aider à la reconnaissance.

Je peux soit utiliser l'image cropée directement :

"Image non traitée"

Soit avec un filtre pour passer en noir et blanc laxiste

"Image traitée laxiste"

Soit avec un filtre pour passer en noir et blanc stricte

"Image traitée stricte"

Il va falloir faire des tests avec tous les noms et les chiffres pour trouver le plus efficace.

Bon malheureusment Iron OCR semblait être une bonne alternative mais c'est une librairie privée qui demande une license pour être utilisée. Il va falloir trouver autre chose.

En utilisant la librairie "Tesseract" qui existe on peut faire de la reconnaissance de texte avec un code plutôt simple :

TesseractEngine engine = new TesseractEngine(tessDataFolder.FullName,"eng", EngineMode.Default);
            
var tessImage = Pix.LoadFromMemory(ImageToByte(sample));

Page page = engine.Process(tessImage);
string text = page.GetText();

Voici la methode ImageToByte : https://stackoverflow.com/questions/7350679/convert-a-bitmap-into-a-byte-array

public static byte[] ImageToByte(Image img)
{
    using (var stream = new MemoryStream())
    {
        img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
            return stream.ToArray();
        }
}

Voici le code pour traiter plusieurs textes sur une seule image :

Page page = engine.Process(tessImage);
            // Get the iterator for the page layout
            using (var iter = page.GetIterator())
            {
                // Loop over the elements of the page layout
                iter.Begin();
                do
                {
                    // Declare a Rect variable to hold the bounding box
                    Rect boundingBox;

                    // Get the bounding box for the current element
                    if (iter.TryGetBoundingBox(PageIteratorLevel.Word, out boundingBox))
                    {
                        g.DrawRectangle(Pens.Red,new Rectangle(boundingBox.X1,boundingBox.Y1,boundingBox.Width,boundingBox.Height));
                    }

                    // Get the text for the current element
                    var text = iter.GetText(PageIteratorLevel.Word);
                    tbxResult.Text += text.ToUpper() + Environment.NewLine;
                } while (iter.Next(PageIteratorLevel.Word));
            }

Etonnament, avec plus de texte, des noms qui étaient autrefois mal reconnus sont parfaitement interprêtés.

Par exemple voici un exemple de reconnaisance de texte sur tous les pilotes :

"Screenshot de reconnaisance d'image complete"

On voit que le nom Leclerc est mal reconnu. Mais voici ce que cela donne quand on prend une image qui ne contient que le nom Leclerc :

"Screenshot de reconnaissance d'image cropée"

On voit ici que le nom Leclerc est très bien reconnu.

Dans le premier exemple on peut voir que Tsunoda est reconnu comme "Reticin" ce qui n'est pas exactement pareil (lol)

Et quand on isole le nom Tsunoda dans une image seule :

"Screenshot de reconnaissance de Tsunoda"

Il le lit "RETLELYY" ce qui n'est toujours pas exactement ca...

Une meilleure résolution pourrait peut-être résoudre le problème en partie.

Jusqu'ici les images étaient en presque 720P ce qui donne ceci :

"Tsunoda en 720P"

Et j'ai lancé une récupèration d'images en 1080p pour récupèrer ceci :

"Tsunoda en 1080P"

On peut voir une certaine différence tout de même.

Et quand on lance la reconnaissance :

"Reconnaissance Tsunoda en 1080P"

"Tsunoda n'est plus écrit "RETLELYY" mais "TSUNDDA" ce qui n'est pas parfait mais qui est déja beaucoup mieux.

J'ai essayé de mettre l'engine de Tesseract en mode "JPN" comme Tsunoda est un nom japonais mais sans succès j'ai le même résultat.

Comme la résolution est meilleure je me suis dit que peut être le filtre de passage en noir et blanc pourrait aider.

J'ai écrit cette petite methode pour convertir l'image en noir et blanc :

private static Bitmap ConvertToBlackAndWhite(Bitmap inputBmp)
        {
            const int BLACK_TO_WHITE_TRESHOLD = 200;
            Bitmap result = new Bitmap(inputBmp.Width, inputBmp.Height);

            for (int y = 0; y < inputBmp.Height; y++)
            {
                for (int x = 0; x < inputBmp.Width; x++)
                {
                    Color pixelColor = inputBmp.GetPixel(x,y);
                    if (pixelColor.R <= BLACK_TO_WHITE_TRESHOLD && pixelColor.G <= BLACK_TO_WHITE_TRESHOLD && pixelColor.B <= BLACK_TO_WHITE_TRESHOLD)
                    {
                        pixelColor = Color.FromArgb(0,0,0);
                    }
                    else
                    {
                        pixelColor = Color.FromArgb(255,255,255);
                    }
                    result.SetPixel(x,y,pixelColor);
                }
            }
            return result;
        }

Rien de bien dingue mais cela fonctionne et je peux jouer avec le BLACK_AND_WHITE_TRESHOLD pour changer son comportement.

J'ai dabord testé avec un treshold de 100 et le programme a réussi à me sortir Tsunoda en deux mots ce qui était déja très encourageant.

Et après avoir augmenté le Treshold... Tada :

"Tsunoda 1080P avec filtre"

Le programme arrive bien à reconnaitre TSUNODA. Je pense que cette tactique ne fonctionnait pas avant car la resolution était trop faible et l'aliasing se mêlait trop avec le texte pour être utilisable.

Cependant cette technique ne fonctionne pas sur tous les noms. Par example avec Leclerc :

"Leclerc 1080P avec filtre"

On récupère "Leeler'c" ce qui n'est pas bon du tout.

Mais en modulant le Treshold (ici à 150) On peut de nouveau voir Leclerc être reconnu correctement

"Leclerc 1080P avec filtre 2"

Je pense que pour avoir de bons résultats il va falloir faire un algo qui :

  • Découpe l'image en autant de plus petites images pour avoir un mot par image.
  • Teste voir si avec l'image originale un nom correspond à la liste de pilotes existant.
  • Si cela ne marche pas, on applique le filtre en modulant le Treshold.
  • Dans le cas ou on aurait pas un match parfait on fait un algo qui cherche le nom le plus proche qui existe dans la liste de noms donnés.

Seulement voila, il n'y a pas que des lettres que l'on veut récupèrer. On veut surtout pouvoir récupèrer les chiffres.

Pour les chiffres on va avoir des soucis également...

Si on essaie directement la même technique sans filtre on a des résultats comme celui ci :

"Tentative de reconnaisance du timing"

La virgule a tendeance à se barrer ce qui est particulièrement problématique. Cependant comme les chiffres ont beaucoup moins de possibilitées que les lettres et qu'il n'y a pas de problème de langue on devrait pouvoir travailler à faire des règlage que l'on pourra ensuite utiliser.

Avec un Treshold de 165 on arrive presque à quelque chose d'intéressant :

"Tentative 2 de reconnaissance du timing"

Le + n'est clairement pas compris mais ca n'est pas embêtant car c'est souvent redondant. On arrive cependant à isoler 3 et 259. Même si la virgule n'est pas comprise cela veut dire qu'il est tout de même possible de discriminer les secondes des milisecondes.

Maintenant avec un temps au tour :

"Reconnaissance du timing au tour"

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.

Demain ce qui serait bien cela serait que je fasse un jeu d'images avec des valeurs connues et que je fasse une batterie de tests pour voir à quel point je peux faire confiance à la reconnaissance des chiffres.

Automatiser un système de test de la sorte me sera très utile dans le futur pour vérifier la non regression de ma reconnaissance de texte quand je tenterai d'y faire des changements.

Je suis toujours curieux cependant de voir comment le programme se débrouille avec les nombres de tours qui se trouvent dans les icones de pneus.

Journal de bord

Mercredi 29 Mars 2023


Premier jour du travail de diplôme. Nous avons eu un briefing de mr Garcia et nous avons pu commencer à préparer le travail.

Nous avons eu les différents fichiers nescessaires à la bonne réalisation du projet et je me suis mis à faire les fichiers nescessaires

La première chose a été de faire ce mkdocs dans lequel j'ai mis un fichier yml plutôt standart qui risque de changer au fur et à mesure.

Voici le premier yml :

site_name: Documentation Diplome
theme:
        name: material
        palette:
        # Palette toggle for light mode
        - media: "(prefers-color-scheme: light)"
          scheme: default
          toggle:
          icon: material/brightness-7
          name: Switch to dark mode

        # Palette toggle for dark mode
        - media: "(prefers-color-scheme: dark)"
          scheme: slate
          toggle:
          icon: material/brightness-4
          name: Switch to light mode
markdown_extensions:
  - attr_list
  - md_in_html
plugins:
  - glightbox
  - with-pdf

Voici un example de à quoi ca ressemble en forme de site

"Exemple mkdocs"

Ensuite il m'a fallu faire une version plus à jour de mon cahier des charges car je n'y avait pas touché depuis novembre. J'ai envoyé un mail à mes enseignants pour qu'ils puissent y jeter un oeuil pour être sûr que je n'ai rien changé qui les dérangent.

Monsieur Jayr m'a demadé à l'occasion de lui faire un planning type Gantt alors je me suis mis à la tâche.

J'ai fait un planning prévisionnel et une légende les deux sont dispo dans le dossier planning de ce repertoire.

Ensuite je me suis mis à tout mettre sur git. A commencer par ce repertoire

Et c'est deja la fin de la journée ! Demain j'avance un peu sur la doc avec ce que je peux déja remplir et je finis de préparer ce dont j'ai besoin pour commencer à coder.

Jeudi 30 Mars 2023


Aujourd'hui selon le planning je dois me charger des dernirers préparatifs pour commencer correctement. J'ai fait exprès de prenre du temps pour ca au début pour ne pas me créer de soucis plus loin pendant le travail.

Je vais envoyer par mail le planning que j'ai fait à mes suiveurs.

Ensuite je vais m'attaquer au squelette de la docmentation. Je vais essayer de remplir tout ce que je peux remplir dans un premier temps car cela tout ca de fait pour plus tard quitte à modifier quelques aspects au fur et à mesure.

J'ai aussi désactivé mkdocs with pdf par ce que les résultats ne sont vraiment pas ceux que j'attends et cela ralentis énormément le déploiment.

J'ai aussi rassemblé mes croquis pour le poster :

"Croquis Poster 1" "Croquis Poster 2"

On peut voir que dans un premier temps j'ai tenté de faire un poster un peu plus stylisé et marketing. Cependant après avoir discuté avec Mr Garcia et différents profs dont un de l'HEPIA et ils m'ont indiqué que ce qui était attendu était moins du marketing qu'un diagramme de fonctionnement.

On peut voir sur les derniers posters que le coté technique ressort de plus en plus. Le but sera de faire une version encore plus technique ou on peut voir les différents fonctionnements de l'application avec les technologies utilisées.

Le défi cela va être de faire un joli poster qui soit en même temps vendeur et en même temps rempli techniquement.

ATTENTION!!! NE PAS OUBLIER DE RENDRE LE JOURNAL DE BORD UNE FOIS QU'IL A ETE VALIDE !!! DERNIER JOUR