Réalité Augmentée — TP — Marker Tracking (OpenCV)
Marker Tracking
Librairies requises:
pip install opencv-python
pip install numpy
Introduction
Le but de ce TP est de vous initier à plusieurs notions essentielles de vision par ordinateur, à travers un cas d’application concret : la détection et la localisation d’un marqueur plan dans un flux vidéo.
Vous travaillerez notamment sur :
- la détection de points caractéristiques (points d’intérêt, feature points),
- la description de ces points (descripteurs locaux),
- le matching (mise en correspondance) de points détectés dans deux images,
- le calcul d’une homographie (transformation projective),
- une augmentation du flux vidéo basée sur la localisation du marqueur.
À l’issue du TP, vous disposerez d’un programme qui, à partir :
- d’une image de référence (le marqueur),
- d’un flux vidéo (webcam ou fichier),
détecte automatiquement la présence du marqueur dans la scène et masque la zone du marqueur en la remplaçant par un polygone blanc (pour valider visuellement la détection).
Principe de l’application
L’idée générale du système est la suivante :
Charger l’image du marqueur (image de référence).
Ouvrir un flux vidéo (webcam ou fichier vidéo).
Détecter dans l’image du marqueur un ensemble de points d’intérêt (FP_M).
Calculer pour ces points un ensemble de descripteurs (FD_M).
Pour chaque frame I_t du flux vidéo :
- détecter un ensemble de points d’intérêt (FP_t),
- calculer des descripteurs (FD_t),
- effectuer le matching entre FD_M et FD_t pour obtenir des correspondances,
- filtrer ces correspondances pour ne conserver que des « bons matchs ».
Estimer la transformation géométrique reliant le plan du marqueur à la frame : une homographie H_{M->t} calculée de manière robuste avec RANSAC.
Utiliser H_{M->t} pour :
- projeter les 4 coins du marqueur dans l’image I_t,
- masquer la zone détectée en la remplissant en blanc.
Remarque importante : ce TP réalise une localisation par « redétection + matching » à chaque frame. Il ne s’agit pas d’un suivi temporel (type KLT/optical flow), mais d’une approche robuste et simple à mettre en œuvre.
Détection de points d’intérêt
L’objectif de la détection de points d’intérêt (ou plus généralement de « régions » d’intérêt) est de sélectionner automatiquement des éléments de l’image qui présentent des propriétés remarquables : coins, textures, zones contrastées, etc.
Un détecteur de features prend en entrée une image et renvoie un ensemble de coordonnées (pixels) correspondant aux points jugés « intéressants » par l’algorithme.
Important : un détecteur fournit des positions (et parfois une échelle/orientation) mais pas de signature descriptive associée.
Exemples de détecteurs : Harris, FAST, Shi-Tomasi, ORB, AKAZE, SIFT, etc.
Ressources (à lire après le TP) :
- https://fr.wikipedia.org/wiki/D%C3%A9tection_de_zones_d%27int%C3%A9r%C3%AAt
- https://en.wikipedia.org/wiki/Feature_detection_(computer_vision)
Description de points d’intérêt
Un descripteur de features vise à caractériser numériquement l’apparence locale autour d’un point d’intérêt.
Il prend en entrée :
- une image,
- une liste de points d’intérêt,
et renvoie un vecteur (ou une matrice) de descripteurs, un par point.
Ces descripteurs représentent une forme « d’empreinte digitale » locale permettant de comparer des points détectés dans des images différentes.
Propriétés souhaitables d’un descripteur :
- invariance (ou robustesse) aux rotations,
- invariance (ou robustesse) aux changements d’échelle,
- robustesse aux variations photométriques (éclairage),
- robustesse aux transformations géométriques modérées.
Exemples : ORB, AKAZE, BRISK, SIFT (détecteur+descripteur), etc.
Ressources (à lire après le TP) :
- https://fr.wikipedia.org/wiki/Extraction_de_caract%C3%A9ristique_en_vision_par_ordinateur
- https://en.wikipedia.org/wiki/Visual_descriptor
- https://en.wikipedia.org/wiki/Scale-invariant_feature_transform
Matching (mise en correspondance)
Le matching correspond à la question suivante :
Étant donné une feature dans l’image du marqueur, comment trouver la feature la plus similaire dans la frame vidéo courante ?
L’idée générale est :
- Définir une distance ou une similarité entre descripteurs.
- Pour chaque descripteur du marqueur, trouver le descripteur le plus proche dans la frame.
Mesures possibles : L1, L2, Hamming (descripteurs binaires), ratio test, etc.
Méthodes de matching :
- Brute force : compare tous les descripteurs 2 à 2 (simple, peut être coûteux).
- FLANN : approche par plus proches voisins approximatifs (plus rapide sur grands volumes).
Après le matching, il faut définir une règle de filtrage pour ne conserver que les correspondances pertinentes. Une approche classique (et celle utilisée dans la base de code fournie) consiste à utiliser un seuil basé sur la distance minimale observée :
threshold = alpha * minDist
où alpha est un coefficient (typiquement entre 3 et 20 selon la méthode et la qualité attendue).
Ressources (à lire après le TP) :
- https://docs.google.com/presentation/d/1_HFh3SdmdyZ_j-sFS4Tw17DmhKfjmYZqvSp7TmfdD_M/edit?slide=id.p#slide=id.p
- https://www.cs.toronto.edu/~urtasun/courses/CV/lecture04.pdf
Homographie et projection
Une fois des correspondances établies entre le marqueur (plan) et la frame (image), on souhaite estimer la transformation géométrique reliant ces deux ensembles de points.
Pour un objet plan, cette transformation est une homographie (matrice 3x3). Elle permet de modéliser la perspective et relie deux vues d’un même plan.
On cherche à estimer une matrice H à partir des bons matchs (après filtrage). L’estimation doit être robuste aux mauvais matchs : on utilise RANSAC.
Ressources (à lire après le TP) :
- https://en.wikipedia.org/wiki/Homography_(computer_vision)
- https://fr.wikipedia.org/wiki/Application_projective
Implémentation dans OpenCV
L’objectif du TP est d’implémenter les étapes précédentes dans OpenCV en partant d’un squelette de code.
Base de code fournie
Vous disposez des fichiers suivants :
main.pyfileciteturn1file0MyFeatureDetector.pyfileciteturn1file3MyDescriptorExtractor.pyfileciteturn1file1MyDescriptorMatcher.pyfileciteturn1file2
Ces fichiers contiennent des sections TODO qui guident votre implémentation.
Important : la base actuelle charge deux images fixes. Vous devez l’adapter pour gérer :
- une image de référence
marker.jpg, - un flux vidéo (webcam ou fichier).
Vous supprimerez la partie finale de génération d’une image transformée (warp) et la remplacerez par une augmentation (masquage du marqueur) basée sur la projection des coins.
Questions
Question 1 : Lecture et compréhension du code fourni
Lisez le code fourni et identifiez :
- où sont chargées les images,
- où sont instanciés le détecteur, l’extracteur et le matcher,
- où sont stockés les points détectés et les descripteurs,
- comment la liste des meilleurs matchs est construite,
- comment l’homographie est calculée.
Expliquez en quelques lignes le rôle de chaque fichier.
Question 2 : Créer un détecteur de features (ORB)
Dans MyFeatureDetector.py, complétez la fonction changeFeatureDetector pour créer un détecteur ORB.
Objectif : remplir l’attribut myFeatureDetector en appelant le constructeur OpenCV approprié (par exemple cv.ORB_create(...)).
Question 3 : Afficher les points détectés
Dans main.py, affichez les points d’intérêt détectés :
- sur l’image
marker.jpg, - sur une frame de la vidéo.
Indication : utilisez la méthode displayFeatures et les sections TODO déjà présentes dans le squelette.
À faire : ajoutez une capture d’écran montrant les résultats sur le marqueur et sur une frame.
Option : ajoutez des paramètres à cv.ORB_create(...) (nombre de points, seuil, etc.), puis commentez l’impact.
Question 4 : Instancier un extracteur de descripteurs (ORB)
Dans MyDescriptorExtractor.py, complétez changeDescriptorExtractor pour créer un extracteur ORB.
Question 5 : Calculer les descripteurs
Complétez computeDescriptors() dans MyDescriptorExtractor.py et complétez les appels correspondants dans main.py pour :
- calculer les descripteurs du marqueur,
- calculer les descripteurs d’une frame.
Vérifiez que les descripteurs sont bien calculés (dimensions cohérentes, non nuls).
Question 6 : Réaliser le matching
Dans MyDescriptorMatcher.py, complétez la méthode match pour ne conserver que les correspondances dont la distance est inférieure à un seuil :
threshold = alpha * minDist
Les matchs retenus doivent être stockés dans bestMatches.
Question 7 : Afficher le résultat du matching
Dans main.py, appelez drawMatchingResults() et affichez l’image résultante.
À faire : illustrez ce résultat par une capture d’écran dans votre compte rendu.
Question 8 : Comprendre et calculer l’homographie
À partir des meilleurs matchs, construisez deux listes de points 2D :
- points dans l’image du marqueur,
- points dans la frame vidéo.
Calculez ensuite l’homographie avec cv.findHomography(..., cv.RANSAC, epsilon).
Expliquez en quelques lignes ce que fait ce calcul et pourquoi RANSAC est nécessaire.
Question 9 : Augmentation — masquer le marqueur
Une fois l’homographie H estimée, projetez les 4 coins du marqueur dans la frame.
Étapes attendues :
- Définir les 4 coins du marqueur dans son repère image.
- Les projeter avec
cv.perspectiveTransform. - Dessiner le contour (recommandé pour le debug).
- Remplir le polygone projeté en blanc avec
cv.fillConvexPoly.
Condition : n’effectuez l’augmentation que si H est valide et si le nombre d’inliers est suffisant (seuil à définir et justifier).
À faire : fournissez une capture d’écran où le marqueur est effectivement masqué.
Question 10 : Tester sur d’autres séquences
Testez votre programme avec :
- une autre vidéo (ou une autre scène webcam),
- un autre marqueur (image de référence différente).
À faire : illustrez au moins un test supplémentaire et commentez la robustesse.
Question 11 : Changer de détecteurs/descripteurs (option)
Essayez une autre combinaison de détecteur/descripteur (par exemple AKAZE) et comparez :
- le nombre de points détectés,
- la stabilité du matching,
- le nombre d’inliers,
- la robustesse aux variations d’échelle/éclairage,
- le coût en temps de calcul.
À faire : illustrez et commentez.
Livrables
Vous devez rendre :
Le code complété.
Un court compte rendu (PDF ou Markdown) contenant :
- les captures demandées,
- vos choix de paramètres (alpha, seuil d’inliers, etc.),
- une analyse de robustesse (tests, cas d’échec).