Reconnaissance de dossards par IA
Lors des éditions 2025 et 2026 de la Purple Rouen, une course organisée par les étudiants, les photographes de l’association Le Studio INSA ont capturé au total des milliers de clichés.
Le défi technique était le suivant : comment permettre à des centaines de coureurs de retrouver facilement leurs photos au milieu d’une galerie massive, sans avoir à imposer un tri manuel titanesque aux photographes ?
Pour résoudre ce problème, j’ai conçu un pipeline de traitement de bout en bout, combinant vision par ordinateur, ingénierie des données et développement front-end, afin d’indexer automatiquement chaque photo grâce au numéro de dossard des coureurs.
1. Détection des dossards
La première étape a consisté à isoler les dossards sur les photos. J’ai entraîné un modèle YOLO (You Only Look Once) pour détecter et recadrer (crop) spécifiquement les zones de l’image contenant un dossard.
path: /chemin/vers/dataset
train: images
val: images
nc: 1
names: ['Dossard']
from ultralytics import YOLO
# On charge le modèle de base
model = YOLO("yolov8n.pt")
results = model.train(
data="data.yaml",
epochs=50,
imgsz=640,
batch=8,
)

2. Extraction OCR spatial
Une fois ces petits extraits générés, j’ai utilisé l’API Google Cloud Vision pour l’extraction du texte (OCR). Cependant, une simple lecture textuelle était insuffisante. Sur un dossard de la Purple Rouen, on retrouve beaucoup de “bruit” visuel : la distance (“5km”), l’année (“Edition 2026”), ou encore les numéros de téléphone d’urgence.
Pour différencier le vrai numéro du coureur du reste du texte, j’ai mis en place une extraction spatiale. Au lieu de récupérer uniquement le texte, mon script Python enregistre dans un fichier JSON les coordonnées exactes (bounding boxes X et Y) et la hauteur en pixels de chaque mot détecté.
3. Filtrage géométrique
Une bonne pratique en data engineering est de découpler l’extraction de la transformation. En stockant les retours bruts de Google Vision dans un cache JSON local, j’ai pu développer et affiner ma logique de post-traitement sans jamais avoir à rappeler (et payer) l’API.
Pour trouver le bon numéro de dossard parmi tous les textes lus, j’ai implémenté un algorithme de post-traitement basé sur la géométrie pure, voici la logique appliquée :
- Isoler tous les “mots” composés strictement de 3 ou 4 chiffres.
- Éliminer les nombres écrits en trop petit (ce qui filtre instantanément les mentions comme “Edition 2026” ou les numéros de téléphone).
- Parmi les gros nombres restants, sélectionner celui dont la coordonnée Y est la plus haute sur l’image.
Ce pipeline géométrique s’est révélé extrêmement robuste, regroupant ensuite les numéros trouvés sur différents crops sous le nom de l’image originale dans un fichier JSON final, prêt à être consommé par le site web.
Conclusion
Ce projet a été une bonne opportunité de mettre en pratique des compétences transversales : de l’entraînement d’un modèle d’IA au script Python d’automatisation, jusqu’à l’intégration front-end optimisée pour l’expérience utilisateur.
L’outil final a permis aux participants de retrouver leurs souvenirs de la course en quelques secondes, valorisant par la même occasion le superbe travail des photographes de l’INSA.