Spaces:
Sleeping
Sleeping
| # 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. | |