Aller au contenu

OCR et reconnaissance de texte

OculiX propose deux moteurs OCR aux compromis très différents.

Tesseract — embarqué

Écritures latines, mises en page simples, aucun processus externe. Livré dans le JAR via Legerix, zéro installation. C’est le bon choix par défaut.

PaddleOCR — serveur HTTP optionnel

Écritures CJK, scripts mélangés, mises en page complexes, exigence de précision haute. Tourne comme un petit serveur Python local, à installer séparément.

Rien n’empêche d’utiliser les deux dans le même script. Le choix se fait appel par appel, en fonction de ce qu’il y a à lire.

Tesseract est entièrement embarqué dans OculiX via Legerix. La coordonnée Maven io.github.oculix-org:legerix:5.5.0-4 apporte à la fois les binaires natifs et les fichiers tessdata dans le JAR. Rien à installer côté machine.

Langues fournies par défaut :

CodeLangue
engAnglais
fraFrançais
spaEspagnol
chi_simChinois simplifié
hinHindi
osdOrientation & Script Detection (auto-rotation)
from sikuli import *
# Lit tout l'écran
print Screen(0).text()
# → "File Edit View ... Save Cancel"
# Lit dans une region précise
btn_area = Region(100, 200, 300, 50)
print btn_area.text()

Region.text() lance Tesseract sur la capture de la region et renvoie le texte reconnu. Le contour englobant est nettoyé automatiquement. Pour la meilleure précision, capturez un crop serré autour du texte plutôt qu’une zone large.

# Repère le mot "Submit" à l'écran et clique dessus
target = Region(0, 0, 1920, 1080).findText("Submit")
target.click()

findText(label) renvoie un Match qui se manipule comme tout autre Match — clic, survol, frappe, chaînage. Utile quand l’image du bouton change (thème, icône dynamique) alors que son libellé reste stable.

Settings.OcrLanguage = "fra"
print Region(...).text() # lecture en français
Settings.OcrLanguage = "chi_sim"
print Region(...).text() # lecture en chinois simplifié

Tesseract expose deux familles de paramètres : Page Segmentation Modes (PSM) et OCR Engine Modes (OEM).

Settings.OcrPSM = 7 # bloc unique de texte uniforme (idéal pour un libellé court)
Settings.OcrPSM = 11 # texte épars — trouve tout ce qu'il peut
Settings.OcrOEM = 3 # défaut — combine neural et legacy

Le PSM 7 donne les meilleurs résultats pour reconnaître un libellé de bouton. Le PSM 11 est plus adapté à la lecture d’un paragraphe.

Pour les écritures CJK, le texte vertical, l’écriture manuscrite ou les mises en page bruitées, PaddleOCR est nettement supérieur à Tesseract. Il tourne comme un petit serveur HTTP Python avec lequel OculiX communique en localhost.

Fenêtre de terminal
pip install paddleocrserver-powered
paddleocrserver
# Écoute sur http://localhost:5000

Publié sur PyPI sous le nom paddleocrserver-powered. Stack Flask + Waitress, binaire unique, GPU optionnel.

from sikuli import *
from org.sikuli.script import PaddleOCREngine
ocr = PaddleOCREngine() # détecte automatiquement http://localhost:5000
# Capture la region, envoie au moteur
img = capture(Region(0, 0, 1920, 1080))
json = ocr.recognize(img.getFile())
# Récupère les coordonnées d'un texte à l'écran
coords = ocr.findTextCoordinates(json, "Validate")
if coords:
x, y, w, h = coords[0], coords[1], coords[2], coords[3]
click(Location(x + w//2, y + h//2))
results = ocr.parseTextWithConfidence(json)
for text, confidence in results.items():
print "%-30s %.2f" % (text, confidence)
# Submit 0.9997
# Cancel 0.9981
# 你好 0.9962

Écritures CJK

Chinois, japonais, coréen. PaddleOCR a été entraîné pour ces écritures de bout en bout, contrairement à Tesseract qui les traite en après-coup.

Scripts mélangés

Latin + asiatique dans la même image — PaddleOCR ne se perd pas, Tesseract si.

Texte vertical

Japonais ou chinois traditionnel imprimé verticalement, sur lequel Tesseract n’a aucune chance.

Précision sur images bruitées

Petites polices, antialiasing fort, fonds chargés, captures basse résolution.

Commons.loadTesseract() enchaîne quatre niveaux de repli à l’initialisation :

  1. Binaires natifs Legerix embarqués — première tentative.
  2. Tess4J + tessdata Legerix — deuxième niveau si le loader natif échoue.
  3. Binaire système tesseract — troisième niveau si la JVM ne charge pas le JNI.
  4. SikuliXception("Reinstall OculiX") — abandon.

En pratique on ne dépasse jamais l’étape 1. Si vous voyez ce repli se dérouler dans les logs, c’est presque toujours une installation corrompue — réinstallez le JAR ou recompilez depuis les sources.

Capturez serré

Tesseract traite ce qu’on lui donne. Une region ciblée tourne dix fois plus vite que l’écran entier.

Mettez le moteur en cache

Instanciez PaddleOCREngine une fois par script, pas à chaque appel. La connexion HTTP se réutilise.

findText() plutôt que text() + parsing

Pour cliquer sur un mot précis, un seul aller-retour suffit avec findText() au lieu de découper le texte renvoyé par text().

OCR uniquement si nécessaire

Un match PNG est toujours moins cher qu’un OCR. Gardez l’OCR pour les libellés réellement dynamiques.