Réalité Augmentée Projective — Tutoriel

Tutoriel pratique sur la réalité augmentée projective utilisant la calibration caméra-projecteur et OpenCV.

Réalité Augmentée Projective

alt text

Code de base

Objectifs

Ce tutoriel introduit les fondements de la réalité augmentée projective (AR), depuis la détection d’événements par caméra jusqu’à l’augmentation spatiale via un projecteur.

L’application de référence est un jeu de morpion (tic-tac-toe), mais l’architecture peut être réutilisée pour tout scénario d’augmentation de surface (ex. jeux de plateau augmentés, visualisation scientifique, dispositifs expérimentaux).

Vous apprendrez à :

  • Calibrer la caméra, le projecteur et la surface physique
  • Calculer les matrices de transformation (homographies) entre espaces
  • Détecter des modifications sur la surface
  • Projeter des augmentations cohérentes en temps réel

Vue d’ensemble du système

Nous travaillons dans trois espaces distincts :

  1. Espace image caméra
  2. Espace image projecteur
  3. Espace plateau physique

Ces espaces ne sont pas alignés. Une calibration est nécessaire pour calculer les transformations entre eux.

L’objectif principal est :

  • Convertir un coup détecté (espace caméra) en coordonnées du plateau
  • Convertir une coordonnée du plateau en coordonnées projecteur

Installation

Assurez-vous que Python et pip sont installés.

Le TP a été testé avec Python 3.12 et 3.13. D’autres versions peuvent fonctionner, mais des ajustements pourraient être nécessaires.

Installez les dépendances requises :

pip install numpy==1.26.4
pip install opencv-python==4.10.0.84
pip install opencv-contrib-python==4.6.0.66
  • OpenCV : bibliothèque de vision par ordinateur
  • Aruco : module de génération et détection de marqueurs (inclus dans opencv-contrib)

Documentation : https://docs.opencv.org/4.x/index.html

Génération des marqueurs

Exécutez :

python generateMarkers.py

Si l’installation est correcte, quatre marqueurs définissant la zone de jeu seront générés.

Imprimez-les et placez-les sur le plateau.

Conventions de coordonnées

Représentation matricielle (images)

Les images sont des matrices NumPy en ordre ligne-major :

  • Premier indice → ligne (vertical, vers le bas)
  • Second indice → colonne (horizontal, vers la droite)
  • (0,0) correspond au coin supérieur gauche

Représentation des points

Les points suivent la convention image :

  • Origine : coin supérieur gauche
  • X → droite
  • Y → bas

Système de coordonnées :

(0,0) - X →
   |
   |
   Y

Soyez extrêmement attentif lors du passage entre indexation matricielle et coordonnées géométriques.

Structure du code

Quatre composants principaux :

  • Camera
  • Projector
  • CoreAR
  • TicTacToe

Toutes les parties manquantes sont indiquées par :

### TODO

1️⃣ Initialisation

Camera

  • Recherche automatiquement une caméra disponible
  • Exposition configurable
  • Doit être libérée via :
camera.release()

Complétez toutes les sections TODO.

Projector

Constructeur : aucune modification requise.

Implémentez :

drawBlack()

Comprenez le fonctionnement du dessin dans l’espace projecteur.

CoreAR

Le constructeur stocke uniquement les références.

Aucune modification requise.

2️⃣ Calibration

Calibration caméra

Objectif :

  • Détecter les quatre marqueurs ArUco
  • Associer les coins détectés aux coordonnées du plateau
  • Calculer l’homographie entre plateau et caméra

Complétez toutes les sections TODO dans :

calibrateCamera()

Calibration projecteur

Principe :

  1. Projeter des marqueurs à des positions projecteur connues
  2. Les détecter avec la caméra
  3. Convertir les détections caméra en coordonnées plateau
  4. Calculer l’homographie projecteur → plateau

Complétez :

  • drawMarkers() dans Projector
  • calibrateProjector() dans CoreAR

3️⃣ Dessin dans l’espace projecteur

Implémentez :

  • draw()
  • checkCalibration()

Cela permet :

  • D’afficher le plateau de jeu
  • De valider visuellement la calibration

Testez l’ensemble de la chaîne de calibration.

4️⃣ Logique du jeu

La classe ticTacToe est déjà implémentée.

Vous devez maintenant vous concentrer sur la détection des coups.

5️⃣ Détection des coups

Stratégie :

  1. Capturer une image de référence
  2. Comparer l’image courante à la référence
  3. Calculer l’image différence
  4. Appliquer un seuillage
  5. Appliquer une ouverture morphologique
  6. Extraire la position du blob
  7. Valider la stabilité temporelle
  8. Mettre à jour l’image de référence

Complétez toutes les sections TODO dans :

findMove()

Les lignes intermédiaires imshow() peuvent être décommentées pour le débogage.

Pipeline de traitement d’image

  • Soustraction d’images
  • Seuillage
  • Ouverture morphologique
  • Extraction de contours

Cela permet d’isoler les nouveaux coups placés sur le plateau.

Améliorations & Réglages

Vous pouvez ajuster :

  • L’exposition de la caméra
  • La luminosité du projecteur
  • La valeur de seuil

Un réglage fin influence fortement la robustesse de la détection.

Ce que vous avez construit

À la fin de ce tutoriel, vous avez implémenté :

  • Une calibration caméra-projecteur
  • Une estimation d’homographies multi-espaces
  • Une augmentation de surface en temps réel
  • Une détection d’événements basique

Cette architecture peut être réutilisée pour :

  • Jeux de plateau augmentés
  • Surfaces interactives
  • Dispositifs expérimentaux
  • Visualisation scientifique

Livrables

  • Code complété (tous les TODO remplis)
  • Calibration fonctionnelle
  • Morpion augmenté entièrement opérationnel

Optionnel :

  • Améliorations de détection
  • Améliorations graphiques
  • Fonctionnalités de jeu supplémentaires

Clarifications (Suite aux questions étudiantes)

Installation OpenCV avec Conda

Si pip n’est pas disponible, utilisez :

conda install -c conda-forge opencv

Dans la plupart des cas, Aruco est installé automatiquement.

Sinon :

conda install -c conda-forge aruco

Si ArUco est toujours absent, installez pip et utilisez opencv-contrib-python.

Matrice de projection Caméra → Projecteur (R2P)

La matrice de projection du plateau réel vers l’espace projecteur (R2P) :

  • Est calculée dans CoreAR
  • Est assignée dans main.py via :
proj.R2P = core.R2P

Il n’y a pas de mécanisme d’encapsulation ici. L’attribut est ajouté dynamiquement à l’instance Projector.

Dans la classe Projector, utilisez simplement :

self.R2P

Cela fonctionne car draw() est appelé uniquement après la définition de l’attribut.

Fonctions de calibration et matrices de transformation

calibrateCamera()

  • Détecte les marqueurs ArUco physiques placés sur le plateau
  • ⚠ Ne placez pas les marqueurs sur un fond noir
  • Calcule la matrice :
R2C  (Réel → Caméra)

calibrateProjector()

  1. Le projecteur affiche des marqueurs virtuels

  2. La caméra détecte ces marqueurs projetés

  3. Une correspondance est effectuée entre :

    • Positions projetées connues
    • Positions détectées en espace caméra
  4. Une transformation Caméra → Projecteur est calculée

On en déduit :

R2P  (Réel → Projecteur)

Chaîne complète :

Réel → Caméra → Projecteur

Finalement :

R2P = (C2P) ∘ (R2C)

Fin du tutoriel.