Pôle HTR des hackathons du master Humanités numériques de l'École nationale des chartes-PSL (janvier 2026). Travail collectif (dir. Chahan Vidal-Gorène et Alexandre Lionnet-Rollin).
Projets concernés :
- One prompt to rule them all? Compet. d’HTR de manuscrits médiévaux français - École nationale des chartes-PSL, ERC LostMa (dir. Jean-Baptiste Camps)
- Text Acquisition Pipeline for Early-Modern Latin Manuscripts - École nationale des chartes-PSL, ANR (dir. Katarzyna Kapitan)
- Abbreviations and algorithms - The Icelandic challenge - École nationale des chartes-PSL, ANR (dir. Paola Peratello)
pip install -r requirements_htr.txtModèle YOLO requis: models/LINES-bbox_YOLOv11n.pt
scripts/
├── modules/
│ ├── layout_detection.py
│ ├── model_wrappers.py
│ ├── data_processing.py
│ └── yolo_detection.py
├── app_gradio.py
├── htr_pipeline_modular.py
└── sort_lines-topological.py
Le pipeline est organisé en modules dans scripts/modules/:
Détection de la mise en page des documents.
Fonctions:
detect_layout()- Détection des paragraphes et lignesunify_rows()- Regroupement des lignesunify_paragraphs()- Fusion des paragraphesget_horizontal_breakpoints()/get_vertical_breakpoints()- Analyse spatiale
Dépendances: numpy, pandas, scipy
Wrappers pour les modèles HTR.
Classes:
TrOCRMedievalWrapper- TrOCR médiévalQwenWrapper- Qwen3-VL (4B/8B) avec adapter CatmusMiniCPMWrapper- MiniCPM-Llama3-V-2.5 (modes ABBR/NOT_ABBR)
Support quantization 4-bit optionnelle via bitsandbytes.
Dépendances: torch, transformers, peft, PIL
Chargement et traitement des données.
Fonctions:
load_image()- Charge une imageconvert_yolo_to_bbox()- Conversion coordonnées YOLOprocess_detections()- Pipeline complet de traitementget_crop_coordinates()- Calcul coordonnées de crop
Dépendances: cv2, pandas
Détection des lignes via YOLOv11.
Classes:
YOLOLineDetector- Détecteur de lignes
Dépendances: ultralytics, torch
python scripts/app_gradio.pyAccessible sur http://127.0.0.1:7861
python scripts/htr_pipeline_modular.py \
--img data-test/image.jpg \
--txt results/detection_lines/labels/image.txt \
--model qwen4b \
--out_txt output.txt \
--no_4bitpython scripts/sort_lines-topological.py \
--img data-test/image.jpg \
--txt results/detection_lines/labels/image.txt \
--out result_sorted.jpg \
--out_txt result_sorted.txtAjout d'un nouveau modèle HTR:
- Créer une classe dans
model_wrappers.pyhéritant deModelWrapper - Implémenter
transcribe(self, image: Image.Image) -> str - Ajouter dans
load_model()dehtr_pipeline_modular.py - Mettre à jour les choix dans
app_gradio.py
Script standalone pour utiliser des VLM via OpenRouter avec In-Context Learning.
pip install -r requirements_openrouter.txtscripts/
└── openrouter_transcribe.py
prompts/
├── system.txt
└── user.txt
Prompts modifiables dans prompts/:
system.txt- Instructions systèmeuser.txt- Prompt utilisateur
python scripts/openrouter_transcribe.py \
--img image.jpg \
--gt_dir exemples/GT \
--api_key sk-or-v1-xxxRequis:
--img- Image à transcrire--gt_dir- Dossier avec exemples (images + .txt associés)--api_key- Clé API OpenRouter (ou variableOPENROUTER_API_KEY)
Optionnels:
--prompts_dir- Dossier des prompts (défaut:prompts)--system_prompt- Fichier prompt système (défaut:system.txt)--user_prompt- Fichier prompt utilisateur (défaut:user.txt)--model- Modèle (défaut:google/gemini-3-flash-preview)--max_examples- Nombre d'exemples ICL (défaut: 3)--temperature- Température (défaut: 0.1)--output- Fichier de sortie
export OPENROUTER_API_KEY=sk-or-v1-xxx
python scripts/openrouter_transcribe.py \
--img page.jpg \
--gt_dir GT/ \
--prompts_dir prompts \
--model "google/gemini-3-flash-preview" \
--max_examples 5 \
--output result.txt
