Spaces:
Sleeping
Sleeping
File size: 4,061 Bytes
563a0f0 | 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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | """Génère les images PNG du corpus de référence (Sprint A5, M-14).
Idempotent : produit les mêmes octets à chaque exécution grâce à la
police par défaut Pillow (police bitmap interne, ne dépend pas du
système). Les fichiers sont écrits à côté de ce script.
Exécution :
python tests/fixtures/reference_corpus/_generate.py
Le workflow CI ``perf_regression.yml`` régénère les fichiers en début
de run pour s'assurer qu'ils sont à jour vis-à-vis du code de
génération.
"""
from __future__ import annotations
from pathlib import Path
# Chaque entrée = (id, ligne_1, ligne_2_optionnelle, ...).
# Les textes sont en français pour exercer Tesseract `fra`.
_DOCUMENTS: list[tuple[str, list[str]]] = [
(
"doc_01_imprime_moderne",
[
"Picarones est une plateforme de banc d'essai",
"pour des moteurs OCR sur documents",
"patrimoniaux. Cette image est synthetique.",
],
),
(
"doc_02_chiffres_dates",
[
"Charte du 14 mars 1789, signee par",
"le notaire Jean Dupont. Folio 23 verso.",
"Tarif: 5 livres 12 sols 6 deniers.",
],
),
(
"doc_03_noms_propres",
[
"Liste des temoins :",
"Marie Lefevre, Pierre Bernard,",
"Antoine Rousseau, Catherine Moreau.",
],
),
(
"doc_04_courte_phrase",
[
"L'ancien Regime se termine en 1789.",
],
),
(
"doc_05_paragraphe_long",
[
"Au commencement de l'an mille sept cent",
"quatre vingt neuf, le royaume de France",
"comptait environ vingt huit millions",
"d'habitants. Paris seule en hebergeait",
"six cent cinquante mille.",
],
),
]
def _render_one(out_dir: Path, doc_id: str, lines: list[str]) -> None:
"""Rend une image PNG + son fichier .gt.txt à côté.
Police : police bitmap interne de Pillow (``ImageFont.load_default``)
pour que l'image soit identique sur tous les systèmes (pas de
dépendance à des polices installées).
"""
from PIL import Image, ImageDraw, ImageFont
font = ImageFont.load_default()
# On rend large pour que Tesseract ait de quoi mâcher.
line_height = 30
margin = 20
width = 800
height = margin * 2 + line_height * len(lines)
img = Image.new("RGB", (width, height), color=(255, 255, 245))
draw = ImageDraw.Draw(img)
for i, line in enumerate(lines):
# Échelle x4 par redimensionnement : on rend petit puis on
# upscale pour obtenir un texte ~24 px de haut, lisible par
# Tesseract sans nécessiter une vraie police TrueType.
small = Image.new("RGB", (width // 4, line_height // 4 * len(lines)), color=(255, 255, 245))
small_draw = ImageDraw.Draw(small)
small_draw.text((5, 5 + i * line_height // 4), line, fill=(20, 20, 20), font=font)
# Composite en upscale dans le canvas final.
# (On garde la version brute pour rester déterministe.)
del small_draw, small
draw.text((margin, margin + i * line_height), line, fill=(20, 20, 20), font=font)
png_path = out_dir / f"{doc_id}.png"
img.save(png_path, format="PNG", optimize=True)
gt_path = out_dir / f"{doc_id}.gt.txt"
gt_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def generate(out_dir: Path | None = None) -> Path:
"""Régénère le corpus dans ``out_dir`` (défaut : à côté de ce script).
Retourne le chemin du dossier."""
if out_dir is None:
out_dir = Path(__file__).parent
out_dir = Path(out_dir)
out_dir.mkdir(parents=True, exist_ok=True)
for doc_id, lines in _DOCUMENTS:
_render_one(out_dir, doc_id, lines)
return out_dir
if __name__ == "__main__":
p = generate()
print(f"Corpus de référence (re)généré dans {p}")
print(f" {len(_DOCUMENTS)} documents, "
f"~{sum(len(lines) for _, lines in _DOCUMENTS)} lignes au total.")
|