web-dev-qa-db-fra.com

Utilisation de tesseract pour reconnaître les plaques d'immatriculation

Je développe une application qui reconnaît les plaques d'immatriculation (ANPR). La première étape consiste à extraire les plaques d'immatriculation de l'image. J'utilise OpenCV pour détecter les plaques en fonction du rapport largeur/hauteur et cela fonctionne plutôt bien:

extracting license plates

extracting license plates

Mais comme vous pouvez le voir, les résultats de l'OCR sont assez mauvais.

J'utilise tesseract dans mon Objective C (iOS) environnement. Voici mes variables init lors du démarrage du moteur:

// init the tesseract engine.
    tesseract = new tesseract::TessBaseAPI();
    int initRet=tesseract->Init([dataPath cStringUsingEncoding:NSUTF8StringEncoding], [language UTF8String]);
    tesseract->SetVariable("tessedit_char_whitelist", "BCDFGHJKLMNPQRSTVWXYZ0123456789-");
    tesseract->SetVariable("language_model_penalty_non_freq_dict_Word", "1");
    tesseract->SetVariable("language_model_penalty_non_dict_Word ", "1");
    tesseract->SetVariable("load_system_dawg", "0");

Comment puis-je améliorer les résultats? Dois-je laisser OpenCV faire plus de manipulation d'images? Ou puis-je améliorer quelque chose avec tesseract?

36
unicorn80

Deux choses vont résoudre ce problème complètement:

  1. Supprimez tout ce qui n'est pas du texte de l'image. Vous devez utiliser un CV pour trouver la zone de la plaque (par exemple par couleur, etc.), puis masquer tout de l'arrière-plan. Vous voulez que l'entrée à tesseract soit en noir et blanc, où le texte est noir et tout le reste est blanc

  2. Supprimer l'inclinaison (comme mentionné par FrankPI ci-dessus). tesseract est censé fonctionner correctement avec le biais (voir " Tesseract OCR Engine " aperçu par R. Smith) mais d'un autre côté cela ne fonctionne pas toujours , surtout si vous avez une seule ligne par opposition à quelques paragraphes. Il est donc toujours préférable de supprimer l'inclinaison manuellement d'abord, si vous pouvez le faire de manière fiable. Vous saurez probablement la forme exacte du trapèze de délimitation de la plaque à partir de l'étape 1, donc cela ne devrait pas être trop dur. Dans le processus de suppression de l'inclinaison, vous pouvez également supprimer la perspective: toutes les plaques d'immatriculation ont (généralement) la même police, et si vous les redimensionnez à la même forme (sans perspective), les formes des lettres seraient exactement les mêmes, cela aiderait reconnaissance de texte.

Quelques conseils supplémentaires ...

N'essayez pas de coder cela au début: prenez une image OCR très simple (c'est-à-dire directement de devant, sans perspective) d'une plaque, modifiez-la dans photoshop (ou gimp) et exécutez-la via tesseract sur la ligne de commande. Continuez à éditer de différentes manières jusqu'à ce que cela fonctionne. Par exemple: sélectionnez par couleur (ou sélectionnez les formes des lettres), remplissez de noir, inversez la sélection, remplissez de blanc, transformez la perspective de façon à ce que les coins de la plaque soient un rectangle, etc. angles, etc.). Faites-le avec chacun d'eux. Une fois que cela fonctionne complètement, réfléchissez à la façon de créer un algorithme CV qui fait la même chose que vous avez fait dans Photoshop :)

P.S. En outre, il est préférable de commencer avec une image de résolution supérieure si possible. Il semble que le texte de votre exemple mesure environ 14 pixels de haut. tesseract fonctionne assez bien avec du texte en 12 points à 300 dpi, c'est environ 50 pixels de haut, et il fonctionne beaucoup mieux à 600 dpi. Essayez de faire en sorte que la taille de votre lettre soit d'au moins 50, de préférence 100 pixels.

P.P.S. Faites-vous quelque chose pour former tesseract ? Je pense que vous devez le faire, la police ici est suffisamment différente pour être un problème. Vous avez probablement aussi besoin de quelque chose pour reconnaître (et non pénaliser) les tirets qui seront très courants dans vos textes, comme dans le deuxième exemple "T-" est reconnu comme H.

50
Alex I

Je ne connais pas trop tesseract, mais j'ai quelques informations sur l'OCR. Et c'est parti.

  • Dans une tâche OCR, vous devez vous assurer que vos données de train ont la même police que vous essayez de reconnaître. Ou si vous essayez de reconnaître plusieurs polices, assurez-vous d'avoir ces polices dans vos données de train pour obtenir les meilleures performances.
  • Pour autant que je sache, tesseract applique l'OCR de différentes manières: Premièrement, vous donnez une image qui contient plusieurs lettres et laissez tesseract effectuer la segmentation. Et d'autre part, vous donnez des lettres segmentées à tesseract et vous attendez seulement à ce qu'il reconnaisse la lettre. Vous pouvez peut-être essayer de changer celui que vous utilisez.
  • Si vous entraînez vous-même le programme de reconnaissance, assurez-vous que vous disposez de suffisamment et de la même quantité de chaque lettre dans vos données de train.

J'espère que cela t'aides.

13
guneykayim

J'ai travaillé sur une application iOS, si vous avez besoin d'améliorer les résultats, vous devriez former l'OCR tesseract, cela s'est amélioré de 90% pour moi. Avant le balayage, les résultats de l'OCR étaient plutôt mauvais.

Donc, j'ai utilisé ce Gist dans le passé pour former tesseract ORC avec une police de plaque d'immatriculation.

Si vous êtes intéressé, j'ai ouvert ce projet il y a quelques semaines sur github

8
chroman

Voici mon exemple du monde réel avec l'essai d'OCR à partir de mon ancien wattmètre. Je voudrais utiliser votre code OpenCV pour qu'OpenCV recadre automatiquement l'image, et je ferai des scripts de nettoyage d'image.

  • La première image est l'image d'origine (numéros des wattmètres rognés)
  • La deuxième image est légèrement nettoyée dans GIMP, environ 50% de précision OCR dans tesseract
  • La troisième image est une image entièrement nettoyée - 100% OCR reconnue sans aucune formation!

enter image description hereenter image description hereenter image description here

2
valentt

Maintenant, la plaque d'immatriculation peut être facilement reconnue par mlmodel. J'ai créé le modèle de base que vous pouvez trouver ici . Vous avez juste besoin de diviser les caractères en résolution 28 * 28 via le cadre de vision et d'envoyer cette image à VNImageRequestHandler comme indiqué ci-dessous-

let handler = VNImageRequestHandler(cgImage: imageUI.cgImage!, options: [:])

vous obtiendrez les résultats souhaités en utilisant mon core mlmodel. Utilisez le lien this pour une meilleure clarification mais utilisez mon modèle pour de meilleurs résultats dans la reconnaissance des plaques d'immatriculation. J'ai également créé le mlmodel pour la reconnaissance des plaques d'immatriculation.

1