Dans ce tutoriel, vous apprendrez à détecter et classifier des objets en utilisant le module ESP32-CAM et YOLO, un système d’apprentissage profond pour la détection d’objets.
Je vous guiderai pour construire un projet où l’ESP32-CAM capture des images, fonctionne comme un serveur web, et envoie les images à un ordinateur pour analyse. L’ordinateur utilisera YOLO pour détecter et classifier les objets. Vous apprendrez à assembler le matériel, configurer la caméra, et servir des images JPEG via HTTP.
À la fin, vous disposerez d’une interface web fonctionnelle pour visualiser les instantanés capturés par votre ESP32-CAM ainsi qu’un système de détection d’objets pour 80 types différents d’objets.
Pièces requises
Vous trouverez ci-dessous les composants nécessaires pour réaliser le projet. Au lieu du programmateur FTDI, vous pouvez aussi utiliser un shield de programmation pour l’ESP32-CAM, mais je recommande le premier.

ESP32-CAM

Adaptateur FTDI USB-TTL

Câble USB de données

Arduino IDE
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Architecture du système
Le système que nous allons construire est composé de deux éléments principaux : 1) un module ESP32-CAM qui capture des images et fonctionne comme un serveur web envoyant les images via WiFi. 2) un PC où le YOLO système de détection d’objets est exécuté. Il analyse les images et annote les objets détectés. Le schéma ci-dessous donne un aperçu de l’architecture du système :

L’image suivante montre un exemple de détection du système. Sur mon bureau encombré, YOLO a pu détecter une tasse avec 88 % de confiance, une paire de ciseaux avec 68 %, et un ordinateur portable avec 59 %. Vous pouvez voir les boîtes englobantes autour des objets avec leurs noms et le niveau de confiance affichés en haut à gauche :

Dans les sections suivantes, vous apprendrez à programmer le serveur web sur l’ESP32-CAM et à configurer le système de détection YOLO sur un PC.
La carte de développement ESP32-CAM
La carte de développement ESP32-CAM est un module compact qui combine une puce ESP32-S, une caméra, un flash intégré, et un slot pour carte microSD. La carte intègre le Wi-Fi et le Bluetooth et supporte une caméra OV2640 ou OV7670 avec une résolution allant jusqu’à 2 mégapixels.

Dans ce tutoriel, nous ferons référence à la carte originale AI-Thinker model de l’ESP32-CAM, mais il existe de nombreux clones avec exactement les mêmes spécifications. Ils se programment et s’utilisent de la même manière, y compris celui que nous avons listé dans les pièces requises.
Connexion du programmateur FTDI
Vous pouvez programmer l’ESP32-CAM via un Programming Shield ou via un FTDI Programmer. Ce dernier est plus facile à utiliser et plus flexible. Il convertit les signaux USB en signaux série et permet de programmer des microcontrôleurs comme Arduino et ESP32 via l’interface UART. L’image suivante montre comment connecter le programmateur FTDI au module ESP32-CAM.

Les connexions sont simples. Commencez par relier le GND du programmateur au GND du module ESP32-CAM (fil bleu). Puis faites de même avec l’alimentation 5V (fil rouge). Notez que certains programmateurs FTDI ont des cavaliers ou interrupteurs pour passer de 3,3V à 5V. Faites attention à cela et utilisez 5V si possible.
Ensuite, connectez la broche U0T (U0TXD) de l’ESP32-CAM à la broche RXD du programmateur (fil jaune). De même, U0R se connecte à TXD (fil vert). La communication série est ainsi établie.
Pour passer l’ESP32-CAM en mode programmation, la broche IO0 doit être reliée à la masse (GND). Mais pour exécuter le programme, la broche IO0 doit rester déconnectée. J’ai donc ajouté un interrupteur entre IO0 et GND (fil violet) qui me permet de basculer entre mode programmation et mode exécution. La photo ci-dessous montre mon câblage de l’ESP32-CAM avec l’interrupteur et le programmateur FTDI :

Installation du Core ESP32
Si c’est votre premier projet avec une carte de la série ESP32, vous devez d’abord installer le core de la carte. Si les cartes ESP32 sont déjà installées dans votre Arduino IDE, vous pouvez passer cette section.
Commencez par ouvrir la boîte de dialogue Préférences en sélectionnant « Preferences… » dans le menu « File ». Cela ouvrira la boîte de dialogue des préférences ci-dessous.
Sous l’onglet Settings, vous trouverez un champ de saisie en bas de la boîte de dialogue intitulé «Additional boards manager URLs» :

Dans ce champ, copiez l’URL suivante : « https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json«
Cela permettra à l’Arduino IDE de savoir où trouver les bibliothèques du core ESP32. Ensuite, nous allons installer ces bibliothèques via le Boards Manager.
Ouvrez le Boards Manager via « Tools -> Boards -> Board Manager ». Le gestionnaire de cartes apparaîtra dans la barre latérale gauche. Tapez « ESP32 » dans le champ de recherche en haut et vous verrez deux types de cartes ESP32 : « Arduino ESP32 Boards » et « esp32 by Espressif ». Nous voulons les bibliothèques esp32 par Espressif. Cliquez sur le bouton INSTALL et attendez la fin du téléchargement et de l’installation.

Sélection de la carte ESP32-CAM
Cliquez sur le menu déroulant puis sur « Select other board and port… »:

Cela ouvrira une boîte de dialogue où vous tapez « ESP32-CAM » dans la barre de recherche. Vous verrez la carte « AI Thinker ESP32-CAM » sous Boards. Cliquez dessus, sélectionnez le port COM pour l’activer, puis cliquez sur OK :

Si vous ne pouvez pas sélectionner de PORT malgré que l’ESP32-CAM soit branché via le programmateur FTDI, alors le pilote CP210X est manquant. Rendez-vous sur SILICON LABS Software Download set téléchargez le pilote CP210x adapté à votre système d’exploitation, par exemple pour Windows « CP210x VCP Windows » :

Cela téléchargera un fichier ZIP. Décompressez-le et lancez l’installateur. Après cela, votre ESP32-CAM devrait apparaître comme connecté à un port USB. Si vous avez encore des problèmes, vous devrez peut-être aussi installer un FTDI Driver.
Installation de la bibliothèque ESP32-CAM
Pour notre serveur web, nous allons utiliser la esp32cam library. Rendez-vous sur le github repo, cliquez sur le bouton vert CODE puis sur « Download ZIP » pour télécharger la bibliothèque :

Puis cliquez sur « Sketch->Include Library->Add .Zip Library » :

et sélectionnez le chemin vers le fichier ZIP que vous venez de télécharger pour installer la bibliothèque. Dans la section suivante, nous écrirons et expliquerons le code pour faire tourner un serveur web sur l’ESP32-CAM.
Code pour le serveur web ESP32-CAM
Le code suivant configure un module ESP32-CAM pour envoyer des images via un réseau Wi-Fi. Il capture des images et les sert en fichiers JPEG aux clients qui en font la demande. Le serveur fonctionne sur le port 80, le port HTTP par défaut.
#include "WebServer.h"
#include "WiFi.h"
#include "esp32cam.h"
const char* WIFI_SSID = "SSID";
const char* WIFI_PASS = "PASSWORD";
const char* URL = "/cam.jpg";
static auto RES = esp32cam::Resolution::find(800, 600);
WebServer server(80);
void serveJpg() {
auto frame = esp32cam::capture();
if (frame == nullptr) {
Serial.println("CAPTURE FAILED!");
server.send(503, "", "");
return;
}
Serial.printf("CAPTURE OK %dx%d %db\n",
frame->getWidth(), frame->getHeight(),
static_cast<int>(frame->size()));
server.setContentLength(frame->size());
server.send(200, "image/jpeg");
WiFiClient client = server.client();
frame->writeTo(client);
}
void handleJpg() {
if (!esp32cam::Camera.changeResolution(RES)) {
Serial.println("CAN'T SET RESOLUTION!");
}
serveJpg();
}
void initCamera() {
{
using namespace esp32cam;
Config cfg;
cfg.setPins(pins::AiThinker);
cfg.setResolution(RES);
cfg.setBufferCount(2);
cfg.setJpeg(80);
bool ok = Camera.begin(cfg);
Serial.println(ok ? "CAMERA OK" : "CAMERA FAIL");
}
}
void initWifi() {
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED)
;
Serial.printf("http://%s%s\n",
WiFi.localIP().toString().c_str(), URL);
}
void initServer() {
server.on(URL, handleJpg);
server.begin();
}
void setup() {
Serial.begin(115200);
initWifi();
initCamera();
initServer();
}
void loop() {
server.handleClient();
}
Décomposons le code en ses composants pour comprendre son fonctionnement.
Bibliothèques et constantes
Au début du code, nous incluons les bibliothèques nécessaires pour le serveur web, la fonctionnalité Wi-Fi et le contrôle de la caméra.
#include "WebServer.h" #include "WiFi.h" #include "esp32cam.h"
Nous définissons aussi des constantes pour les identifiants Wi-Fi et l’URL d’accès à l’image de la caméra.
const char* WIFI_SSID = "SSID"; const char* WIFI_PASS = "PASSWORD"; const char* URL = "/cam.jpg";
Évidemment, vous devrez remplacer ces identifiants par le SSID et le mot de passe de votre réseau Wi-Fi.
Résolution de la caméra
Nous définissons la résolution souhaitée pour la caméra. Ici, nous choisissons une résolution de 800×600 pixels.
static auto RES = esp32cam::Resolution::find(800, 600);
Initialisation du serveur web
Ensuite, nous créons une instance du serveur web qui écoute sur le port 80.
WebServer server(80);
Fonction de service JPEG
La fonction serveJpg() capture une image de la caméra et l’envoie au client sous forme de fichier JPEG. Si la capture échoue, elle renvoie une réponse « 503 Service Unavailable ».
void serveJpg() {
auto frame = esp32cam::capture();
if (frame == nullptr) {
Serial.println("CAPTURE FAILED!");
server.send(503, "", "");
return;
}
Serial.printf("CAPTURE OK %dx%d %db\n",
frame->getWidth(), frame->getHeight(),
static_cast<int>(frame->size()));
server.setContentLength(frame->size());
server.send(200, "image/jpeg");
WiFiClient client = server.client();
frame->writeTo(client);
}
Ici, nous tentons d’abord de capturer une image. Si cela réussit, nous enregistrons les dimensions et la taille de l’image, définissons la longueur du contenu, et renvoyons l’image au client.
Fonction de gestion JPEG
La fonction handleJpg() change la résolution de la caméra et appelle serveJpg() pour servir l’image.
void handleJpg() {
if (!esp32cam::Camera.changeResolution(RES)) {
Serial.println("CAN'T SET RESOLUTION!");
}
serveJpg();
}
Cette fonction garantit que la caméra est réglée à la résolution désirée avant de servir l’image.
Initialisation de la caméra
La fonction initCamera() configure les paramètres de la caméra, y compris les broches, la résolution, le nombre de buffers et la qualité JPEG.
void initCamera() {
{
using namespace esp32cam;
Config cfg;
cfg.setPins(pins::AiThinker);
cfg.setResolution(RES);
cfg.setBufferCount(2);
cfg.setJpeg(80);
bool ok = Camera.begin(cfg);
Serial.println(ok ? "CAMERA OK" : "CAMERA FAIL");
}
}
Nous créons un objet de configuration, définissons les paramètres nécessaires, et initialisons la caméra. Un message est affiché sur le moniteur série indiquant si l’initialisation a réussi.
Initialisation du Wi-Fi
La fonction initWifi() connecte l’ESP32 au réseau Wi-Fi spécifié.
void initWifi() {
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED)
;
Serial.printf("http://%s%s\n",
WiFi.localIP().toString().c_str(), URL);
}
Nous désactivons la connexion Wi-Fi persistante, réglons le mode en station, et tentons de nous connecter au réseau. Une fois connecté, nous affichons l’URL pour accéder à l’image de la caméra.
Initialisation du serveur
La fonction initServer() configure le serveur pour gérer les requêtes d’images de la caméra.
void initServer() {
server.on(URL, handleJpg);
server.begin();
}
Nous définissons l’URL d’accès et l’associons à la fonction handleJpg(), puis démarrons le serveur.
Fonction setup
La fonction setup() initialise la communication série, le Wi-Fi, la caméra et le serveur.
void setup() {
Serial.begin(115200);
initWifi();
initCamera();
initServer();
}
Fonction loop
Enfin, la fonction loop() gère en continu les requêtes des clients entrants.
void loop() {
server.handleClient();
}
Cette fonction garantit que le serveur reste réactif aux requêtes des clients, leur permettant de récupérer les images capturées par la caméra.
Test du serveur web ESP32-CAM
Testons maintenant le serveur web. Compilez et téléversez le code ci-dessus. Pour téléverser le code sur l’ESP32-CAM, passez la carte en mode programmation en basculant l’interrupteur, appuyez brièvement sur le bouton Reset de la carte, puis cliquez sur le bouton Upload dans l’Arduino IDE.
Si vous avez besoin d’aide pour téléverser le code sur l’ESP32-CAM, consultez le Programming the ESP32-CAM tutoriel qui donne plus de détails.
Après un téléversement réussi, vous verrez l’URL des images de la caméra affichée dans le moniteur série et vous devriez aussi voir le texte « CAMERA OK » :
http://192.168.1.146/cam.jpg CAMERA OK
Copiez cette URL dans la barre d’adresse de votre navigateur web et vous devriez voir la photo prise par la caméra :

Chaque fois que vous appuyez sur le bouton de rafraîchissement de votre navigateur, le serveur web prend cette requête, demande à l’ESP32-CAM de prendre une nouvelle photo et envoie cette nouvelle photo à votre navigateur. Ci-dessous, une photo de mon bureau prise de cette façon :

Dans la section suivante, nous enverrons les images au modèle de détection d’objets YOLO pour reconnaître les objets dans la scène.
Détection d’objets avec YOLO
YOLO (You Only Look Once) est un modèle d’apprentissage profond pour la détection d’objets, connu pour sa rapidité et sa précision. Il a été introduit pour la première fois par Joseph Redmon et al. in 2016. Depuis, plusieurs versions améliorées ont vu le jour, avec YOLO11 by Ultralytics comme la plus récente (en février 2025).
Cependant, nous allons utiliser un modèle plus ancien YOLOv3v, car il est plus petit et plus facile à utiliser, même si sa précision est inférieure aux modèles plus récents.

Le modèle YOLO est un réseau convolutionnel profond qui prend en entrée une image RGB de dimensions 448x448x3 et produit en sortie les boîtes englobantes et les scores de confiance des objets détectés dans un tenseur 7×7×30. Nous allons utiliser une version du modèle entraînée pour détecter 80 different objects, tels que :
- personne
- vélo
- voiture
- moto
- …
- ciseaux
- ours en peluche
- sèche-cheveux
- brosse à dents
Nous n’entrerons pas dans les détails du modèle ici, mais si vous souhaitez en savoir plus, voici les liens vers la publication originale de YOLO, une description des améliorations de la version 3 de YOLO, et un article d’application avec des informations utiles :
- YOLOv3: An Incremental Improvement
- You Only Look Once: Unified, Real-Time Object Detection
- YOLO v3: Visual and Real-Time Object Detection Model for Smart Surveillance Systems(3s)
Structure du dossier du projet
Pour exécuter le système de détection d’objets YOLO sur un PC, nous devons créer un dossier de projet, par exemple « esp32-cam-yolo-object-detection ». Dans ce dossier, créez un sous-dossier nommé « YOLO » et un fichier python nommé « detect.py ». La structure de votre dossier devrait ressembler à ceci :

Téléchargement des fichiers YOLO
Ensuite, vous devez télécharger les fichiers YOLO requis (poids, configuration de l’architecture, noms des classes) et les placer dans le dossier « YOLO » du projet. Voici les liens vers ces fichiers :
- https://pjreddie.com/media/files/yolov3.weights
- https://github.com/pjreddie/darknet/blob/master/cfg/yolov3.cfg
- https://github.com/pjreddie/darknet/blob/master/data/coco.names
Le contenu de votre dossier « YOLO » devrait alors ressembler à ceci :

Création d’un environnement virtuel
Nous devons aussi installer certaines bibliothèques Python et nous allons les installer dans un environnement virtuel avec venv. Ouvrez un terminal et exécutez les commandes suivantes :
cd esp32-cam-object-detection python -m venv venv venv\Scripts\activate.bat pip install opencv-python opencv-python-headless numpy torch torchvision
La commandecdnous déplace dans le dossier du projet. La commandevencrée l’environnement virtuel et à l’intérieur nous installons les bibliothèques requises viapip install. Cela créera un dossier « venv » dans le dossier du projet contenant les bibliothèques :

Code de détection d’objets
Enfin, en dernière étape, copiez le code suivant dans le fichier detect.py de votre dossier de projet.
import cv2
import numpy as np
import urllib.request
# Camera URL
url = "http://192.168.1.146/cam.jpg"
# YOLO model files
weights_path = r"./YOLO/yolov3.weights"
config_path = r"./YOLO/yolov3.cfg"
names_path = r"./YOLO/coco.names"
# Load the YOLO model and COCO class names
net = cv2.dnn.readNet(weights_path, config_path)
with open(names_path, "r") as f:
classes = [line.strip() for line in f.readlines()]
layer_names = net.getLayerNames()
# Handling the return value of getUnconnectedOutLayers()
out_layers = net.getUnconnectedOutLayers()
if isinstance(out_layers[0], list):
output_layers = [layer_names[i[0] - 1] for i in out_layers]
else:
output_layers = [layer_names[i - 1] for i in out_layers]
# Generate random colors for each class
colors = np.random.uniform(0, 255, size=(len(classes), 3))
def detect_objects(frame):
height, width, _ = frame.shape
blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)
net.setInput(blob)
layer_outputs = net.forward(output_layers)
boxes = []
confidences = []
class_ids = []
for output in layer_outputs:
for detection in output:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.3:
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)
x = int(center_x - w / 2)
y = int(center_y - h / 2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.3, 0.4)
# Draw detections on the frame
if len(indexes) > 0 and isinstance(indexes, np.ndarray):
indexes = indexes.flatten()
for i in indexes:
x, y, w, h = boxes[i]
label = str(classes[class_ids[i]])
confidence = confidences[i]
color = colors[class_ids[i]]
print(f"Detected: {label} with confidence {confidence:.2f}")
cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
cv2.putText(
frame,
f"{label} {confidence:.2f}",
(x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX,
0.5,
color,
2,
)
return frame
def main():
cv2.namedWindow("Object Detection", cv2.WINDOW_AUTOSIZE)
while True:
try:
img_resp = urllib.request.urlopen(url)
imgnp = np.array(bytearray(img_resp.read()), dtype=np.uint8)
frame = cv2.imdecode(imgnp, -1)
frame = detect_objects(frame)
cv2.imshow("Object Detection", frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
except Exception as e:
print(f"Error occurred: {e}")
break
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
Le code ci-dessus implémente un système de détection d’objets utilisant le modèle YOLO avec OpenCV. Il capture des images d’un flux caméra et détecte les objets en temps réel, affichant les résultats à l’écran.
Importation des bibliothèques
Nous commençons par importer les bibliothèques nécessaires : cv2pour les tâches de vision par ordinateur, numpy pour les opérations numériques, et urllib.request pour gérer les requêtes URL.
import cv2 import numpy as np import urllib.request
URL de la caméra
Ici, nous définissons l’URL du flux de la caméra à partir duquel nous capturerons les images. Vous devrez remplacer cette constante par l’URL que votre serveur web délivre :
url = "http://192.168.1.146/cam.jpg"
Fichiers du modèle YOLO
Ensuite, nous spécifions les chemins vers les fichiers du modèle YOLO : le fichier des poids, le fichier de configuration, et les noms des objets que le modèle peut détecter.
weights_path = r"./YOLO/yolov3.weights" config_path = r"./YOLO/yolov3.cfg" names_path = r"./YOLO/coco.names"
Chargement du modèle YOLO
Nous chargeons le modèle YOLO en utilisant le modulednnd’OpenCV et lisons les noms des classes depuis le fichier spécifié. Les noms des couches sont aussi récupérés pour un usage ultérieur.
net = cv2.dnn.readNet(weights_path, config_path)
with open(names_path, "r") as f:
classes = [line.strip() for line in f.readlines()]
layer_names = net.getLayerNames()
Couches de sortie
Nous déterminons les couches de sortie du réseau. C’est crucial pour savoir quelles couches fournissent les détections finales.
out_layers = net.getUnconnectedOutLayers()
if isinstance(out_layers[0], list):
output_layers = [layer_names[i[0] - 1] for i in out_layers]
else:
output_layers = [layer_names[i - 1] for i in out_layers]
Génération des couleurs pour les classes
Pour visualiser et distinguer les objets détectés, nous générons des couleurs aléatoires pour les boîtes englobantes.
colors = np.random.uniform(0, 255, size=(len(classes), 3))
Fonction de détection d’objets
La fonction detect_objects() prend une image en entrée, la traite, et détecte les objets avec le modèle YOLO. Elle retourne l’image avec les boîtes englobantes et les étiquettes dessinées.
def detect_objects(frame):
height, width, _ = frame.shape
blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)
net.setInput(blob)
layer_outputs = net.forward(output_layers)
boxes = []
confidences = []
class_ids = []
Dans cette fonction, nous créons d’abord un blob à partir de l’image d’entrée, une version prétraitée adaptée au modèle. Nous effectuons ensuite une passe avant pour obtenir la sortie du modèle.
Traitement des détections
Nous parcourons les sorties pour extraire les boîtes englobantes, les scores de confiance, et les IDs de classe des objets détectés. Seules les détections avec une confiance supérieure à 0,3 sont considérées valides. Vous pouvez modifier ce paramètre (0…1) pour afficher moins ou plus de détections selon la confiance.
for output in layer_outputs:
for detection in output:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.3:
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)
x = int(center_x - w / 2)
y = int(center_y - h / 2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
Suppression non maximale
Pour éliminer les boîtes redondantes qui se chevauchent, nous appliquons la suppression non maximale (NMS) pour ne garder que les meilleures boîtes.
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.3, 0.4)
Dessin des détections
Nous dessinons les boîtes englobantes et les étiquettes sur l’image pour chaque objet détecté. Le nom de la classe/objet détecté et le score de confiance sont affichés.
if len(indexes) > 0 and isinstance(indexes, np.ndarray):
indexes = indexes.flatten()
for i in indexes:
x, y, w, h = boxes[i]
label = str(classes[class_ids[i]])
confidence = confidences[i]
color = colors[class_ids[i]]
print(f"Detected: {label} with confidence {confidence:.2f}")
cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
cv2.putText(
frame,
f"{label} {confidence:.2f}",
(x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX,
0.5,
color,
2,
)
Fonction principale
La fonction main() ouvre une fenêtre pour afficher les détections et capture en continu les images du flux caméra. Elle traite chaque image via la fonction detect_objects() et affiche le résultat.
def main():
cv2.namedWindow("Object Detection", cv2.WINDOW_AUTOSIZE)
while True:
try:
img_resp = urllib.request.urlopen(url)
imgnp = np.array(bytearray(img_resp.read()), dtype=np.uint8)
frame = cv2.imdecode(imgnp, -1)
frame = detect_objects(frame)
cv2.imshow("Object Detection", frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
except Exception as e:
print(f"Error occurred: {e}")
break
cv2.destroyAllWindows()
Une fenêtre s’ouvrira et si vous appuyez sur « q » lorsque la fenêtre est active, l’application se terminera.
Point d’entrée de l’exécution
Enfin, nous vérifions si le script est exécuté directement et appelons la fonction main() pour démarrer le programme.
if __name__ == "__main__":
main()
Dans la section suivante, nous mettons tout ensemble et lançons notre système de détection d’objets.
Exécution du détecteur d’objets
D’abord, lancez votre module ESP32-CAM avec le code du serveur web et assurez-vous que l’ESP32-CAM capture des images et les affiche dans un navigateur web à l’URL affichée dans le moniteur série. Assurez-vous aussi que cette URL est utilisée dans detect.py, par exemple dans mon cas cette URL est :
url = "http://192.168.1.146/cam.jpg"
Ensuite, lancez le détecteur d’objets YOLO. Allez dans votre dossier de projet (« esp32-cam-object-detection »), activez l’environnement virtuel et exécutez le code du détecteur detect.py:
cd esp32-cam-object-detection venv\Scripts\activate.bat python detect.py
Notez que vous pouvez désactiver l’environnement virtuel en appelant :
venv\Scripts\deactivate.bat
Si le code tourne, vous devriez voir les noms des objets détectés avec leur score de confiance affichés dans la console :
Detected: cup with confidence 0.76 Detected: laptop with confidence 0.39 Detected: cup with confidence 0.51 Detected: laptop with confidence 0.33 Detected: cup with confidence 0.44 Detected: cup with confidence 0.65 Detected: cup with confidence 0.63
Une fenêtre nommée « Object Detection » s’ouvrira, montrant l’image actuelle vue par la caméra avec des boîtes englobantes autour des objets détectés. Ci-dessous un exemple où le système détecte correctement une tasse, une télécommande et un ordinateur portable :

Si vous souhaitez voir plus d’exemples des capacités de détection du modèle YOLO, rendez-vous sur le YOLO Demo Video.
Conclusions
Dans ce tutoriel, vous avez appris à construire un système de détection d’objets. Le module ESP32-CAM a été utilisé pour capturer des images et faire tourner un serveur web pour ces images. Les images ont ensuite été envoyées via Wi-Fi à un PC qui exécute un logiciel de détection d’objets basé sur le modèle d’apprentissage profond YOLO.
Compiler et téléverser du code sur l’ESP32-CAM peut être assez délicat. Si vous rencontrez des problèmes, consultez le Programming the ESP32-CAM tutoriel qui fournit des instructions plus détaillées.
Notez que notre petit système de détection d’objets est limité à 80 objets prédéfinis (ou classes). Cependant, vous pouvez entraîner le modèle YOLO avec vos propres objets. Le How to Train YOLOv3 to Detect Custom Objects? tutoriel peut vous aider si vous souhaitez faire cela.
Si vous avez d’autres questions, n’hésitez pas à les poser dans la section des commentaires.
Bon bricolage ; )


