Spaces:
Sleeping
Sleeping
Architecture du module IA
Vue d'ensemble
Photo du terminal
│
▼
┌─────────────────────┐
│ preprocessing.py │ détection de l'écran LCD (contours) puis
│ │ découpage en 3 lignes (prix / volume / prix_litre)
└─────────┬────────────┘
▼
┌─────────────────────┐
│ recognizer.py │ CRNN fine-tuné : lit chaque ligne, renvoie
│ (models/*.pt) │ {field, text, confidence} par valeur
└─────────┬────────────┘
▼
┌─────────────────────┐
│ postprocess.py │ normalise les nombres (virgule/point),
│ │ calcule la valeur manquante, vérifie
│ │ montant = litres × prix
└─────────┬────────────┘
▼
┌─────────────────────┐ ┌─────────────────┐
│ rules.py │◄──────│ quality.py │ flou / luminosité
│ décide success/blocage │ └─────────────────┘
└─────────┬────────────┘
▼
réponse API (main.py)
Pourquoi ce découpage en modules séparés
Chaque étage a une responsabilité et une durée de vie différentes :
- preprocessing et quality : de la vision par ordinateur classique (OpenCV), aucune dépendance au modèle de reconnaissance. Réutilisable même si on change de modèle IA demain.
- recognizer : la seule brique qui dépend du modèle entraîné. Isolée pour pouvoir la remplacer (nouvelle version du CRNN, ou un autre modèle) sans toucher au reste.
- postprocess : logique métier pure (aucune I/O, aucun modèle) — donc
entièrement testable sans charger le CRNN (voir
tests/test_postprocess.py, instantané). - rules : la décision finale (bloquer/valider) séparée du calcul, pour
pouvoir ajuster les seuils (
config.py/config.yaml) sans toucher à la logique de calcul.
Différence avec le prototype précédent (OCR générique)
L'ancienne version du projet (racine du dépôt, src/, api/) utilisait
PaddleOCR/EasyOCR : des modèles pré-entraînés génériques, avec toute une
mécanique de variantes d'image et de repli entre moteurs pour compenser
leur manque de spécialisation. Ce module utilise à la place un modèle
entraîné sur nos propres données (voir train/), ce qui simplifie le
post-traitement : le CRNN sait déjà quelle ligne correspond à quel champ
(par position), il n'y a donc plus besoin d'heuristique de proximité de
libellé ni de deviner "quel nombre est le montant" par magnitude — la
principale source d'erreur du prototype précédent.
Fichiers clés
| Fichier | Rôle |
|---|---|
app/preprocessing.py |
détection écran + découpage lignes |
app/recognizer.py |
chargement CRNN + inférence |
app/postprocess.py |
normalisation, calculs, cohérence |
app/rules.py |
porte de décision succès/blocage |
app/config.py |
seuils configurables |
app/main.py |
API FastAPI |
train/finetune_doctr.py |
entraînement du CRNN |
docs/LIMITATIONS.md |
limites connues du modèle actuel |