samedi 10.03.2012, 14:00
OCR de meilleure qualité
Par Cédric Tabin - C/C++ - Lien permanent
Dans un précédent billet, j'avais fait un petit exemple avec tesseract (version 3.00) qui illustre le fonctionnement de la librarie pour reconnaître du texte dans une image. L'ayant essayé récemment sur des images avec du texte français, les résultats ne sont (vraiment) pas concluants.
Pour tester le tout, j'ai été sur wikipedia et j'ai fait une capture d'un morceau d'article pour voir comment tesseract s'en sort.
De base, en utilisant la dernière révision du svn (r703) avec le dictionnaire (eng.traineddata) anglais, voici le résultat obtenu:
L’Eurogroupe esl Ia réunlan mensuelle (e\ Infnrmelle) des mlnlslres des Finances des Elals membres de la zone euro, en vue d’y caordonner Ieur pollllque écnncmlque Créé par Ie Oonsell européen en 1997, |’Euragraupe a de facto vldé de sa substance Ie Consell des mlnlstres des Finances européens qul se uem Ie Iendemaln de la réunlon de |’Eurogroupe, dont u enténne Ies déclsmns, Le présldenl esl e'|u pour un mandatde 2,5 ans (nouveamé apporlée par Ie tralté de Llsbanne)‘ Actuellemenl, Ie présldenl esl Jean—C|aude Juncker, Ie Premier mlnlslre et mlnlstre du Trésar Iuxembcurgeaws, dnyen du conseu européen au 1*’ Janv\er2D05 En 2003, |’Eurograupe a cannu de nouvelles modlficalmns, quand n s'est réunl Ie 12 nclabre, au nlveau des chefs d’E|a| et de gouvernemenl, el a accuellll pour une demI—heure Gordon Brown, anclen Premier mlnlslre du Royaumeunl, un pays ne falsanl pas parlle de la zone euro
Visiblement, ça trouve déjà pas mal de choses, mais le taux de réussite est assez faible, surtout pour des mots relativement communs tels que économique ou réunion... Donc théoriquement, le dictionnaire français devrait mieux s'en sortir.
L’Eurogroupe est la réunron mensuelle (et tnformelle) des mrnrstres des Ftnances des Èlals membres de ta zone euro, en vue d'y coordonner teur potrtrque economrque Créé par te Oonsetl européen en 1997, |’Euragraupe a de recto vtdé de sa substance te consert des mrnrstres des Ftnances européens qut se trent te tendemarn de ta reunron de |’Eurogroupe, dont tl enténne tes déctstons, Le présrdent est étu pour un mandat de 2,5 ans (nouveauté apporlée par te trarte de Lrsponne)‘ Aotuettement, te présrdent est Jeawclaude Juneker, te Ptemter mrnrstre et mrnrstre du Tresor Iuxembcurgeats, doyen du Consetl européen au 1*’ Janvter2D05 En 2003, |’Euragraupe a connu de nouvettes modtficaltons, quand tl s'est réunr te t2 oclabre, au nrveau des cnets d’Èlal et de gouvernemenl, et a accuetllt pour une demrheure Gordon Brown, ancten Premter mrnrstre du Royaumeunr, un pays ne fatsanl pas partre de ta zone euro
Grossomodo, pas d'amélioration flagrante. J'ai cherché pendant un moment comment lui ajouter un dictionnaire spécifique, histoire qu'au moins il puisse récupérer les mots simples. J'avais finalement réussi à lui faire prendre en compte une liste de mot (fra.user-words) en allant modifier les sources, mais ça n'a rien changé:
// dans dict/dict.h - ligne 790 STRING_VAR_H(user_words_suffix, "user-words", "A list of user-provided words."); // dans dict/dict.cpp - ligne 54 STRING_INIT_MEMBER(user_words_suffix, "user-words", "A list of user-provided words.", getImage()->getCCUtil()->params())
Finalement la solution est venue grâce à cette question qui m'a permis de mettre à jour mon code ainsi que d'obtenir un excellent résultat.
L’Eurogroupe est la réunion mensuelle (et informelle) des ministres des Finances des États membres de la zone euro, en vue d’y coordonner leur politique économique. Créé par le Conseil européen en 1997, l’Eurogroupe a de facto vidé de sa substance le Conseil des ministres des Finances européens qui se tient le lendemain de la réunion de l’Eurogroupe, dont il entérine les décisions. Le président est élu pour un mandat de 2,5 ans (nouveauté apportée par le traité de Lisbonne)1. Actuellement, le président est Jean-Claude Juncker, le Premier ministre et ministre du Trésor luxembourgeois, doyen du Conseil européen au 1°’ janvier 2005. En 2008, l’Eurogroupe a connu de nouvelles modifications, quand il s'est réuni le 12 octobre, au niveau des chefs d’État et de gouvernement, et a accueilli pour une demi-heure Gordon Brown, ancien Premier ministre du Royaume-Uni, un pays ne faisant pas partie de la zone euro.
Non content du résultat obtenir, l'utilisation de l'API (notamment pour la lecture d'image) a été simplifiée. Désormais, le code consiste en 3 parties:
//lecture du fichier avec leptonica PIX* pix = pixRead(file); if (!pix) { fprintf(stderr, "Unable to read %s\n", file); return 1; } //transformations sur l'image pour améliorer l'OCR pix = pixConvertTo8(pix, 0); pix = pixScaleLI(pix, 4.0, 4.0); pix = pixContrastNorm(NULL, pix, 20, 20, 100, 2, 2); pix = pixGammaTRC(NULL, pix, 1.0, 50, 220); pix = pixThresholdToBinary(pix, 150); //reconnaissance d'écriture TessBaseAPI* api = new TessBaseAPI(); api->Init(argv[0], lang); api->SetImage(pix); const char* text = api->GetUTF8Text();
J'ai mis en fichier le code source de l'exemple. Pour pouvoir compiler, il faut installer leptonica (version 1.68) et faire un checkout de tesseract:
# installation leptonicy emerge -q leptonica # installation & compilation tesseract svn checkout -r 703 "http://tesseract-ocr.googlecode.com/svn/trunk" "tesseract-svn" cd "tesseract-svn" ./autogen.sh ./configure make -j9 cd .. # installation & compilation de l'exemple wget "http://www.astorm.ch/blog/public/Sources/tesseract-r703.zip" unzip "tesseract-r703.zip" mkdir "build" cd "build" cmake .. make # test (avec multilangue) ln -s "../tesseract-svn/tessdata" ".tessdata" export TESSDATA_PREFIX="." ./tesseract-test "fra+eng" "../sample.png"
