ESP32 S3 Kamera - Live-Video an Python auf dem PC senden

Der ESP32 S3 ist ein kleines Board. Er kann sehr gut Bilder aufnehmen, aber er kann kein Gesicht erkennen, kein Autokennzeichen lesen und keine Katze im Bild finden. Ihr Computer kann all das problemlos.

Deshalb lassen wir jede Seite das tun, was sie gut kann: Der ESP32 S3 sendet das Live-Video über WLAN, und ein Python-Programm auf Ihrem Computer empfängt es. Sobald das Bild in Python ist, können Sie alles damit machen.

Das Python-Programm hat nur etwa 20 Zeilen.

ESP32 S3 Kamera - Live-Video an Python auf dem PC senden

Was Sie bauen werden:

  1. Eine ESP32 S3 Kamera, die Live-Video über WLAN sendet
  2. Ein kurzes Python-Programm, das das Video in einem Fenster auf Ihrem Computer anzeigt
  3. Eine Taste, um jederzeit ein Bild als Datei zu speichern
  4. Ein zweites Python-Programm, das Gesichter im Video findet, um Ihnen zu zeigen, wie es weitergeht

Erforderliche Hardware

1×ESP32 S3 N16R8 OV5640 Camera
1×(Alternativ) ESP32 S3 N16R8 OV2640 Camera
1×USB-Kabel Typ-A zu Typ-C (für USB-A PC)
1×USB-Kabel Typ-C zu Typ-C (für USB-C PC)
1×(Optional) DC-Stromanschluss
1×(Empfohlen) Screw Terminal Expansion Board for ESP32 S3
1×(Empfohlen) Breakout Expansion Board for ESP32 S3
1×(Empfohlen) Power Splitter for ESP32 S3

Oder Sie können die folgenden Kits kaufen:

1×DIYables Sensor-Kit (18 Sensoren/Displays)
Offenlegung: Einige der in diesem Abschnitt bereitgestellten Links sind Amazon-Affiliate-Links. Wir können eine Provision für Käufe erhalten, die über diese Links getätigt werden, ohne zusätzliche Kosten für Sie. Wir schätzen Ihre Unterstützung.

※ Notiz:

Das ESP32 S3 Kamera-Board hat 40 Pins, aber der Schraubklemmenblock und das Breakout-Board haben 44 Pins. Sie funktionieren trotzdem zusammen. Setzen Sie das Kamera-Board in die Mitte des 44-Pin-Boards, sodass auf der linken Seite 2 Pins frei bleiben und auf der rechten Seite 2 Pins frei bleiben.

Mit dem Schraubklemmenblock können Sie Drähte mit einem Schraubendreher anschließen, ganz ohne Löten. Das Breakout-Board bietet Ihnen einfache Stiftleisten für ein Breadboard.

Sie brauchen außerdem einen Computer mit Python. Windows, Mac und Linux funktionieren alle.

Wie es funktioniert

Der ESP32 S3 sendet das Video auf dieselbe Weise wie eine Webkamera, als MJPEG-Stream. Das sind einfach viele JPEG-Bilder, eins nach dem anderen.

Die gute Nachricht: Python versteht das bereits. Die Bibliothek OpenCV öffnet das Video mit einer Zeile, genau so, wie sie eine Videodatei oder eine USB-Webcam öffnet:

camera = cv2.VideoCapture("http://192.168.0.2/stream")

Hier ist der ganze Weg, den ein Bild zurücklegt:

SchrittWoWas passiert
1KameraNimmt ein Bild auf und packt es als JPEG
2ESP32 S3Sendet das JPEG über WLAN
3Ihr RouterLeitet es an Ihren Computer weiter
4PythonLiest es und macht daraus ein Bild, mit dem Sie arbeiten können
5Ihr CodeZeigt es an, speichert es oder sucht etwas darin
Wie das Video zu Python gelangt

Das Board hat außerdem zwei weitere Adressen, die während des Aufbaus nützlich sind:

AdresseWas sie Ihnen liefert
http://<IP>/Eine Webseite, um die Kamera zuerst in einem Browser zu testen
http://<IP>/streamDas Live-Video. Diese Adresse öffnet Python.
http://<IP>/photoEin einzelnes JPEG-Bild, falls Ihr Programm nur eines braucht

※ Notiz:

Testen Sie http://<IP>/ immer zuerst in Ihrem Webbrowser, bevor Sie Python starten. Wenn der Browser das Video zeigt, ist das Board in Ordnung, und jedes Problem danach liegt im Python-Teil. Diese eine Gewohnheit spart viel Zeit.

Verdrahtungsdiagramm

In diesem Projekt gibt es keine Verdrahtung. Der ESP32 S3 braucht nur Strom und WLAN.

ESP32 S3 Kamera Python Schaltplan

Dieses Bild wurde mit Fritzing erstellt. Klicken Sie, um das Bild zu vergrößern.

※ Notiz:

Ihr Computer und Ihr ESP32 S3 müssen im selben WLAN-Netzwerk sein. Wenn sie in verschiedenen Netzwerken sind, kann Python das Board nicht erreichen.

Arduino IDE Einstellungen für die ESP32 S3 Kamera

Die Kamera funktioniert nicht mit den Standardeinstellungen der Arduino IDE. Sie müssen einige Punkte im Menü Tools ändern, bevor Sie den Code hochladen.

Menüpunkt in ToolsDiese Auswahl treffen
BoardESP32S3 Dev Module
Flash Size16MB (128Mb)
PSRAMOPI PSRAM
Partition SchemeHuge APP (3MB No OTA/1MB SPIFFS)
CPU Frequency240MHz (WiFi)
USB ModeHardware CDC and JTAG
Upload ModeUART0 / Hardware CDC
Upload Speed921600
USB CDC On BootEnabled

DIYables ESP32 WebServer Bibliothek installieren

  1. Öffnen Sie die Arduino IDE.
  2. Klicken Sie auf das Symbol Libraries in der linken Leiste.
  3. Geben Sie DIYables ESP32 WebServer in das Suchfeld ein.
  4. Suchen Sie die Bibliothek von DIYables.io und klicken Sie auf INSTALL.
  • Search for DIYables ESP32 WebServer created by DIYables.io and click the Install button.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Library Manager
Type:
All
Topic:
All
DIYables ESP32 WebServer by DIYables.io
DIYables ESP32 WebServer library designed for ESP32 boards. It includes multi-page web server capabilities and WebSocket support for real-time communication, perfect for IoT projects and DIYables ESP32 boards. More info
1.0.1
INSTALL
Newbiely.ino
···
1 void setup() {
Output
Serial Monitor
Ln 1, Col 1
ESP32S3 Dev Module on COM15
1

ESP32 S3 Code

Ändern Sie oben WIFI_SSID und WIFI_PASSWORD. Sonst muss nichts geändert werden.

/* * Dieser ESP32 S3 Code wurde von newbiely.de entwickelt * Dieser ESP32 S3 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/esp32-s3/esp32-s3-camera-send-live-video-to-python-on-pc */ #include <WiFi.h> #include <DIYables_ESP32_WebServer.h> // DIYables ESP32 WebServer library #include "esp_camera.h" const char *WIFI_SSID = "YOUR_WIFI_SSID"; // CHANGE IT const char *WIFI_PASSWORD = "YOUR_WIFI_PASSWORD"; // CHANGE IT // The picture size. Bigger is nicer, but slower over WiFi. // FRAMESIZE_QVGA (320x240) is the fastest, FRAMESIZE_SVGA (800x600) is the biggest useful one. #define FRAME_SIZE FRAMESIZE_VGA // 640x480 #define JPEG_QUALITY 12 // 0 to 63. A bigger number makes a smaller file. // Camera pins of the ESP32-S3-N16R8 camera board. // The same pins work for the OV2640, OV3660 and OV5640 versions. #define PWDN_GPIO_NUM -1 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 15 #define SIOD_GPIO_NUM 4 #define SIOC_GPIO_NUM 5 #define Y9_GPIO_NUM 16 #define Y8_GPIO_NUM 17 #define Y7_GPIO_NUM 18 #define Y6_GPIO_NUM 12 #define Y5_GPIO_NUM 10 #define Y4_GPIO_NUM 8 #define Y3_GPIO_NUM 9 #define Y2_GPIO_NUM 11 #define VSYNC_GPIO_NUM 6 #define HREF_GPIO_NUM 7 #define PCLK_GPIO_NUM 13 DIYables_ESP32_WebServer server(80); // The text that separates one picture from the next one in the stream #define BOUNDARY "diyablesframe" const char INDEX_HTML[] = R"rawliteral( <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ESP32 S3 Camera for Python</title> <style> body { background:#111; color:#eee; font-family:sans-serif; text-align:center; margin:0; padding:16px; } img { width:100%; max-width:640px; border-radius:8px; } code { background:#222; padding:2px 6px; border-radius:4px; } </style> </head> <body> <h2>ESP32 S3 Camera</h2> <p>The video below is the same one your Python code reads.</p> <img src="/stream"> <p>Address for Python: <code>/stream</code></p> </body> </html> )rawliteral"; // Returns the name of the camera sensor that is installed on the board const char *getSensorName(int pid) { switch (pid) { case OV2640_PID: return "OV2640 (2 MP, max UXGA 1600x1200)"; case OV3660_PID: return "OV3660 (3 MP, max QXGA 2048x1536)"; case OV5640_PID: return "OV5640 (5 MP, max QSXGA 2592x1944)"; default: return "Unknown sensor"; } } bool initCamera() { camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sccb_sda = SIOD_GPIO_NUM; config.pin_sccb_scl = SIOC_GPIO_NUM; config.pin_pwdn = PWDN_GPIO_NUM; config.pin_reset = RESET_GPIO_NUM; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_JPEG; config.frame_size = FRAME_SIZE; config.jpeg_quality = JPEG_QUALITY; config.fb_count = 1; config.fb_location = CAMERA_FB_IN_DRAM; config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; if (psramFound()) { config.fb_location = CAMERA_FB_IN_PSRAM; config.fb_count = 2; // two buffers, so the video is smoother config.grab_mode = CAMERA_GRAB_LATEST; } else { config.frame_size = FRAMESIZE_QVGA; Serial.println("WARNING: PSRAM not found. Please set PSRAM to OPI PSRAM in the Tools menu."); } esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x\n", err); return false; } sensor_t *s = esp_camera_sensor_get(); Serial.printf("Camera sensor: %s\n", getSensorName(s->id.PID)); // Each sensor needs slightly different settings switch (s->id.PID) { case OV2640_PID: s->set_vflip(s, 0); s->set_hmirror(s, 0); break; case OV3660_PID: s->set_vflip(s, 1); // the OV3660 image is upside down by default s->set_brightness(s, 1); // make the image a little brighter s->set_saturation(s, -2); // make the colors a little softer break; case OV5640_PID: s->set_vflip(s, 0); s->set_hmirror(s, 0); break; default: break; } return true; } // Shows a small web page, so you can test the camera in a browser first void handleHome(WiFiClient &client, const String &method, const String &request, const QueryParams &params, const String &jsonData) { server.sendResponse(client, INDEX_HTML, "text/html"); } // Sends one JPEG picture. Good for Python code that wants single images. void handlePhoto(WiFiClient &client, const String &method, const String &request, const QueryParams &params, const String &jsonData) { camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("Photo capture failed"); server.sendResponse(client, "Photo capture failed", "text/plain"); return; } client.print("HTTP/1.1 200 OK\r\n"); client.print("Content-Type: image/jpeg\r\n"); client.printf("Content-Length: %u\r\n", fb->len); client.print("Connection: close\r\n\r\n"); client.write(fb->buf, fb->len); esp_camera_fb_return(fb); } // Sends the live video. This is the address the Python code opens. void handleStream(WiFiClient &client, const String &method, const String &request, const QueryParams &params, const String &jsonData) { Serial.println("A program opened the video stream"); client.print("HTTP/1.1 200 OK\r\n"); client.print("Content-Type: multipart/x-mixed-replace; boundary=" BOUNDARY "\r\n"); client.print("Access-Control-Allow-Origin: *\r\n"); client.print("Connection: close\r\n\r\n"); while (client.connected()) { camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("Frame capture failed"); break; } size_t len = fb->len; client.print("--" BOUNDARY "\r\n"); client.print("Content-Type: image/jpeg\r\n"); client.printf("Content-Length: %u\r\n\r\n", len); size_t sent = client.write(fb->buf, len); client.print("\r\n"); esp_camera_fb_return(fb); if (sent != len) { // the program on the PC stopped break; } } Serial.println("The video stream was closed"); } void setup() { Serial.begin(115200); delay(1000); if (!initCamera()) { Serial.println("Stopped"); while (true) delay(1000); } WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.print("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); WiFi.setSleep(false); // keep WiFi fast for the video server.addRoute("/", handleHome); server.addRoute("/photo", handlePhoto); server.addRoute("/stream", handleStream); server.begin(); Serial.print("Camera is ready. Put this address into your Python code: http://"); Serial.print(WiFi.localIP()); Serial.println("/stream"); } void loop() { server.handleClient(); }

Schnelle Schritte

  • Neu beim ESP32 S3? Arbeiten Sie zuerst unsere Anleitung Erste Schritte mit dem ESP32 S3 durch.
  • Installieren Sie die Bibliothek DIYables ESP32 WebServer.
  • Kopieren Sie den obigen Code und fügen Sie ihn in die Arduino IDE ein.
  • Ändern Sie WIFI_SSID und WIFI_PASSWORD auf Ihr eigenes WLAN.
  • Ändern Sie die Einstellungen im Menü Tools. Siehe die Tabelle oben.
  • Kompilieren Sie den Code und laden Sie ihn auf das ESP32 S3 Board hoch, indem Sie in der Arduino IDE auf die Schaltfläche Upload klicken.
Arduino IDE Code hochladen
  • Öffnen Sie den Seriellen Monitor in der Arduino IDE.
So öffnen Sie den Seriellen Monitor in der Arduino IDE
  • Drücken Sie einmal die Taste RESET.
  • Notieren Sie sich die Adresse, die der Serielle Monitor ausgibt. Sie brauchen sie im Python-Code.
  • Öffnen Sie diese Adresse in Ihrem Webbrowser und prüfen Sie, ob Sie das Video sehen.

Serieller Monitor

∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
[2026-09-28 16:00:01] Camera sensor: OV5640 (5 MP, max QSXGA 2592x1944) [2026-09-28 16:00:01] Connecting to WiFi... [2026-09-28 16:00:04] Camera is ready. Put this address into your Python code: http://192.168.0.2/stream [2026-09-28 16:00:31] A program opened the video stream [2026-09-28 16:01:58] The video stream was closed
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2

※ Notiz:

Die Zeile A program opened the video stream erscheint, wenn Ihr Python-Code startet. Wenn Sie sie nie sehen, erreicht Python das Board nicht, und das Problem liegt bei der Adresse oder dem Netzwerk.

Python und OpenCV installieren

  1. Installieren Sie Python von python.org. Unter Windows setzen Sie während der Installation das Häkchen bei Add python.exe to PATH.
  2. Öffnen Sie ein Terminal und installieren Sie OpenCV mit einem Befehl:
pip install opencv-python
  1. Prüfen Sie, ob es funktioniert hat:
python -c "import cv2; print(cv2.__version__)"

Sie sollten eine Versionsnummer sehen, zum Beispiel 4.12.0.

※ Notiz:

OpenCV ist die weltweit meistgenutzte Bibliothek für die Arbeit mit Bildern. Sie ist kostenlos und weiß bereits, wie man einen MJPEG-Stream liest, sodass Sie selbst nichts über JPEG oder WLAN schreiben müssen.

Python-Code - Beispiel 1: Das Video anzeigen

Das ist das ganze Programm. Es öffnet das Video, zeigt es in einem Fenster an und speichert ein Bild, wenn Sie die Taste s drücken.

/* * Dieser ESP32 S3 Code wurde von newbiely.de entwickelt * Dieser ESP32 S3 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/esp32-s3/esp32-s3-camera-send-live-video-to-python-on-pc */ import cv2 CAMERA_URL = "http://192.168.0.2/stream" # CHANGE IT to the address of your ESP32 S3 camera = cv2.VideoCapture(CAMERA_URL) if not camera.isOpened(): print("Cannot open the camera.") print("Check the address, and try it in your web browser first.") exit() print("The video is open.") print("Press ESC to stop, or press s to save a picture.") photo_number = 1 while True: ok, frame = camera.read() if not ok: print("No picture. Is the ESP32 S3 still on?") break # frame is a normal OpenCV picture. You can do anything you like with it here. cv2.imshow("ESP32 S3 Camera", frame) key = cv2.waitKey(1) & 0xFF if key == 27: # the ESC key break if key == ord("s"): file_name = "photo_%05d.jpg" % photo_number cv2.imwrite(file_name, frame) print("Saved", file_name) photo_number += 1 camera.release() cv2.destroyAllWindows() print("Stopped.")

Ändern Sie eine Zeile auf die Adresse aus Ihrem Seriellen Monitor:

CAMERA_URL = "http://192.168.0.2/stream" # CHANGE IT

Schnelle Schritte

  • Speichern Sie den Code als camera_pc_view.py auf Ihrem Computer.
  • Ändern Sie CAMERA_URL auf die Adresse Ihres Boards.
  • Öffnen Sie ein Terminal im selben Ordner und führen Sie ihn aus:
python camera_pc_view.py
  • Ein Fenster öffnet sich und zeigt das Live-Video.
  • Drücken Sie s, um ein Bild zu speichern. Drücken Sie ESC, um zu beenden.
The video is open. Press ESC to stop, or press s to save a picture. Saved photo_00001.jpg Saved photo_00002.jpg Stopped.
ESP32 S3 Kameravideo in einem Python-Fenster

Die wichtige Zeile

Alles Interessante passiert hier:

ok, frame = camera.read()

frame ist jetzt das Bild, als Tabelle von Zahlen. Das ist dieselbe Art von Bild, die jedes OpenCV-Beispiel im Internet verwendet. Ab dieser Zeile machen Sie also kein ESP32-Projekt mehr. Sie machen ein normales Computer-Vision-Projekt, und jedes Tutorial, jedes Beispiel und jede KI-Bibliothek funktioniert damit.

Python-Code - Beispiel 2: Gesichter finden

Um zu zeigen, was "jetzt können Sie alles machen" bedeutet, hier ist dasselbe Programm mit Gesichtserkennung. Es braucht keinen zusätzlichen Download, weil OpenCV einen Gesichtsfinder mitbringt.

/* * Dieser ESP32 S3 Code wurde von newbiely.de entwickelt * Dieser ESP32 S3 Code wird der Öffentlichkeit ohne jegliche Einschränkung zur Verfügung gestellt. * Für vollständige Anleitungen und Schaltpläne besuchen Sie bitte: * https://newbiely.de/tutorials/esp32-s3/esp32-s3-camera-send-live-video-to-python-on-pc */ import cv2 CAMERA_URL = "http://192.168.0.2/stream" # CHANGE IT to the address of your ESP32 S3 # OpenCV brings a ready-made face finder with it. Nothing to download. face_finder = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml") camera = cv2.VideoCapture(CAMERA_URL) if not camera.isOpened(): print("Cannot open the camera.") print("Check the address, and try it in your web browser first.") exit() print("Looking for faces. Press ESC to stop.") while True: ok, frame = camera.read() if not ok: print("No picture. Is the ESP32 S3 still on?") break # The face finder works on a black and white picture gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_finder.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(60, 60)) # Draw a green box around every face for (x, y, width, height) in faces: cv2.rectangle(frame, (x, y), (x + width, y + height), (0, 255, 0), 2) cv2.putText(frame, "%d face(s)" % len(faces), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 2) cv2.imshow("ESP32 S3 Camera - Faces", frame) if cv2.waitKey(1) & 0xFF == 27: # the ESC key break camera.release() cv2.destroyAllWindows() print("Stopped.")

Es wurden nur drei Dinge hinzugefügt:

# 1. Load the ready-made face finder face_finder = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml") # 2. Look for faces in the picture gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_finder.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(60, 60)) # 3. Draw a green box around every face for (x, y, width, height) in faces: cv2.rectangle(frame, (x, y), (x + width, y + height), (0, 255, 0), 2)

Führen Sie es auf dieselbe Weise aus:

python camera_pc_face.py
ESP32 S3 Kamera Gesichtserkennung in Python

※ Notiz:

Dieser Gesichtsfinder ist alt und einfach, aber er ist schnell und braucht nichts zusätzlich. Er findet nur Gesichter, die direkt in die Kamera schauen. Für bessere Ergebnisse sehen Sie sich die Liste unten an.

Was können Sie in Python sonst noch tun?

Sobald das Bild in frame ist, ist der ESP32 S3 Teil Ihres Projekts fertig. Das fügen die Leute normalerweise als Nächstes hinzu:

Was Sie möchtenWas Sie verwendenWie schwer
Gesichter findenOpenCV, bereits installiertEinfach
Personen, Autos, Tiere und 80 andere Dinge findenYOLO (pip install ultralytics)Einfach
Erkennen, wer eine Person istBibliothek face_recognitionMittel
Text und Zahlen im Bild lesenTesseract OCR (pip install pytesseract)Mittel
Einen QR-Code oder Barcode lesenOpenCV, bereits installiertEinfach
Hände, Körper und Gesichter verfolgenMediaPipe (pip install mediapipe)Einfach
Eine KI fragen, was sie siehtEin KI-Dienst mit einer Bild-APIMittel
Das Video in einer Datei aufzeichnenOpenCV VideoWriterEinfach
Eine Warnung an Telegram oder per E-Mail sendenPython requests oder smtplibEinfach

Zum Beispiel sind es etwa fünf Zeilen, um mit YOLO Personen zu finden:

from ultralytics import YOLO model = YOLO("yolov8n.pt") # downloads itself the first time results = model(frame) # look at the picture frame = results[0].plot() # draw the boxes

※ Notiz:

Ihr Computer erledigt die schwere Arbeit, nicht der ESP32 S3. Deshalb ist dieser Weg so stark: Ein kleines, günstiges Board wird zum Auge, und Ihr Computer wird zum Gehirn. Das Board weiß nicht einmal, dass jemand nach Gesichtern sucht.

Fehlerbehebung

Python meldet Cannot open the camera.

  • Öffnen Sie zuerst http://<IP>/ in Ihrem Webbrowser. Kein Video dort bedeutet, dass das Problem beim Board liegt, nicht bei Python.
  • Ihr Computer und das Board müssen im selben WLAN-Netzwerk sein.
  • Prüfen Sie, ob die Adresse in CAMERA_URL mit /stream endet.
  • Verwenden Sie http://, nicht https://.

Das Fenster öffnet sich, bleibt aber grau oder schwarz.

Warten Sie ein paar Sekunden. Das erste Bild kann einen Moment dauern. Wenn es schwarz bleibt, ist der Raum möglicherweise zu dunkel.

Python meldet ModuleNotFoundError: No module named 'cv2'.

OpenCV ist nicht installiert. Führen Sie pip install opencv-python erneut aus und stellen Sie sicher, dass Sie dasselbe Python verwenden, das Ihre Datei ausführt.

Das Video in Python hinkt dem Video im Browser hinterher.

OpenCV hält einige Bilder in einer Warteschlange. Stellen Sie sicher, dass Ihre Schleife kein time.sleep() enthält, und halten Sie Ihre eigene Arbeit kurz. Ein kleineres Bild hilft auch: Ändern Sie FRAME_SIZE im ESP32 S3 Code auf FRAMESIZE_QVGA.

Das Video ist langsam, nur wenige Bilder pro Sekunde.

  • Ändern Sie FRAME_SIZE im ESP32 S3 Code auf FRAMESIZE_QVGA (320 x 240).
  • Ändern Sie JPEG_QUALITY von 12 auf 16, damit die Bilder kleiner werden.
  • Bringen Sie das Board näher an den Router.

Das Video stoppt nach einigen Minuten.

Nur ein Programm kann das Video gleichzeitig lesen. Schließen Sie den Browser-Tab, der das Video anzeigt, und starten Sie Python dann erneut.

Der Serielle Monitor zeigt nie A program opened the video stream.

Python erreicht das Board nicht. Das ist ein Netzwerkproblem, kein Codeproblem. Prüfen Sie die Adresse und das WLAN.

Der Serielle Monitor zeigt nach den Startmeldungen nichts an.

Wenn Ihr USB-Kabel im Anschluss mit dem Namen UART steckt, stellen Sie USB CDC On Boot auf Disabled. Wenn es im Anschluss mit dem Namen USB steckt, stellen Sie es auf Enabled.

Anwendungen

Ein günstiges Board als Auge und ein Computer als Gehirn. Hier sind praktische Projekte, die Sie mit diesem Code bauen können:

  1. Türkamera mit Gesichtserkennung: Ihr Computer sieht ein Gesicht und öffnet die Tür oder schreibt die Uhrzeit in eine Datei.
  2. Personenzähler für einen Laden: Zählen Sie, wie viele Menschen im Laufe des Tages vorbeigehen.
  3. Kennzeichenleser: Lesen Sie das Kennzeichen mit OCR und öffnen Sie ein Tor für bekannte Autos.
  4. Paketdetektor: Lassen Sie YOLO erkennen, wenn ein Paket vor Ihrer Tür abgelegt wird, und senden Sie dann eine Nachricht an Ihr Handy.
  5. Haustierbeobachter: Erfahren Sie, wann Ihre Katze oder Ihr Hund in den Raum kommt, und zeichnen Sie nur diese Momente auf.
  6. Beobachter für Maschinen und 3D-Drucker: Stoppen Sie einen Druck, wenn das Bild zeigt, dass etwas schiefgelaufen ist.
  7. Qualitätsprüfung an einer Werkbank: Betrachten Sie jedes Teil, das an der Kamera vorbeikommt, und markieren Sie die fehlerhaften.
  8. Vogelhauskamera: Finden Sie mit einem Tiererkennungsmodell heraus, welche Vögel kommen.
  9. Fernbedienung per Handgeste: Winken Sie mit der Hand und lassen Sie den Computer eine Lampe einschalten.
  10. Computer Vision lernen: Ein sehr günstiger Weg, eine echte Live-Kamera in Ihren Python-Unterricht zu bringen.

Video Tutorial

Wir erwägen die Erstellung von Video-Tutorials. Wenn Sie Video-Tutorials für wichtig halten, abonnieren Sie bitte unseren YouTube-Kanal , um uns zu motivieren, die Videos zu erstellen.

Sehen Sie sich unten die Schritt-für-Schritt-Videoanleitung für dieses ESP32 S3 Projekt an.

Herausforderungen

  1. Einsteiger: Machen Sie das Bild in Python mit cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) schwarz-weiß, bevor Sie es anzeigen.
  2. Fortgeschrittene: Speichern Sie jedes Mal automatisch ein Bild, wenn ein Gesicht gefunden wird, mit der Uhrzeit im Dateinamen.
  3. Profis: Senden Sie einen Befehl zurück an den ESP32 S3, wenn Python etwas sieht. Fügen Sie dem Board eine Adresse wie /led_on hinzu und rufen Sie sie aus Python mit requests.get() auf. Im Tutorial ESP32 S3 - Telegram Bot erfahren Sie, wie Sie eigene Adressen hinzufügen.

Fortgeschrittenes Wissen - Warum HTTP hier gut genug ist

Viele Leute sehen sich dieses Projekt an und stellen eine berechtigte Frage: Python verwendet HTTP. Fragt es das Board nicht immer wieder nach einem neuen Bild? Das muss doch langsam sein.

Die Antwort ist nein, und es lohnt sich zu verstehen, warum.

Es gibt nur eine Anfrage

Python fragt ein einziges Mal, und die Verbindung bleibt dann für immer offen. Das Board schreibt neue Bilder in dieselbe offene Verbindung, bis Sie das Programm beenden.

Das funktioniert dank einer besonderen Antwort des Boards:

Content-Type: multipart/x-mixed-replace; boundary=diyablesframe

multipart/x-mixed-replace sagt der anderen Seite: *"Auf dieser Verbindung kommen weitere Bilder, und jedes neue ersetzt das vorherige"*. Das Board schreibt also einfach Bild für Bild:

while (client.connected()) { // one connection, it stays open camera_fb_t *fb = esp_camera_fb_get(); client.print("--" BOUNDARY "\r\n"); // a line to separate the pictures client.write(fb->buf, len); // the picture itself }

Sie können das selbst im Seriellen Monitor sehen. Die Zeile A program opened the video stream erscheint ein einziges Mal, wenn Python startet, nicht zehnmal pro Sekunde. Würde HTTP wirklich für jedes Bild neu fragen, würde diese Zeile über Ihren Bildschirm laufen.

Wie viel wird verschwendet?

Zwischen zwei Bildern sendet das Board nur ein Trennzeichen und zwei kurze Zeilen:

--diyablesframe 17 bytes Content-Type: image/jpeg 26 bytes Content-Length: 30000 25 bytes (empty line) 2 bytes = 70 bytes

Ein Bild mit 640 × 480 ist etwa 30000 Bytes groß. Der zusätzliche Text macht also etwa 0,2 % dessen aus, was gesendet wird. Zwei Bytes von tausend. Durch das Entfernen gibt es nichts zu gewinnen.

※ Notiz:

Eine andere Art des Sendens, ganz ohne HTTP, würde diese 70 Bytes pro Bild sparen. Bei einem Stream mit 10 Bildern pro Sekunde sind das 700 Bytes pro Sekunde, von etwa 300000. Sie würden den Unterschied nie bemerken.

Was wirklich etwas kostet

Die Verschwendung liegt nicht bei HTTP. Sie liegt an zwei anderen Stellen:

Echte KostenWarumKönnen Sie es beheben?
Jedes Bild ist ein vollständiges JPEGDer ESP32 S3 hat keinen Video-Encoder, daher kann er nicht nur "das, was sich geändert hat" senden, wie es ein Film tutNein. Das liegt an der Hardware.
Ihr Computer hält alte Bilder in einer WarteschlangeOpenCV hält einige Bilder vor, sodass das, was Sie sehen, einen Moment hinterherhinken kannJa, siehe unten
Nur ein Programm kann zusehenDer kleine Webserver antwortet jeweils nur einem ProgrammJa, mit einem größeren Server

Das zweite ist das einzige Problem, das die Leute wirklich bemerken. Die Lösung liegt auf der Python-Seite, nicht auf dem Board: Lesen Sie die Bilder im Hintergrund und nehmen Sie immer das neueste.

import cv2, threading class Camera: def __init__(self, url): self.capture = cv2.VideoCapture(url) self.frame = None threading.Thread(target=self.loop, daemon=True).start() def loop(self): while True: ok, frame = self.capture.read() # keep reading, never stop if ok: self.frame = frame # always keep only the newest one

※ Notiz:

Ihr eigener Code liest dann camera.frame, wann immer er bereit ist. Alte Bilder werden verworfen, statt in einer Warteschlange zu warten, sodass sich das Video wieder live anfühlt. Das hilft sehr, wenn Ihr Programm langsame Arbeit erledigt, zum Beispiel Objekterkennung.

Warum HTTP hier eine gute Wahl ist

Abgesehen davon, dass es schnell genug ist, bietet Ihnen HTTP Dinge, die eine eigene Übertragungsart nie bieten würde:

VorteilWarum es wichtig ist
Ihr Webbrowser kann es öffnenSie können die Kamera testen, bevor Sie eine Zeile Python schreiben
VLC kann es öffnenEin kostenloser Videoplayer zeigt den Stream ganz ohne Code
OpenCV öffnet es mit einer Zeilecv2.VideoCapture(url) und Sie sind fertig
Home Assistant und andere Programme kennen esIhre Kamera passt ohne zusätzliche Arbeit in ein Smart Home
Es läuft durch Ihren RouterKeine Portweiterleitung, keine speziellen Einstellungen
Es ist leicht zu untersuchen, wenn es nicht funktioniertJedes Problem ist in einem Browser sichtbar

※ Notiz:

Das ist der eigentliche Grund, HTTP zu wählen. Nicht die Geschwindigkeit, sondern dass alles es bereits spricht. Ein schnellerer Weg, den nur Ihr eigenes Programm versteht, ist meist ein schlechter Tausch.

Wann sollten Sie etwas anderes verwenden?

Es gibt echte Gründe für einen Wechsel, aber sie haben nichts mit den 70 Bytes zu tun:

ÜbertragungsartWählen Sie sie, wennKosten
MJPEG über HTTP (dieses Tutorial)Fast immerKeine
Rohes TCP, eigenes FormatDer PC ist das Gehirn und Sie möchten volle KontrolleSie schreiben beide Seiten selbst
UDPSie brauchen die geringstmögliche Verzögerung, und ein kaputtes Bild ist besser als ein verspätetesBilder kommen beschädigt oder gar nicht an
RTSPSie möchten die Kamera in ein Sicherheitssystem oder einen NVR einbindenEine Bibliothek und mehr Code
WebSocketEine Webseite muss das Video anzeigen und Befehle zurücksendenMehr Code auf beiden Seiten

※ Notiz:

Für ein Projekt, bei dem ein Computer die Bilder auswertet, ist MJPEG über HTTP die richtige Antwort. Ändern Sie es nur, wenn Sie ein echtes Problem gemessen haben, nicht weil HTTP langsam klingt.

※ UNSERE NACHRICHTEN

  • Sie können gerne den Link zu diesem Tutorial teilen. Bitte verwenden Sie jedoch unsere Inhalte nicht auf anderen Websites. Wir haben viel Mühe und Zeit in die Erstellung der Inhalte investiert, bitte respektieren Sie unsere Arbeit!