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 | | |