Last Seen : j'ai appris à un drone de onze ans à retrouver une personne à partir d'une seule photo, et à demander avant de suivre qui que ce soit
Last Seen donne à un DJI Phantom 3 de 2015 une seule photo et une zone de recherche. OpenCV 5 trouve et compare chaque personne, Claude décide où regarder ensuite, et un humain répond à « Est-ce que c'est elle? » avant que le drone suive qui que ce soit. Piloté en direct dans un parc : trouvé dès le premier balayage à 0,85, suivi pendant 90 secondes, 49 épingles sur la carte.

Une seule photo et un vieux drone
Imaginez une coordonnatrice de recherche dans un parc à la brunante. Un homme atteint de démence a quitté sa résidence il y a une heure. Elle a une seule photo prise ce matin et un bénévole avec un vieux drone grand public. C'est un personnage composite; le travail, lui, est réel. L'appareil aussi : un DJI Phantom 3 Standard de 2015, sans détection d'obstacles et avec un lien vidéo en 720p, piloté par une application Kotlin sur le téléphone qui fait sortir la vidéo et entrer les commandes. La personne que le drone trouve dans la vidéo, c'est moi, avec mon consentement.
OpenCV voit, à chaque image
Trois boucles sont gardées séparées exprès. La première, c'est OpenCV 5 à chaque image. cv2.dnn, le nouveau moteur de graphes, exécute YOLO11n pour les personnes en environ 41 à 50 ms par image sur le processeur d'un portable. Chaque personne est ensuite comparée à la photo de deux façons : le réseau de réidentification de personnes du Model Zoo d'OpenCV et des histogrammes HSV des vêtements par bande du corps, fusionnés en un seul score. Un modèle de caméra transforme les pieds de chaque boîte en un point au sol, et c'est ce point qui arrive sur la carte de la coordonnatrice.


Claude décide où regarder, jamais qui est quelqu'un
La deuxième boucle, c'est Claude, toutes les quelques secondes. Il a six outils stricts : scan_here, fly_to, look_closer, ask_coordinator, follow_confirmed et end_mission. Il voit le tableau des candidats et les images recadrées et choisit la suite. Pendant qu'il réfléchit, l'environnement d'exécution garde l'appareil en vol stationnaire et en perception, et chaque décision est écrite dans trace.jsonl. La troisième boucle, c'est une personne, une seule fois. ask_coordinator affiche « Est-ce que c'est elle? » sur le téléphone de la coordonnatrice avec la photo à côté de ce que voit le drone. La page est une URL de fonction Lambda, et la réponse est une écriture conditionnelle DynamoDB, alors une deuxième réponse à la même question est refusée.

Trois missions dans un parc
Le 25 octobre 2026, j'ai piloté trois missions dans un parc public en jouant la personne disparue. La mission 1 utilisait une photo prise à hauteur des yeux. Vu des airs, je n'ai jamais dépassé 0,24, alors il a regardé de plus près deux fois, fouillé deux coins, n'a jamais rien demandé à personne, et je l'ai rappelé. C'est le bon comportement pour une correspondance faible, et c'est le cas difficile. La mission 2 utilisait une photo aérienne : il a regardé de plus près à 0,76, a demandé, a été confirmé, et m'a suivi pendant 90 secondes avec 49 épingles. Dans son propre résumé, l'agent a écrit que le verrouillage n'a tenu que 47 % du temps et qu'il m'a perdu sept fois. La mission 3 m'a trouvé dès le premier balayage à 0,85, a demandé, a été confirmée, et m'a suivi jusqu'à ce que la batterie atteigne son seuil de 18 % après 64 secondes; l'enveloppe a alors interrompu la mission et l'appareil s'est posé tout seul.


La vérification de la caméra elle-même
J'ai imprimé des marqueurs ArUco de 190 mm et je les ai vérifiés avec une règle. La calibration complète n'a pas été faite en vol, mais les marqueurs apparaissent dans la vidéo de bord, alors la vérification de la caméra a été faite après coup sur les images. solvePnP d'OpenCV, sur un seul marqueur, place la caméra à 5,9 m au-dessus alors que le baromètre indiquait 8,0 m. L'écart est stable, environ 2 m, ce qui pointe vers le modèle d'objectif de la fiche technique plutôt que vers du bruit, et le rapport le dit.

Une sécurité qu'une consigne ne peut pas promettre
follow_confirmed lève NotConfirmed pour toute personne que la coordonnatrice n'a pas confirmée. C'est du code, pas une consigne, et c'est testé. L'enveloppe (géorepérage, plafond, vitesse, seuil de batterie et arrêt si le lien devient périmé) est vérifiée à chaque cycle de contrôle dans pilot.py, et l'agent ne peut pas l'élargir. La coordonnatrice peut rappeler l'appareil à partir de la page, et l'interrupteur de mode du pilote a priorité sur tout : je le rebascule et les manettes sont à moi. La sécurité ne dépend jamais de l'aller-retour vers le nuage.

Ce qui n'est pas revendiqué
Chaque chiffre de ce billet vient de mes trois propres vols, avec moi comme seul sujet, alors rien n'est corrigé par quelqu'un d'autre; ce que le dépôt garantit, c'est que le texte concorde avec les fichiers de mission, parce qu'un script fait échouer la construction quand ils ne concordent pas. L'erreur des épingles par rapport au GPS du téléphone du sujet et la vérification de l'angle de la nacelle avec les marqueurs imprimés étaient prévues et n'ont pas été mesurées. L'identification repose sur les vêtements et la silhouette, pas sur le visage : une photo avec d'autres vêtements ne correspondra pas, deux personnes habillées pareil sont toutes deux soumises à la coordonnatrice, et une photo prise à hauteur des yeux ne correspond pas à la même personne vue d'en haut, ce qui est le prochain problème. Une personne a parfois été séparée en deux pistes, et l'agent l'a signalé au lieu de le cacher. Le décollage autonome a échoué à chaque tentative le 30 septembre et a fonctionné le 25 octobre. Il n'y a pas de détection d'obstacles : l'appareil est gardé au-dessus d'un terrain dégagé par le géorepérage et le plafond. Le Phantom est immatriculé auprès de Transports Canada et a été piloté avec un certificat de pilote de base, en visibilité directe, loin des passants.
Last Seen: an eleven-year-old drone finds a person from one photo with OpenCV 5, asks a human "Is this them?", and only then follows
Voir le projet