Spaces:
Sleeping
Sleeping
File size: 3,010 Bytes
b510add | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | # Reconnaissance CRNN (`app/recognizer.py`)
## Le modèle
`crnn_vgg16_bn` (bibliothèque [doctr](https://github.com/mindee/doctr)) :
un CNN (VGG16) qui extrait des features le long de l'image, suivi d'un
RNN qui prédit une séquence de caractères — architecture standard pour la
reconnaissance de texte en une ligne (pas besoin de segmenter les
caractères un par un).
Poids de départ : pré-entraînés par Mindee sur des textes imprimés
génériques, puis **fine-tunés** sur nos propres crops de lignes LCD
(voir `docs/TRAINING.md`). C'est ce fine-tuning qui constitue le "modèle IA
développé" attendu par le §8.4 du cahier des charges, par opposition à un
OCR générique utilisé tel quel.
## `load_model(model_path=None, device=None)`
Charge les poids depuis `models/crnn_fuel_pump_best.pt` (chemin par défaut).
Échoue explicitement (`FileNotFoundError`/`ImportError`) plutôt que de se
rabattre silencieusement sur autre chose — un module de vérification de
paiement ne doit pas tourner avec un modèle absent sans que ce soit visible.
## `recognize_screen(model, screen_crop, device, n_lines=3)`
1. Découpe l'écran en lignes (`preprocessing.split_lcd_lines`).
2. Pour chaque ligne, dans l'ordre : prétraitement (`preprocess_crop`) puis
prédiction (`predict_line`).
3. Associe chaque ligne à un champ (`prix`, `volume`, `prix_litre`) par sa
**position** (voir `FIELD_NAMES` dans `preprocessing.py`) — pas par
analyse du contenu. C'est la différence clé avec l'ancien pipeline OCR
générique, qui devait deviner quel nombre était quoi.
Retourne une liste de `{"field": ..., "text": ..., "confidence": ...}`,
un élément par ligne détectée.
## `preprocess_crop` / `_resize_preserve_aspect` — le bug corrigé cette session
Redimensionne chaque ligne à une hauteur fixe (32px) **en conservant le
ratio d'aspect**, puis normalise les valeurs de pixels.
**Pourquoi c'est écrit deux fois** (ici et dans `train/finetune_doctr.py`) :
le modèle doit voir, à l'entraînement et à l'inférence, des images
prétraitées de la **même façon**. Avant correction, l'entraînement étirait
les images à une largeur fixe (déformant les chiffres), alors que
l'inférence préservait le ratio — le modèle apprenait donc sur des formes
différentes de celles qu'il voyait réellement en production. Si l'un des
deux fichiers est modifié à l'avenir, vérifier que l'autre reste cohérent.
## Limites connues
- Le decoder CTC de doctr peut produire des caractères hors du vocabulaire
numérique attendu (ex. "9AAm" au lieu de "20000" observé pendant les
tests) quand la ligne d'entrée est trop bruitée/mal découpée — normal vu
la taille du jeu d'entraînement (voir `docs/LIMITATIONS.md`), pas un bug
de code.
- Aucune contrainte n'est imposée sur le vocabulaire de sortie (le modèle
pourrait techniquement prédire des lettres) — une piste d'amélioration
serait de contraindre le décodage aux chiffres/virgule/point uniquement.
|