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.