Et oui c’est encore moi Aujourd’hui je viens à la fois demander de l’aide théorique et présenter ce que je souhaite faire.
Comme l’indique le titre, le but de ce "mini" projet (il n’est pas petit mais je peu de temps à lui allouer à cause de mon autre projet ZONNY) est d’extraire des données clés de tickets de caisse : le TTC, la TVA, la date et le nom du magasin émetteur du ticket de caisse. Vous vous rendrez compte que ce projet est assez ambitieux et demande du temps. Or, je n’ai pas forcément beaucoup de temps. Je trouverai donc pour résoudre ce problème un compris résultat/temps.
Ce problème se découpe en deux parties :
L’extraction du texte du ticket de caisse. C’est convertir l’image en texte quoi ! Cela est fait par de l’optical character recognition (OCR)
L’extraction des données clés à partir d’un bloc de texte (celui obtenu à l’étape 1).
Ce projet sera réalisé en PHP et sera Open-Source.
La première partie est actuellement assurée par Tesseract https://github.com/tesseract-ocr/tesseract Après plusieurs essais, la version 4.0 qui est en alpha est celle qui rend les meilleurs résultats https://github.com/tesseract-ocr/tesseract/wiki/4.0-with-LSTM Le problème est que la reconnaissance de texte peut prendre plus ou moins de temps et le résultat plus ou moins mitigé. Actuellement, l’image est uploadé sur le serveur, et la commande tesseract file.jpg stdout -l FRA -psm 6 est lancée. Les résultats peuvent-être très variable en fonction de la taille de l’image, de sa luminosité etc.
Il faudra donc avant de lancer Tesseract effectuer quelques pré étapes comme : recadrer l’image selon les bords, enlever le bruit, définir la résolution de l’image, modifier les couleurs… Les étapes sont résumés ici : https://github.com/tesseract-ocr/tesseract/wiki/ImproveQuality
L’extraction des données clés à partir du bloc de texte est actuellement gérée par une série de REGEX. Même si les résultats sont acceptables, ils ne sont pas extraordinaires. En effet, s’il y a plusieurs dates, plusieurs TVA, les REGEX sont complètements perdues (Bien que les TVA sont additionnées pour le moment). En tombant sur cet article génialissime https://zestedesavoir.com/articles/1654/deep-learning-cest-quoi/ (merci @Orpheo !), j’ai envisagé une solution de machine learning. Très clairement, je n’en n’ai fais qu’une seule fois et c’était un cas bien plus simple. Je ne sais pas si c’est possible à mettre en place et par où commencer. Enfin, avant de lancer l’idée, j’ai quand même pris le temps de trouver un dataset de tickets de caisse et j’en ai trouvé un composé de 1969 éléments : http://receipts.univ-lr.fr/
Je ne sais pas si c’est suffisant (on doit probablement pas pouvoir le savoir à l’avance). J’ai regardé du côté des librairies de machine learning en PHP et la principale semble être https://github.com/php-ai/php-ml
La documentation est très bonne mais je ne sais vraiment pas par où commencer : cela m’étonnerai par exemple que les méthodes de classifications SVC ou k-Nearest Neighbors soient adaptées ! On pourra d’ailleurs se servir de ce dataset pour entrainer Tesseract également.
Je n’ai pas encore crée de repos Git avec mon travail actuel mais cela arrive bientôt !
Pour le moment je souhaite me concentrer sur la partie 2. Me conseillez-vous de rester sur un système complexe de REGEX ou de partir à l’aventure dans le machine learning ? Si oui, vers où dois-je me tourner ?
Merci d’avance pour vos réponses
EDIT : Après coup je me demande si ce post devrait pas être dans "Vos projets".
Ce soir, je me suis concentré sur le prétraitement de l’image. Sans ce prétraitement, le temps d’exécution de Tesseract est très long et les résultats moins bons. Les différentes étapes du prétraitement du ticket de caisse sont donc :
Définir une précision de 400 DPI
Recouper l’image pour ne garder que le ticket de caisse (et enlever les contours inutiles de la photo).
Binariser l’image en niveaux de gris.
Le tout est fait avec ImageMagick. Définir la précision et la binarisation ne pose pas problème. Le plus compliqué est le redécoupage de l’image.
La solution actuelle utilisée est la suivante : http://www.imagemagick.org/Usage/crop/#trim Pour résumer ce qu’elle fait, elle tente de supprimer les couleurs en bordures qui ne correspondent pas au blanc du ticket de caisse.
La ligne utilisée en PHP est équivalente à
convert input.jpeg -fuzz 45% -trim output.jpg
Plus le paramètre fuzz est élevé et plus l’image sera redécoupée. Si le paramètre est trop élevé, l’image devient un point microscopique (et là on peut plus rien faire ). J’ai donc choisi le paramètre en faisant la moyenne des valeurs optimales pour une quinzaine de tickets. Ce n’est pas optimal certes mais au moins c’est rapide !
L’autre solution proposée est la suivante : http://www.imagemagick.org/Usage/crop/#trim_blur Cette solution semble plus adaptée (bien que parfois la première découpe mieux) mais se décompose en deux étapes. Le temps d’exécution est donc bien plus long… Si vous avez une solution plus simple, adaptée ou rapide n’hésitez pas !
J’avais initialement prévu d’autres tâches de prétraitements comme le suppression de bruits ou encore le lissage des caractères (car l’ancre sur les tickets est de très mauvaise qualité) mais cela prend un temps fou ! Plus de 10 sec sur un i7 avec 6 Go de RAM donc ça pourra pas être plus rapide sur un petit VPS…
Sinon, le dernier commit 55e319fc ajoute la reconnaissance de l’image pré-traitée par Tesseract. Tesseract retourne le contenu sous forme HTML avec la taille estimée des caractères. Cela sera utile pour l’extraction des noms des magasins par exemple (et même pour les prix TTC qui sont souvent affichés en gros). Il faut encore ajouter les fichiers d’entraînement français aussi.
Résultat obtenu pour le ticket de caisse ci-dessus :
Je continue d’avancer de temps en temps quand j’ai quelques minutes de libres ! Même si personne ne semble réellement intéressé, je poste tout de même. On ne sait jamais, peut-être que certains seront content de trouver ce petit travail un jour !
Le dernier commit #0c155838 ajoute l’extraction du contenu HTML (dans le post précédent) en un tableau contenant les morceaux de textes et leurs tailles correspondantes. Le tableau est trié par ordre de taille de texte. L’objectif est de récupérer le texte avec la plus grande taille et de le considérer comme le titre du ticket de caisse (nom du magasin)… Ce n’est pas une solution optimale mais je ne vois pas comment faire autrement Avez-vous des idées svp ?
Aussi, Tesseract est maintenant exécutée pour une utilisation avec du contenu Français. Il s’agit simplement de l’ajout du paramètre l- FRA (lien). Mais dans tous les cas je ne vois pas sensiblement de différence avant ou après l’ajout de ce paramètre…
En effet, j’ai fais un peu de rangement sur mon compte GitLab. Je vais essayer de re-upload ce projet le plus rapidement possible.
Le projet a été mis en pause mais était capable à 60% de trouver les bonnes informations (TVA, TOTAL, nom du magasin et date).
La solution utilisée n’était cependant extraordinaire :
Prétraitement avec Imagick ;
Analyse avec Tesseract (récupération d’un fichier HTML avec les positions et tailles des différents blocs de textes trouvés) ;
Utilisation d’expressions régulières (regexs) sur le fichier HTML.
Nous n’avons pas réussi à rapidement dépasser ces 60%. Le problème majeur était dû à Tesseract. À plusieurs reprises, le fichier HTML retourné par Tesseract était composé de chaînes de caractères aberrantes (et pourtant pour des tickets de caisses parfois simple). Aussi, de nombreuses fois les tailles des textes ne sont pas bonnes (alors que pour le nom du magasin la taille du texte est un élément déterminant).
Une nouvelle solution devient néanmoins bientôt possible. Le dataset disponible à cette adresse : http://receipts.univ-lr.fr/ va être très prochainement accessible. En effet, pour que cela devienne le cas, il faut que les 1969 tickets de caisses aient été corrigés manuellement par un visiteur du site : http://receipts.univ-lr.fr/correct-ocr-results/ À l’heure où j’écris ce message, 1751 tickets ont été corrigés.
Je ne connais pas exactement ton besoin (pourquoi faire de l’extraction de données de tickets de caisses), mais il y a parfois d’autres solutions plus simples quand il s’agit d’une application mobile par exemple.
Connectez-vous pour pouvoir poster un message.
Connexion
Pas encore membre ?
Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte