<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Augmented Reality | Étienne Peillard</title><link>https://www.etiennepeillard.com/fr/tag/augmented-reality/</link><atom:link href="https://www.etiennepeillard.com/fr/tag/augmented-reality/index.xml" rel="self" type="application/rss+xml"/><description>Augmented Reality</description><generator>Wowchemy (https://wowchemy.com)</generator><lastBuildDate>Thu, 26 Feb 2026 00:00:00 +0000</lastBuildDate><image><url>https://www.etiennepeillard.com/media/sharing.png</url><title>Augmented Reality</title><link>https://www.etiennepeillard.com/fr/tag/augmented-reality/</link></image><item><title>TP — Réalité augmentée sur smartphone</title><link>https://www.etiennepeillard.com/fr/teaching/lab/ar-handheld/</link><pubDate>Thu, 26 Feb 2026 00:00:00 +0000</pubDate><guid>https://www.etiennepeillard.com/fr/teaching/lab/ar-handheld/</guid><description>&lt;h2 id="objectif">Objectif&lt;/h2>
&lt;p>Créer une application de réalité augmentée capable de :&lt;/p>
&lt;ol>
&lt;li>détecter une image utilisée comme marqueur,&lt;/li>
&lt;li>afficher un objet 3D attaché à ce marqueur,&lt;/li>
&lt;li>détecter un plan dans l&amp;rsquo;environnement,&lt;/li>
&lt;li>définir une zone de jeu,&lt;/li>
&lt;li>créer des interactions entre les marqueurs et la zone.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="partie-1--création-du-projet">Partie 1 — Création du projet&lt;/h2>
&lt;ol>
&lt;li>
&lt;p>Créer un projet Unity.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Basculer la plateforme vers &lt;strong>Android&lt;/strong> dans les &lt;em>Build Settings&lt;/em>.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;blockquote>
&lt;p>Pour avoir accès aux logs sur le téléphone, installer &lt;strong>Android Logcat&lt;/strong> depuis le Package Manager.&lt;/p>
&lt;/blockquote>
&lt;ol start="3">
&lt;li>
&lt;p>Installer &lt;strong>AR Foundation&lt;/strong>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Installer &lt;strong>ARCore XR Plugin&lt;/strong> (Android) ou &lt;strong>ARKit XR Plugin&lt;/strong> (iOS).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Ouvrir &lt;strong>Project Settings → XR Plug-in Management&lt;/strong> et activer :&lt;/p>
&lt;ul>
&lt;li>&lt;strong>ARCore&lt;/strong> dans l’onglet Android&lt;/li>
&lt;li>&lt;strong>ARKit&lt;/strong> dans l’onglet iOS (si nécessaire)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Dans &lt;strong>Project Settings → Player → Android&lt;/strong> :&lt;/p>
&lt;ul>
&lt;li>définir &lt;strong>Minimum API Level : Android 10 / API 29&lt;/strong>.&lt;/li>
&lt;li>Dans &lt;strong>Graphics APIs&lt;/strong>, désactiver &lt;strong>Vulkan&lt;/strong> et conserver &lt;strong>OpenGLES3&lt;/strong> uniquement.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Ajouter dans la scène :&lt;/p>
&lt;ul>
&lt;li>&lt;strong>AR Session&lt;/strong>&lt;/li>
&lt;li>&lt;strong>XR Origin&lt;/strong> (avec &lt;strong>AR Camera&lt;/strong>)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Configuration du rendu mobile&lt;/p>
&lt;ul>
&lt;li>Dans le projet, ouvrir : &lt;code>Assets/Settings/Mobile_Renderer&lt;/code>&lt;/li>
&lt;li>Dans l’inspecteur : &lt;strong>Add Renderer Feature → AR Background Renderer Feature&lt;/strong>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>Vérifier que l&amp;rsquo;application se lance sur le téléphone et que le flux caméra est visible.&lt;/p>
&lt;p>Lors du premier lancement sur le téléphone, &lt;strong>autoriser l&amp;rsquo;accès à la caméra&lt;/strong> lorsque le système le demande.&lt;/p>
&lt;hr>
&lt;h2 id="partie-2--détection-dimage">Partie 2 — Détection d&amp;rsquo;image&lt;/h2>
&lt;ol>
&lt;li>Créer un nouvel asset &lt;strong>Reference Image Library&lt;/strong>.&lt;/li>
&lt;li>Ajouter une image marqueur.&lt;/li>
&lt;li>Ajouter un composant &lt;strong>ARTrackedImageManager&lt;/strong> au XR Origin.&lt;/li>
&lt;li>Associer la bibliothèque d&amp;rsquo;images.&lt;/li>
&lt;li>Créer un prefab d&amp;rsquo;objet 3D à afficher sur le marqueur.&lt;/li>
&lt;li>Associer ce prefab au &lt;strong>ARTrackedImageManager&lt;/strong>.&lt;/li>
&lt;/ol>
&lt;blockquote>
&lt;p>Vous pouvez utiliser les marqueurs prévus pour ce TP. L&amp;rsquo;asset &lt;strong>ImageLibrary&lt;/strong> est disponible &lt;a href="./Image%20Library%20small/ImageLibrary_small.unitypackage">ici&lt;/a> et les marqueurs sont &lt;a href="./Image%20Library%20small/markers_sheet.png">ici&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h2 id="partie-3--détection-de-plans-sélection-dun-plan--zone-de-jeu">Partie 3 — Détection de plans (sélection d’un plan + zone de jeu)&lt;/h2>
&lt;h3 id="objectif-1">Objectif&lt;/h3>
&lt;ul>
&lt;li>détecter des plans horizontaux/verticaux via AR Foundation,&lt;/li>
&lt;li>permettre à l’utilisateur de &lt;strong>taper&lt;/strong> sur un plan détecté,&lt;/li>
&lt;li>placer une &lt;strong>zone de jeu&lt;/strong> (GameBoard) sur ce plan.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="31-ajouter-les-composants-ar-nécessaires">3.1 Ajouter les composants AR nécessaires&lt;/h3>
&lt;p>Sur l’objet &lt;strong>XR Origin&lt;/strong> :&lt;/p>
&lt;p>&lt;strong>ARPlaneManager&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Sert à détecter et maintenir les plans.&lt;/li>
&lt;li>Associer un &lt;strong>Plane Prefab&lt;/strong> pour visualiser les plans.&lt;/li>
&lt;/ul>
&lt;h4 id="créer-un-plane-prefab-simple">Créer un Plane Prefab simple&lt;/h4>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>Create → Empty GameObject&lt;/strong>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Nommer l’objet : &lt;code>ARPlanePrefab&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Ajouter les composants :&lt;/p>
&lt;ul>
&lt;li>&lt;strong>AR Plane&lt;/strong>&lt;/li>
&lt;li>&lt;strong>AR Plane Mesh Visualizer&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Mesh Renderer&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Mesh Filter&lt;/strong>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Créer un matériau simple (ex : &lt;strong>Unlit / Color&lt;/strong> transparent).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Assigner ce matériau au &lt;strong>Mesh Renderer&lt;/strong>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Glisser l’objet dans le dossier &lt;em>Project&lt;/em> pour créer un prefab.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Assigner ce prefab dans &lt;strong>ARPlaneManager → Plane Prefab&lt;/strong>.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>ARRaycastManager&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Sert à projeter un rayon depuis l’écran pour détecter les plans.&lt;/li>
&lt;/ul>
&lt;p>Réglage conseillé :&lt;/p>
&lt;ul>
&lt;li>Detection Mode → &lt;strong>Horizontal&lt;/strong>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="32-créer-un-prefab-de-zone-de-jeu-gameboard">3.2 Créer un prefab de zone de jeu (GameBoard)&lt;/h3>
&lt;p>Créer un prefab simple :&lt;/p>
&lt;ul>
&lt;li>un &lt;strong>Quad&lt;/strong> posé à plat&lt;/li>
&lt;li>un matériau semi‑transparent&lt;/li>
&lt;li>une échelle ~ &lt;strong>0.5 m&lt;/strong>&lt;/li>
&lt;li>optionnel : &lt;strong>BoxCollider&lt;/strong>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="33-implémenter-le-tap-to-place-new-input-system">3.3 Implémenter le tap-to-place (New Input System)&lt;/h3>
&lt;p>Dans ce TP, on utilise le &lt;strong>New Input System&lt;/strong> (Unity Input System Package) pour récupérer les taps.&lt;/p>
&lt;h4 id="prérequis">Prérequis&lt;/h4>
&lt;ol>
&lt;li>Ouvrir &lt;strong>Project Settings → Player&lt;/strong>&lt;/li>
&lt;li>Mettre &lt;strong>Active Input Handling → Input System Package (New)&lt;/strong>&lt;/li>
&lt;/ol>
&lt;h4 id="principe">Principe&lt;/h4>
&lt;p>Créer un script &lt;code>BoardPlacement.cs&lt;/code>. Le script doit :&lt;/p>
&lt;ol>
&lt;li>activer &lt;strong>EnhancedTouch&lt;/strong> (au démarrage)&lt;/li>
&lt;li>récupérer le premier touch actif&lt;/li>
&lt;li>filtrer sur la phase &lt;strong>Began&lt;/strong>&lt;/li>
&lt;li>lancer un &lt;strong>ARRaycast&lt;/strong> vers les plans (&lt;code>PlaneWithinPolygon&lt;/code>)&lt;/li>
&lt;li>créer ou déplacer le &lt;code>GameBoard&lt;/code> à la pose du hit&lt;/li>
&lt;/ol>
&lt;p>Fonctions / API utiles :&lt;/p>
&lt;ul>
&lt;li>&lt;code>EnhancedTouchSupport.Enable()&lt;/code> / &lt;code>Disable()&lt;/code>&lt;/li>
&lt;li>&lt;code>Touch.activeTouches&lt;/code>&lt;/li>
&lt;li>&lt;code>touch.phase&lt;/code> (New Input System)&lt;/li>
&lt;li>&lt;code>touch.screenPosition&lt;/code>&lt;/li>
&lt;li>&lt;code>ARRaycastManager.Raycast(...)&lt;/code>&lt;/li>
&lt;li>&lt;code>TrackableType.PlaneWithinPolygon&lt;/code>&lt;/li>
&lt;li>&lt;code>Pose&lt;/code>&lt;/li>
&lt;li>&lt;code>Instantiate(...)&lt;/code>&lt;/li>
&lt;li>&lt;code>transform.SetPositionAndRotation(...)&lt;/code>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="checkpoint">Checkpoint&lt;/h3>
&lt;p>Vous devez pouvoir :&lt;/p>
&lt;ul>
&lt;li>voir les plans détectés&lt;/li>
&lt;li>toucher un plan&lt;/li>
&lt;li>placer la zone de jeu&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="partie-4--interactions">Partie 4 — Interactions&lt;/h2>
&lt;h3 id="41-interaction-basique">4.1 Interaction basique&lt;/h3>
&lt;p>Implémenter une interaction entre :&lt;/p>
&lt;ul>
&lt;li>les marqueurs détectés&lt;/li>
&lt;li>la zone de jeu&lt;/li>
&lt;/ul>
&lt;p>Exemples possibles :&lt;/p>
&lt;ul>
&lt;li>un objet apparaît lorsque le marqueur entre dans la zone&lt;/li>
&lt;li>le marqueur déplace un objet dans la zone&lt;/li>
&lt;li>l’orientation du marqueur modifie un paramètre&lt;/li>
&lt;/ul>
&lt;p>Cette partie est volontairement libre.&lt;/p>
&lt;hr>
&lt;h3 id="42-ressources-pour-aller-plus-loin">4.2 Ressources pour aller plus loin&lt;/h3>
&lt;p>Le package &lt;strong>AR Foundation&lt;/strong> fournit plusieurs fonctionnalités utiles pour enrichir votre projet.&lt;/p>
&lt;p>&lt;strong>Suivi des images&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;code>ARTrackedImageManager&lt;/code>&lt;/li>
&lt;li>événements : &lt;code>trackedImagesChanged&lt;/code>&lt;/li>
&lt;li>accès à la position d’un marqueur&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Détection de plans&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;code>ARPlaneManager&lt;/code>&lt;/li>
&lt;li>accès aux plans détectés&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Raycast AR&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;code>ARRaycastManager.Raycast()&lt;/code>&lt;/li>
&lt;li>permet d’interagir avec l’environnement réel&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Ancres AR&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;code>ARAnchorManager&lt;/code>&lt;/li>
&lt;li>permet de fixer durablement un objet dans l’espace&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Estimation de la lumière&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;code>ARCameraManager&lt;/code>&lt;/li>
&lt;li>permet d’adapter la lumière des objets virtuels à la scène réelle&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Tracking du visage / du corps&lt;/strong> (selon appareils)&lt;/p>
&lt;ul>
&lt;li>Face Tracking&lt;/li>
&lt;li>Body Tracking&lt;/li>
&lt;/ul>
&lt;p>Documentation officielle :&lt;/p>
&lt;p>&lt;a href="https://docs.unity3d.com/Packages/com.unity.xr.arfoundation" target="_blank" rel="noopener">https://docs.unity3d.com/Packages/com.unity.xr.arfoundation&lt;/a>&lt;/p>
&lt;hr>
&lt;h2 id="partie-5--scénarisation">Partie 5 — Scénarisation&lt;/h2>
&lt;p>Vous avez maintenant tous les éléments techniques pour créer une expérience AR complète.&lt;/p>
&lt;p>Inventez une petite application ou un mini‑jeu utilisant :&lt;/p>
&lt;ul>
&lt;li>un marqueur ou plusieurs marqueurs&lt;/li>
&lt;li>une zone&lt;/li>
&lt;li>au moins une interaction.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="extensions-possibles">Extensions possibles&lt;/h2>
&lt;ul>
&lt;li>plusieurs marqueurs&lt;/li>
&lt;li>interactions entre marqueurs&lt;/li>
&lt;li>effets visuels&lt;/li>
&lt;li>interface utilisateur AR&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="livrables">Livrables&lt;/h2>
&lt;ol>
&lt;li>
&lt;p>Compte rendu (PDF) avec :&lt;/p>
&lt;ul>
&lt;li>description de l’application&lt;/li>
&lt;li>captures d’écran&lt;/li>
&lt;li>explications techniques&lt;/li>
&lt;li>lien Git vers le projet Unity&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="barème">Barème&lt;/h2>
&lt;ul>
&lt;li>Mise en place du projet — &lt;strong>2 pts&lt;/strong>&lt;/li>
&lt;li>Image tracking — &lt;strong>2 pts&lt;/strong>&lt;/li>
&lt;li>Détection de plan et placement — &lt;strong>4 pts&lt;/strong>&lt;/li>
&lt;li>Interactions — &lt;strong>4 pts&lt;/strong>&lt;/li>
&lt;li>Scénarisation — &lt;strong>5 pts&lt;/strong>&lt;/li>
&lt;li>Qualité technique — &lt;strong>2 pts&lt;/strong>&lt;/li>
&lt;li>Rendu — &lt;strong>1 pt&lt;/strong>&lt;/li>
&lt;/ul></description></item><item><title>TP — Réalité augmentée projective</title><link>https://www.etiennepeillard.com/fr/teaching/lab/projective-ar/</link><pubDate>Thu, 19 Feb 2026 00:00:00 +0000</pubDate><guid>https://www.etiennepeillard.com/fr/teaching/lab/projective-ar/</guid><description>&lt;h2 id="réalité-augmentée-projective">Réalité Augmentée Projective&lt;/h2>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="alt text" srcset="
/fr/teaching/lab/projective-ar/image_hua7e3aa278d0be464fd894aab44259ad1_320305_0eeaf679062a2a085457c0452d37f088.webp 400w,
/fr/teaching/lab/projective-ar/image_hua7e3aa278d0be464fd894aab44259ad1_320305_5ca371ff073ff534a10f2a375116c17d.webp 760w,
/fr/teaching/lab/projective-ar/image_hua7e3aa278d0be464fd894aab44259ad1_320305_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://www.etiennepeillard.com/fr/teaching/lab/projective-ar/image_hua7e3aa278d0be464fd894aab44259ad1_320305_0eeaf679062a2a085457c0452d37f088.webp"
width="760"
height="328"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>&lt;strong>▶ &lt;a href="code.zip">Code de base&lt;/a>&lt;/strong>&lt;/p>
&lt;h3 id="objectifs">Objectifs&lt;/h3>
&lt;p>Ce tutoriel introduit les fondements de la &lt;strong>réalité augmentée projective (AR)&lt;/strong>, depuis la détection d’événements par caméra jusqu’à l’augmentation spatiale via un projecteur.&lt;/p>
&lt;p>L’application de référence est un &lt;strong>jeu de morpion (tic-tac-toe)&lt;/strong>, 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).&lt;/p>
&lt;p>Vous apprendrez à :&lt;/p>
&lt;ul>
&lt;li>Calibrer la caméra, le projecteur et la surface physique&lt;/li>
&lt;li>Calculer les matrices de transformation (homographies) entre espaces&lt;/li>
&lt;li>Détecter des modifications sur la surface&lt;/li>
&lt;li>Projeter des augmentations cohérentes en temps réel&lt;/li>
&lt;/ul>
&lt;h3 id="vue-densemble-du-système">Vue d’ensemble du système&lt;/h3>
&lt;p>Nous travaillons dans trois espaces distincts :&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Espace image caméra&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Espace image projecteur&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Espace plateau physique&lt;/strong>&lt;/li>
&lt;/ol>
&lt;p>Ces espaces ne sont pas alignés. Une calibration est nécessaire pour calculer les transformations entre eux.&lt;/p>
&lt;p>L’objectif principal est :&lt;/p>
&lt;ul>
&lt;li>Convertir un coup détecté (espace caméra) en coordonnées du plateau&lt;/li>
&lt;li>Convertir une coordonnée du plateau en coordonnées projecteur&lt;/li>
&lt;/ul>
&lt;h3 id="installation">Installation&lt;/h3>
&lt;p>Assurez-vous que Python et &lt;code>pip&lt;/code> sont installés.&lt;/p>
&lt;blockquote>
&lt;p>Le TP a été testé avec Python 3.12 et 3.13. D’autres versions peuvent fonctionner, mais des ajustements pourraient être nécessaires.&lt;/p>
&lt;/blockquote>
&lt;p>Installez les dépendances requises :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install &lt;span class="nv">numpy&lt;/span>&lt;span class="o">==&lt;/span>1.26.4
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install opencv-python&lt;span class="o">==&lt;/span>4.10.0.84
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">pip install opencv-contrib-python&lt;span class="o">==&lt;/span>4.6.0.66
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;strong>OpenCV&lt;/strong> : bibliothèque de vision par ordinateur&lt;/li>
&lt;li>&lt;strong>Aruco&lt;/strong> : module de génération et détection de marqueurs (inclus dans opencv-contrib)&lt;/li>
&lt;/ul>
&lt;p>Documentation : &lt;a href="https://docs.opencv.org/4.x/index.html" target="_blank" rel="noopener">https://docs.opencv.org/4.x/index.html&lt;/a>&lt;/p>
&lt;h3 id="génération-des-marqueurs">Génération des marqueurs&lt;/h3>
&lt;p>Exécutez :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">python generateMarkers.py
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Si l’installation est correcte, quatre marqueurs définissant la zone de jeu seront générés.&lt;/p>
&lt;p>Imprimez-les et placez-les sur le plateau.&lt;/p>
&lt;h3 id="conventions-de-coordonnées">Conventions de coordonnées&lt;/h3>
&lt;h4 id="représentation-matricielle-images">Représentation matricielle (images)&lt;/h4>
&lt;p>Les images sont des matrices NumPy en &lt;strong>ordre ligne-major&lt;/strong> :&lt;/p>
&lt;ul>
&lt;li>Premier indice → ligne (vertical, vers le bas)&lt;/li>
&lt;li>Second indice → colonne (horizontal, vers la droite)&lt;/li>
&lt;li>(0,0) correspond au coin supérieur gauche&lt;/li>
&lt;/ul>
&lt;h4 id="représentation-des-points">Représentation des points&lt;/h4>
&lt;p>Les points suivent la convention image :&lt;/p>
&lt;ul>
&lt;li>Origine : coin supérieur gauche&lt;/li>
&lt;li>X → droite&lt;/li>
&lt;li>Y → bas&lt;/li>
&lt;/ul>
&lt;p>Système de coordonnées :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">(0,0) - X →
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Y
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Soyez extrêmement attentif lors du passage entre indexation matricielle et coordonnées géométriques.&lt;/p>
&lt;h2 id="structure-du-code">Structure du code&lt;/h2>
&lt;p>Quatre composants principaux :&lt;/p>
&lt;ul>
&lt;li>&lt;code>Camera&lt;/code>&lt;/li>
&lt;li>&lt;code>Projector&lt;/code>&lt;/li>
&lt;li>&lt;code>CoreAR&lt;/code>&lt;/li>
&lt;li>&lt;code>TicTacToe&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Toutes les parties manquantes sont indiquées par :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">### TODO&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="1-initialisation">1️⃣ Initialisation&lt;/h2>
&lt;h3 id="camera">Camera&lt;/h3>
&lt;ul>
&lt;li>Recherche automatiquement une caméra disponible&lt;/li>
&lt;li>Exposition configurable&lt;/li>
&lt;li>Doit être libérée via :&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">camera&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">release&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Complétez toutes les sections &lt;code>TODO&lt;/code>.&lt;/p>
&lt;h3 id="projector">Projector&lt;/h3>
&lt;p>Constructeur : aucune modification requise.&lt;/p>
&lt;p>Implémentez :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">drawBlack&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Comprenez le fonctionnement du dessin dans l’espace projecteur.&lt;/p>
&lt;h3 id="corear">CoreAR&lt;/h3>
&lt;p>Le constructeur stocke uniquement les références.&lt;/p>
&lt;p>Aucune modification requise.&lt;/p>
&lt;h2 id="2-calibration">2️⃣ Calibration&lt;/h2>
&lt;h3 id="calibration-caméra">Calibration caméra&lt;/h3>
&lt;p>Objectif :&lt;/p>
&lt;ul>
&lt;li>Détecter les quatre marqueurs ArUco&lt;/li>
&lt;li>Associer les coins détectés aux coordonnées du plateau&lt;/li>
&lt;li>Calculer l’homographie entre plateau et caméra&lt;/li>
&lt;/ul>
&lt;p>Complétez toutes les sections &lt;code>TODO&lt;/code> dans :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">calibrateCamera&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="calibration-projecteur">Calibration projecteur&lt;/h3>
&lt;p>Principe :&lt;/p>
&lt;ol>
&lt;li>Projeter des marqueurs à des positions projecteur connues&lt;/li>
&lt;li>Les détecter avec la caméra&lt;/li>
&lt;li>Convertir les détections caméra en coordonnées plateau&lt;/li>
&lt;li>Calculer l’homographie projecteur → plateau&lt;/li>
&lt;/ol>
&lt;p>Complétez :&lt;/p>
&lt;ul>
&lt;li>&lt;code>drawMarkers()&lt;/code> dans Projector&lt;/li>
&lt;li>&lt;code>calibrateProjector()&lt;/code> dans CoreAR&lt;/li>
&lt;/ul>
&lt;h2 id="3-dessin-dans-lespace-projecteur">3️⃣ Dessin dans l’espace projecteur&lt;/h2>
&lt;p>Implémentez :&lt;/p>
&lt;ul>
&lt;li>&lt;code>draw()&lt;/code>&lt;/li>
&lt;li>&lt;code>checkCalibration()&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Cela permet :&lt;/p>
&lt;ul>
&lt;li>D’afficher le plateau de jeu&lt;/li>
&lt;li>De valider visuellement la calibration&lt;/li>
&lt;/ul>
&lt;p>Testez l’ensemble de la chaîne de calibration.&lt;/p>
&lt;h2 id="4-logique-du-jeu">4️⃣ Logique du jeu&lt;/h2>
&lt;p>La classe &lt;code>ticTacToe&lt;/code> est déjà implémentée.&lt;/p>
&lt;p>Vous devez maintenant vous concentrer sur la détection des coups.&lt;/p>
&lt;h2 id="5-détection-des-coups">5️⃣ Détection des coups&lt;/h2>
&lt;p>Stratégie :&lt;/p>
&lt;ol>
&lt;li>Capturer une image de référence&lt;/li>
&lt;li>Comparer l’image courante à la référence&lt;/li>
&lt;li>Calculer l’image différence&lt;/li>
&lt;li>Appliquer un seuillage&lt;/li>
&lt;li>Appliquer une ouverture morphologique&lt;/li>
&lt;li>Extraire la position du blob&lt;/li>
&lt;li>Valider la stabilité temporelle&lt;/li>
&lt;li>Mettre à jour l’image de référence&lt;/li>
&lt;/ol>
&lt;p>Complétez toutes les sections &lt;code>TODO&lt;/code> dans :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">findMove&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Les lignes intermédiaires &lt;code>imshow()&lt;/code> peuvent être décommentées pour le débogage.&lt;/p>
&lt;h2 id="pipeline-de-traitement-dimage">Pipeline de traitement d’image&lt;/h2>
&lt;ul>
&lt;li>Soustraction d’images&lt;/li>
&lt;li>Seuillage&lt;/li>
&lt;li>Ouverture morphologique&lt;/li>
&lt;li>Extraction de contours&lt;/li>
&lt;/ul>
&lt;p>Cela permet d’isoler les nouveaux coups placés sur le plateau.&lt;/p>
&lt;h2 id="améliorations--réglages">Améliorations &amp;amp; Réglages&lt;/h2>
&lt;p>Vous pouvez ajuster :&lt;/p>
&lt;ul>
&lt;li>L’exposition de la caméra&lt;/li>
&lt;li>La luminosité du projecteur&lt;/li>
&lt;li>La valeur de seuil&lt;/li>
&lt;/ul>
&lt;p>Un réglage fin influence fortement la robustesse de la détection.&lt;/p>
&lt;h2 id="ce-que-vous-avez-construit">Ce que vous avez construit&lt;/h2>
&lt;p>À la fin de ce tutoriel, vous avez implémenté :&lt;/p>
&lt;ul>
&lt;li>Une calibration caméra-projecteur&lt;/li>
&lt;li>Une estimation d’homographies multi-espaces&lt;/li>
&lt;li>Une augmentation de surface en temps réel&lt;/li>
&lt;li>Une détection d’événements basique&lt;/li>
&lt;/ul>
&lt;p>Cette architecture peut être réutilisée pour :&lt;/p>
&lt;ul>
&lt;li>Jeux de plateau augmentés&lt;/li>
&lt;li>Surfaces interactives&lt;/li>
&lt;li>Dispositifs expérimentaux&lt;/li>
&lt;li>Visualisation scientifique&lt;/li>
&lt;/ul>
&lt;h2 id="livrables">Livrables&lt;/h2>
&lt;ul>
&lt;li>Code complété (tous les TODO remplis)&lt;/li>
&lt;li>Calibration fonctionnelle&lt;/li>
&lt;li>Morpion augmenté entièrement opérationnel&lt;/li>
&lt;/ul>
&lt;p>Optionnel :&lt;/p>
&lt;ul>
&lt;li>Améliorations de détection&lt;/li>
&lt;li>Améliorations graphiques&lt;/li>
&lt;li>Fonctionnalités de jeu supplémentaires&lt;/li>
&lt;/ul>
&lt;h2 id="clarifications-suite-aux-questions-étudiantes">Clarifications (Suite aux questions étudiantes)&lt;/h2>
&lt;h3 id="installation-opencv-avec-conda">Installation OpenCV avec Conda&lt;/h3>
&lt;p>Si &lt;code>pip&lt;/code> n’est pas disponible, utilisez :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">conda install -c conda-forge opencv
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Dans la plupart des cas, &lt;strong>Aruco&lt;/strong> est installé automatiquement.&lt;/p>
&lt;p>Sinon :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">conda install -c conda-forge aruco
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Si ArUco est toujours absent, installez &lt;code>pip&lt;/code> et utilisez &lt;code>opencv-contrib-python&lt;/code>.&lt;/p>
&lt;h3 id="matrice-de-projection-caméra--projecteur-r2p">Matrice de projection Caméra → Projecteur (R2P)&lt;/h3>
&lt;p>La matrice de projection du plateau réel vers l’espace projecteur (&lt;strong>R2P&lt;/strong>) :&lt;/p>
&lt;ul>
&lt;li>Est calculée dans &lt;code>CoreAR&lt;/code>&lt;/li>
&lt;li>Est assignée dans &lt;code>main.py&lt;/code> via :&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">proj&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">R2P&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">core&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">R2P&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Il n’y a pas de mécanisme d’encapsulation ici. L’attribut est ajouté dynamiquement à l’instance &lt;code>Projector&lt;/code>.&lt;/p>
&lt;p>Dans la classe &lt;code>Projector&lt;/code>, utilisez simplement :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">R2P&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Cela fonctionne car &lt;code>draw()&lt;/code> est appelé uniquement après la définition de l’attribut.&lt;/p>
&lt;h3 id="fonctions-de-calibration-et-matrices-de-transformation">Fonctions de calibration et matrices de transformation&lt;/h3>
&lt;h4 id="calibratecamera">&lt;code>calibrateCamera()&lt;/code>&lt;/h4>
&lt;ul>
&lt;li>Détecte les &lt;strong>marqueurs ArUco physiques&lt;/strong> placés sur le plateau&lt;/li>
&lt;li>⚠ Ne placez pas les marqueurs sur un fond noir&lt;/li>
&lt;li>Calcule la matrice :&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">R2C (Réel → Caméra)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="calibrateprojector">&lt;code>calibrateProjector()&lt;/code>&lt;/h4>
&lt;ol>
&lt;li>
&lt;p>Le projecteur affiche des marqueurs virtuels&lt;/p>
&lt;/li>
&lt;li>
&lt;p>La caméra détecte ces marqueurs projetés&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Une correspondance est effectuée entre :&lt;/p>
&lt;ul>
&lt;li>Positions projetées connues&lt;/li>
&lt;li>Positions détectées en espace caméra&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Une transformation Caméra → Projecteur est calculée&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>On en déduit :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">R2P (Réel → Projecteur)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Chaîne complète :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">Réel → Caméra → Projecteur
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Finalement :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">R2P = (C2P) ∘ (R2C)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Fin du tutoriel.&lt;/strong>&lt;/p></description></item><item><title>TP — Suivi de marqueurs avec OpenCV</title><link>https://www.etiennepeillard.com/fr/teaching/lab/tp-tracking/</link><pubDate>Thu, 12 Feb 2026 00:00:00 +0000</pubDate><guid>https://www.etiennepeillard.com/fr/teaching/lab/tp-tracking/</guid><description>&lt;h1 id="marker-tracking">Marker Tracking&lt;/h1>
&lt;p>&lt;strong>▶ &lt;a href="base-code.zip">Code de base&lt;/a>&lt;/strong>&lt;/p>
&lt;p>&lt;strong>Librairies requises&lt;/strong>:&lt;/p>
&lt;p>&lt;code>pip install opencv-python&lt;/code>&lt;/p>
&lt;p>&lt;code>pip install numpy&lt;/code>&lt;/p>
&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>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.&lt;/p>
&lt;p>Vous travaillerez notamment sur :&lt;/p>
&lt;ul>
&lt;li>la détection de points caractéristiques (points d’intérêt, feature points),&lt;/li>
&lt;li>la description de ces points (descripteurs locaux),&lt;/li>
&lt;li>le matching (mise en correspondance) de points détectés dans deux images,&lt;/li>
&lt;li>le calcul d’une homographie (transformation projective),&lt;/li>
&lt;li>une augmentation du flux vidéo basée sur la localisation du marqueur.&lt;/li>
&lt;/ul>
&lt;p>À l’issue du TP, vous disposerez d’un programme qui, à partir :&lt;/p>
&lt;ul>
&lt;li>d’une image de référence (le marqueur),&lt;/li>
&lt;li>d’un flux vidéo (webcam ou fichier),&lt;/li>
&lt;/ul>
&lt;p>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).&lt;/p>
&lt;hr>
&lt;h2 id="principe-de-lapplication">Principe de l’application&lt;/h2>
&lt;p>L’idée générale du système est la suivante :&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Charger l’image du marqueur (image de référence).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Ouvrir un flux vidéo (webcam ou fichier vidéo).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Détecter dans l’image du marqueur un ensemble de points d’intérêt (FP_M).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Calculer pour ces points un ensemble de descripteurs (FD_M).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Pour chaque frame I_t du flux vidéo :&lt;/p>
&lt;ul>
&lt;li>détecter un ensemble de points d’intérêt (FP_t),&lt;/li>
&lt;li>calculer des descripteurs (FD_t),&lt;/li>
&lt;li>effectuer le matching entre FD_M et FD_t pour obtenir des correspondances,&lt;/li>
&lt;li>filtrer ces correspondances pour ne conserver que des « bons matchs ».&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Estimer la transformation géométrique reliant le plan du marqueur à la frame : une homographie H_{M-&amp;gt;t} calculée de manière robuste avec RANSAC.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Utiliser H_{M-&amp;gt;t} pour :&lt;/p>
&lt;ul>
&lt;li>projeter les 4 coins du marqueur dans l’image I_t,&lt;/li>
&lt;li>masquer la zone détectée en la remplissant en blanc.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;p>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.&lt;/p>
&lt;hr>
&lt;h2 id="détection-de-points-dintérêt">Détection de points d’intérêt&lt;/h2>
&lt;p>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.&lt;/p>
&lt;p>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.&lt;/p>
&lt;p>Important : un détecteur fournit des positions (et parfois une échelle/orientation) mais pas de signature descriptive associée.&lt;/p>
&lt;p>Exemples de détecteurs : Harris, FAST, Shi-Tomasi, ORB, AKAZE, SIFT, etc.&lt;/p>
&lt;p>Ressources (à lire après le TP) :&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://fr.wikipedia.org/wiki/D%C3%A9tection_de_zones_d%27int%C3%A9r%C3%AAt" target="_blank" rel="noopener">https://fr.wikipedia.org/wiki/D%C3%A9tection_de_zones_d%27int%C3%A9r%C3%AAt&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://en.wikipedia.org/wiki/Feature_detection_%28computer_vision%29" target="_blank" rel="noopener">https://en.wikipedia.org/wiki/Feature_detection_(computer_vision)&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="description-de-points-dintérêt">Description de points d’intérêt&lt;/h2>
&lt;p>Un descripteur de features vise à caractériser numériquement l’apparence locale autour d’un point d’intérêt.&lt;/p>
&lt;p>Il prend en entrée :&lt;/p>
&lt;ul>
&lt;li>une image,&lt;/li>
&lt;li>une liste de points d’intérêt,&lt;/li>
&lt;/ul>
&lt;p>et renvoie un vecteur (ou une matrice) de descripteurs, un par point.&lt;/p>
&lt;p>Ces descripteurs représentent une forme « d’empreinte digitale » locale permettant de comparer des points détectés dans des images différentes.&lt;/p>
&lt;p>Propriétés souhaitables d’un descripteur :&lt;/p>
&lt;ul>
&lt;li>invariance (ou robustesse) aux rotations,&lt;/li>
&lt;li>invariance (ou robustesse) aux changements d’échelle,&lt;/li>
&lt;li>robustesse aux variations photométriques (éclairage),&lt;/li>
&lt;li>robustesse aux transformations géométriques modérées.&lt;/li>
&lt;/ul>
&lt;p>Exemples : ORB, AKAZE, BRISK, SIFT (détecteur+descripteur), etc.&lt;/p>
&lt;p>Ressources (à lire après le TP) :&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://fr.wikipedia.org/wiki/Extraction_de_caract%C3%A9ristique_en_vision_par_ordinateur" target="_blank" rel="noopener">https://fr.wikipedia.org/wiki/Extraction_de_caract%C3%A9ristique_en_vision_par_ordinateur&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://en.wikipedia.org/wiki/Visual_descriptor" target="_blank" rel="noopener">https://en.wikipedia.org/wiki/Visual_descriptor&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://en.wikipedia.org/wiki/Scale-invariant_feature_transform" target="_blank" rel="noopener">https://en.wikipedia.org/wiki/Scale-invariant_feature_transform&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="matching-mise-en-correspondance">Matching (mise en correspondance)&lt;/h2>
&lt;p>Le matching correspond à la question suivante :&lt;/p>
&lt;blockquote>
&lt;p>Étant donné une feature dans l’image du marqueur, comment trouver la feature la plus similaire dans la frame vidéo courante ?&lt;/p>
&lt;/blockquote>
&lt;p>L’idée générale est :&lt;/p>
&lt;ol>
&lt;li>Définir une distance ou une similarité entre descripteurs.&lt;/li>
&lt;li>Pour chaque descripteur du marqueur, trouver le descripteur le plus proche dans la frame.&lt;/li>
&lt;/ol>
&lt;p>Mesures possibles : L1, L2, Hamming (descripteurs binaires), ratio test, etc.&lt;/p>
&lt;p>Méthodes de matching :&lt;/p>
&lt;ul>
&lt;li>Brute force : compare tous les descripteurs 2 à 2 (simple, peut être coûteux).&lt;/li>
&lt;li>FLANN : approche par plus proches voisins approximatifs (plus rapide sur grands volumes).&lt;/li>
&lt;/ul>
&lt;p>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 :&lt;/p>
&lt;p>threshold = alpha * minDist&lt;/p>
&lt;p>où alpha est un coefficient (typiquement entre 3 et 20 selon la méthode et la qualité attendue).&lt;/p>
&lt;p>Ressources (à lire après le TP) :&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://docs.google.com/presentation/d/1_HFh3SdmdyZ_j-sFS4Tw17DmhKfjmYZqvSp7TmfdD_M/edit?slide=id.p#slide=id.p" target="_blank" rel="noopener">https://docs.google.com/presentation/d/1_HFh3SdmdyZ_j-sFS4Tw17DmhKfjmYZqvSp7TmfdD_M/edit?slide=id.p#slide=id.p&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.cs.toronto.edu/~urtasun/courses/CV/lecture04.pdf" target="_blank" rel="noopener">https://www.cs.toronto.edu/~urtasun/courses/CV/lecture04.pdf&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="homographie-et-projection">Homographie et projection&lt;/h2>
&lt;p>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.&lt;/p>
&lt;p>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.&lt;/p>
&lt;p>On cherche à estimer une matrice H à partir des bons matchs (après filtrage). L’estimation doit être robuste aux mauvais matchs : on utilise RANSAC.&lt;/p>
&lt;p>Ressources (à lire après le TP) :&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://en.wikipedia.org/wiki/Homography_%28computer_vision%29" target="_blank" rel="noopener">https://en.wikipedia.org/wiki/Homography_(computer_vision)&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://fr.wikipedia.org/wiki/Application_projective" target="_blank" rel="noopener">https://fr.wikipedia.org/wiki/Application_projective&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h1 id="implémentation-dans-opencv">Implémentation dans OpenCV&lt;/h1>
&lt;p>L’objectif du TP est d’implémenter les étapes précédentes dans OpenCV en partant d’un squelette de code.&lt;/p>
&lt;h2 id="base-de-code-fournie">Base de code fournie&lt;/h2>
&lt;p>Vous disposez des fichiers suivants :&lt;/p>
&lt;ul>
&lt;li>&lt;code>main.py&lt;/code> fileciteturn1file0&lt;/li>
&lt;li>&lt;code>MyFeatureDetector.py&lt;/code> fileciteturn1file3&lt;/li>
&lt;li>&lt;code>MyDescriptorExtractor.py&lt;/code> fileciteturn1file1&lt;/li>
&lt;li>&lt;code>MyDescriptorMatcher.py&lt;/code> fileciteturn1file2&lt;/li>
&lt;/ul>
&lt;p>Ces fichiers contiennent des sections TODO qui guident votre implémentation.&lt;/p>
&lt;p>Important : la base actuelle charge deux images fixes. Vous devez l’adapter pour gérer :&lt;/p>
&lt;ul>
&lt;li>une image de référence &lt;code>marker.jpg&lt;/code>,&lt;/li>
&lt;li>un flux vidéo (webcam ou fichier).&lt;/li>
&lt;/ul>
&lt;p>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.&lt;/p>
&lt;hr>
&lt;h2 id="questions">Questions&lt;/h2>
&lt;h3 id="question-1--lecture-et-compréhension-du-code-fourni">Question 1 : Lecture et compréhension du code fourni&lt;/h3>
&lt;p>Lisez le code fourni et identifiez :&lt;/p>
&lt;ul>
&lt;li>où sont chargées les images,&lt;/li>
&lt;li>où sont instanciés le détecteur, l’extracteur et le matcher,&lt;/li>
&lt;li>où sont stockés les points détectés et les descripteurs,&lt;/li>
&lt;li>comment la liste des meilleurs matchs est construite,&lt;/li>
&lt;li>comment l’homographie est calculée.&lt;/li>
&lt;/ul>
&lt;p>Expliquez en quelques lignes le rôle de chaque fichier.&lt;/p>
&lt;hr>
&lt;h3 id="question-2--créer-un-détecteur-de-features-orb">Question 2 : Créer un détecteur de features (ORB)&lt;/h3>
&lt;p>Dans &lt;code>MyFeatureDetector.py&lt;/code>, complétez la fonction &lt;code>changeFeatureDetector&lt;/code> pour créer un détecteur ORB.&lt;/p>
&lt;p>Objectif : remplir l’attribut &lt;code>myFeatureDetector&lt;/code> en appelant le constructeur OpenCV approprié (par exemple &lt;code>cv.ORB_create(...)&lt;/code>).&lt;/p>
&lt;hr>
&lt;h3 id="question-3--afficher-les-points-détectés">Question 3 : Afficher les points détectés&lt;/h3>
&lt;p>Dans &lt;code>main.py&lt;/code>, affichez les points d’intérêt détectés :&lt;/p>
&lt;ul>
&lt;li>sur l’image &lt;code>marker.jpg&lt;/code>,&lt;/li>
&lt;li>sur une frame de la vidéo.&lt;/li>
&lt;/ul>
&lt;p>Indication : utilisez la méthode &lt;code>displayFeatures&lt;/code> et les sections TODO déjà présentes dans le squelette.&lt;/p>
&lt;p>À faire : ajoutez une capture d’écran montrant les résultats sur le marqueur et sur une frame.&lt;/p>
&lt;p>Option : ajoutez des paramètres à &lt;code>cv.ORB_create(...)&lt;/code> (nombre de points, seuil, etc.), puis commentez l’impact.&lt;/p>
&lt;hr>
&lt;h3 id="question-4--instancier-un-extracteur-de-descripteurs-orb">Question 4 : Instancier un extracteur de descripteurs (ORB)&lt;/h3>
&lt;p>Dans &lt;code>MyDescriptorExtractor.py&lt;/code>, complétez &lt;code>changeDescriptorExtractor&lt;/code> pour créer un extracteur ORB.&lt;/p>
&lt;hr>
&lt;h3 id="question-5--calculer-les-descripteurs">Question 5 : Calculer les descripteurs&lt;/h3>
&lt;p>Complétez &lt;code>computeDescriptors()&lt;/code> dans &lt;code>MyDescriptorExtractor.py&lt;/code> et complétez les appels correspondants dans &lt;code>main.py&lt;/code> pour :&lt;/p>
&lt;ul>
&lt;li>calculer les descripteurs du marqueur,&lt;/li>
&lt;li>calculer les descripteurs d’une frame.&lt;/li>
&lt;/ul>
&lt;p>Vérifiez que les descripteurs sont bien calculés (dimensions cohérentes, non nuls).&lt;/p>
&lt;hr>
&lt;h3 id="question-6--réaliser-le-matching">Question 6 : Réaliser le matching&lt;/h3>
&lt;p>Dans &lt;code>MyDescriptorMatcher.py&lt;/code>, complétez la méthode &lt;code>match&lt;/code> pour ne conserver que les correspondances dont la distance est inférieure à un seuil :&lt;/p>
&lt;p>threshold = alpha * minDist&lt;/p>
&lt;p>Les matchs retenus doivent être stockés dans &lt;code>bestMatches&lt;/code>.&lt;/p>
&lt;hr>
&lt;h3 id="question-7--afficher-le-résultat-du-matching">Question 7 : Afficher le résultat du matching&lt;/h3>
&lt;p>Dans &lt;code>main.py&lt;/code>, appelez &lt;code>drawMatchingResults()&lt;/code> et affichez l’image résultante.&lt;/p>
&lt;p>À faire : illustrez ce résultat par une capture d’écran dans votre compte rendu.&lt;/p>
&lt;hr>
&lt;h3 id="question-8--comprendre-et-calculer-lhomographie">Question 8 : Comprendre et calculer l’homographie&lt;/h3>
&lt;p>À partir des meilleurs matchs, construisez deux listes de points 2D :&lt;/p>
&lt;ul>
&lt;li>points dans l’image du marqueur,&lt;/li>
&lt;li>points dans la frame vidéo.&lt;/li>
&lt;/ul>
&lt;p>Calculez ensuite l’homographie avec &lt;code>cv.findHomography(..., cv.RANSAC, epsilon)&lt;/code>.&lt;/p>
&lt;p>Expliquez en quelques lignes ce que fait ce calcul et pourquoi RANSAC est nécessaire.&lt;/p>
&lt;hr>
&lt;h3 id="question-9--augmentation--masquer-le-marqueur">Question 9 : Augmentation — masquer le marqueur&lt;/h3>
&lt;p>Une fois l’homographie H estimée, projetez les 4 coins du marqueur dans la frame.&lt;/p>
&lt;p>Étapes attendues :&lt;/p>
&lt;ol>
&lt;li>Définir les 4 coins du marqueur dans son repère image.&lt;/li>
&lt;li>Les projeter avec &lt;code>cv.perspectiveTransform&lt;/code>.&lt;/li>
&lt;li>Dessiner le contour (recommandé pour le debug).&lt;/li>
&lt;li>Remplir le polygone projeté en blanc avec &lt;code>cv.fillConvexPoly&lt;/code>.&lt;/li>
&lt;/ol>
&lt;p>Condition : n’effectuez l’augmentation que si H est valide et si le nombre d’inliers est suffisant (seuil à définir et justifier).&lt;/p>
&lt;p>À faire : fournissez une capture d’écran où le marqueur est effectivement masqué.&lt;/p>
&lt;hr>
&lt;h3 id="question-10--tester-sur-dautres-séquences">Question 10 : Tester sur d’autres séquences&lt;/h3>
&lt;p>Testez votre programme avec :&lt;/p>
&lt;ul>
&lt;li>une autre vidéo (ou une autre scène webcam),&lt;/li>
&lt;li>un autre marqueur (image de référence différente).&lt;/li>
&lt;/ul>
&lt;p>À faire : illustrez au moins un test supplémentaire et commentez la robustesse.&lt;/p>
&lt;hr>
&lt;h3 id="question-11--changer-de-détecteursdescripteurs-option">Question 11 : Changer de détecteurs/descripteurs (option)&lt;/h3>
&lt;p>Essayez une autre combinaison de détecteur/descripteur (par exemple AKAZE) et comparez :&lt;/p>
&lt;ul>
&lt;li>le nombre de points détectés,&lt;/li>
&lt;li>la stabilité du matching,&lt;/li>
&lt;li>le nombre d’inliers,&lt;/li>
&lt;li>la robustesse aux variations d’échelle/éclairage,&lt;/li>
&lt;li>le coût en temps de calcul.&lt;/li>
&lt;/ul>
&lt;p>À faire : illustrez et commentez.&lt;/p>
&lt;hr>
&lt;h1 id="livrables">Livrables&lt;/h1>
&lt;p>Vous devez rendre :&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Le code complété.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Un court compte rendu (PDF ou Markdown) contenant :&lt;/p>
&lt;ul>
&lt;li>les captures demandées,&lt;/li>
&lt;li>vos choix de paramètres (alpha, seuil d’inliers, etc.),&lt;/li>
&lt;li>une analyse de robustesse (tests, cas d’échec).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol></description></item></channel></rss>