Skip to content

Technik Blog

IoT, Smart Home & Mikrocontroller einfach erklärt

Menu
  • Smarthome
  • Gartenautomation
  • Mikrocontroller
    • Arduino
    • ESP32 & Co.
    • Calliope Mini
    • Raspberry Pi & Pico
  • Solo Mining
  • Über mich
Menu

Arduino USB Camera am UNO Q: Einrichtung, Test und erste Projekte

Veröffentlicht am 10. November 202610. November 2026 von Stefan Draeger

Der Arduino UNO Q unterscheidet sich deutlich von einem klassischen Arduino UNO. Neben dem STM32U585 Mikrocontroller besitzt das Board mit dem Qualcomm Dragonwing QRB2210 einen zusätzlichen Prozessor, auf dem ein vollständiges Debian Linux läuft. Dadurch lassen sich Anwendungen umsetzen, für die auf einem klassischen Mikrocontroller schlicht die Rechenleistung und das Betriebssystem fehlen.

Ein Bereich, den ich dabei besonders interessant finde, ist die Bildverarbeitung. Passend zum UNO Q hat Arduino eine eigene USB Camera veröffentlicht, die speziell für Computer Vision, Objekterkennung und weitere KI-Anwendungen gedacht ist.

Ich habe mir die Arduino USB Camera für meinen Arduino UNO Q mit 2 GB RAM und 16 GB Speicher besorgt. Bevor ich damit jedoch Objekte erkenne oder eigene KI-Modelle ausprobiere, möchte ich zunächst herausfinden, wie sich die Kamera am UNO Q überhaupt verhält.

Arduino USB Camera am UNO Q im Test: Webcam und Objekterkennung
Dieses Video auf YouTube ansehen.

Wie wird sie angeschlossen? Wird sie von Debian automatisch erkannt? Welche Auflösungen stellt sie bereit? Wie einfach lässt sich ein Livebild anzeigen und wie können wir anschließend mit Python und OpenCV auf die Bilder zugreifen?

Debian hat die Kamera in meinem Test erkannt. Für eine scharfe Einzelaufnahme mit OpenCV musste ich den richtigen V4L2-Aufnahmeknoten auswählen, MJPEG einstellen und dem Autofokus nach dem Start etwas Zeit geben. Gleichzeitig möchte ich bereits einige Ideen zeigen, was sich später aus der Kombination von UNO Q und Kamera entwickeln lässt.

Inhaltsverzeichnis

  • Die Arduino USB Camera im Überblick
    • Technische Daten der Arduino USB Camera
  • Warum eine USB-Kamera am Arduino UNO Q interessant ist
  • Arduino USB Camera am UNO Q anschließen
  • Erkennt Debian die Arduino USB Camera automatisch?
  • Welche Videogeräte werden angelegt?
  • Arduino USB Camera mit Video4Linux untersuchen
  • Erstes Livebild ohne eigenen Programmcode
  • Arduino USB Camera mit Python und OpenCV verwenden
  • Einzelnes Kamerabild speichern
    • Troubleshooting bei der Einzelaufnahme
  • Was kann man mit der Arduino USB Camera am UNO Q machen?
  • Objekterkennung mit YOLOX-Nano auf dem Arduino UNO Q
    • ONNX Runtime und Modell installieren
    • Objekte im Kamerafoto erkennen
    • Erkennt YOLOX-X auch die Banane?
  • Fazit
  • Ausblick

Die Arduino USB Camera im Überblick

Bei der Arduino USB Camera handelt es sich zunächst einmal um eine USB-Webcam. Arduino setzt hier nicht auf eine eigene Kameraschnittstelle, sondern auf den verbreiteten USB Video Class Standard, kurz UVC.

Arduino CAM
Arduino CAM

Für die Verwendung unter Linux ist das ein großer Vorteil. Die Kamera kann vom Betriebssystem als normales Videogerät erkannt werden und benötigt keinen speziellen Arduino-Kameratreiber. Arduino beschreibt sie entsprechend als Plug-and-Play-Kamera für den UNO Q und VENTUNO Q. Weitere technische Angaben findest du in der offiziellen Arduino-Dokumentation zur USB Camera.

Im Inneren steckt ein Sony IMX376 Bildsensor. Arduino nennt für die Videoaufnahme 3840 × 2160 Pixeln bei 30 Bildern pro Sekunde im MJPEG-Format. Zusätzlich besitzt die Kamera einen Autofokus, ein integriertes Mikrofon sowie ein Ringlicht.

Technische Daten der Arduino USB Camera

EigenschaftTechnische Daten
BildsensorSony IMX376
Videoauflösung laut Arduino3840 × 2160 Pixel / UHD 4K
Bildrate bei 4Kbis zu 30 fps
Format bei 4KMJPEG
SchnittstelleUSB
KamerastandardUSB Video Class (UVC)
AutofokusJa
Fokusbereichca. 20 cm bis unendlich
BlendeF/2.0
Sichtfeld80° diagonal
Mikrofonintegriert
Beleuchtungintegriertes LED-Ringlicht
Lichtfarbewarmweiß und kaltweiß
Helligkeitper Touch dimmbar
MontageMonitor-Clip, Standfuß oder Stativgewinde
Treiberunter unterstützten Systemen keine zusätzlichen Treiber notwendig
Unterstützte Arduino-BoardsArduino UNO Q und VENTUNO Q
Anschluss am UNO Qüber USB-C-Hub bzw. Multiport-Adapter

Besonders interessant finde ich dabei weniger die maximale 4K-Auflösung als die Tatsache, dass es sich um eine normale UVC-Kamera handelt.

Dadurch können wir zunächst mit bekannten Linux-Werkzeugen arbeiten und müssen nicht sofort Arduino App Lab oder eine spezielle Bibliothek verwenden. Erst wenn der grundlegende Kamerazugriff funktioniert, können wir uns um OpenCV, Computer Vision oder KI kümmern.

Warum eine USB-Kamera am Arduino UNO Q interessant ist

An einem klassischen Arduino UNO wäre eine USB-Kamera mit 4K-Auflösung kaum sinnvoll nutzbar. Beim UNO Q sieht das anders aus.

Auf der Linux-Seite arbeitet ein Qualcomm Dragonwing QRB2210 mit vier Arm Cortex-A53-Kernen. Dazu kommen je nach Variante 2 oder 4 GB LPDDR4X-RAM sowie 16 oder 32 GB eMMC-Speicher. Mein Board ist die kleinere Variante mit 2 GB RAM und 16 GB eMMC.

Parallel dazu steht der STM32U585 als Mikrocontroller zur Verfügung. Linux und Mikrocontroller können über Arduino Bridge miteinander kommunizieren.

Zweizeiliges Schaubild zum Kameradatenfluss am Arduino UNO Q. Von der USB-Kamera geht es über Debian zur Bildverarbeitung. Das erkannte Ergebnis verzweigt zum MQTT-Server und über die Arduino Bridge zum STM32, der LED, Servo oder Relais ansteuert.
Die Arduino USB Camera liefert das Livebild an den UNO Q. Debian verarbeitet die Bilder und kann das erkannte Ergebnis per MQTT veröffentlichen oder über die Arduino Bridge an den STM32 weitergeben, der die angeschlossene Hardware ansteuert.

Die Linux-Seite kann beispielsweise ein Kamerabild analysieren und feststellen, dass sich eine bestimmte Person oder ein bestimmter Gegenstand im Bild befindet.

Der Mikrocontroller kann anschließend darauf reagieren und klassische Hardware ansteuern.

Gerade diese Verbindung zwischen einer relativ leistungsfähigen Linux-Plattform und der klassischen Arduino-Welt macht die Kamera am UNO Q für mich interessant.

Arduino USB Camera am UNO Q anschließen

Ganz direkt lässt sich die Kamera allerdings nicht am UNO Q anschließen.

Die Arduino USB Camera besitzt einen USB-A-Anschluss. Am UNO Q steht für USB-Peripherie dagegen der USB-C-Anschluss zur Verfügung. Deshalb benötigen wir einen entsprechenden USB-C-Hub beziehungsweise Multiport-Adapter.

Arduino nennt USB-Kameras ausdrücklich als unterstützte Peripherie über einen solchen USB-C-Adapter. Für den Betrieb als eigenständigen SBC empfiehlt Arduino einen Multiport-Adapter mit externer Power Delivery. Weitere Details findest du im UNO Q User Manual.

  • Arduino UNO Q mit 2 GB RAM und 16 GB Speicher
  • Arduino USB Camera
  • USB-C-Hub
  • Stromversorgung
  • Rechner für den Zugriff auf den UNO Q
Arduino UNO Q mit angeschlossenem USB-C-Hub und Arduino USB Camera
Arduino UNO Q mit angeschlossenem USB-C-Hub und Arduino USB Camera

Gerade die Stromversorgung werde ich beim Test im Auge behalten. Schließlich hängen sowohl der UNO Q als auch die zusätzliche USB-Hardware an diesem Aufbau.

Erkennt Debian die Arduino USB Camera automatisch?

Nach dem Anschließen interessiert mich zunächst nur eine Frage: Ist die Kamera überhaupt am USB-Bus angekommen?

Dafür benötigen wir noch keine zusätzliche Software und auch keinen Python-Code.

lsusb

lsusb zeigt die vom Linux-System erkannten USB-Geräte an. Arduino verwendet diesen Weg ebenfalls in seiner Debian-Dokumentation für den UNO Q.

Auf meinem UNO Q erscheint die Kamera als HHWei Technology Co., Ltd. Web Camera mit der USB-ID 1c45:6200.

arduino@draeger:~$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 343c:0210
Bus 001 Device 003: ID 343c:0210
Bus 001 Device 004: ID 0bda:8152 Realtek Semiconductor Corp. RTL8152 Fast Ethernet Adapter
Bus 001 Device 005: ID 1ea7:0066 SHARKOON Technologies GmbH [Mediatrack Edge Mini Keyboard]
Bus 001 Device 007: ID 1c45:6200 HHWei Technology Co., Ltd. Web Camera
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
arduino@draeger:~$
Ausgabe von lsusb mit angeschlossener Arduino USB Camera
Ausgabe von lsusb mit angeschlossener Arduino USB Camera

Interessant ist hier auch ein Vergleich vor und nach dem Anschließen der Kamera. Damit lässt sich eindeutig erkennen, welcher Eintrag zur Arduino USB Camera gehört.

Welche Videogeräte werden angelegt?

Dass lsusb die Kamera findet, bedeutet zunächst nur, dass das USB-Gerät erkannt wurde.

Als UVC-Kamera sollte sie vom Linux-Kernel anschließend über Video4Linux als Videogerät bereitgestellt werden.

ls /dev/video*

Abhängig vom Gerät können dort beispielsweise Einträge wie /dev/video0 und /dev/video1 auftauchen.

Dabei ist wichtig: Zwei /dev/video-Einträge bedeuten nicht automatisch, dass zwei Kameras angeschlossen sind. Eine einzelne USB-Kamera kann mehrere Video-Endpunkte bereitstellen.

arduino@draeger:~$ ls /dev/video*
/dev/video0  /dev/video1  /dev/video2  /dev/video3
arduino@draeger:~$
ArduinoUNOQ Terminal - Kamera via Video4Linux erkannt
ArduinoUNOQ Terminal – Kamera via Video4Linux erkannt

Arduino USB Camera mit Video4Linux untersuchen

Jetzt wissen wir, dass die Kamera vorhanden ist. Wir wissen aber noch nicht, welche Auflösungen und Videoformate tatsächlich angeboten werden.

Dafür eignen sich die Video4Linux-Werkzeuge.

sudo apt update
sudo apt install v4l-utils

Danach können wir uns die vorhandenen Videogeräte übersichtlicher anzeigen lassen:

v4l2-ctl --list-devices
ArduinoUNOQ Terminal - vorhandene Videogeräte auflisten
ArduinoUNOQ Terminal – vorhandene Videogeräte auflisten
arduino@draeger:~$ v4l2-ctl --list-devices
Qualcomm Venus video decoder (plat:5a00000.video-codec:dec):
        /dev/video1

Qualcomm Venus video encoder (plat:5a00000.video-codec:enc):
        /dev/video0

Web Camera: Web Camera (usb-xhci-hcd.2.auto-1.1):
        /dev/video2
        /dev/video3
        /dev/media0
arduino@draeger:~$

In dieser Ausgabe gehört /dev/video0 zum Qualcomm-Encoder. Nach einem Wechsel der Gerätenummer zeigte der Kameralink dagegen auf /dev/video0. Deshalb prüfe ich die Links mit ls -l /dev/v4l/by-id/ und bestätige mit v4l2-ctl -d PFAD --all, dass unter Device Caps der Eintrag Video Capture steht. Bei meiner Kamera ist das der Link mit video-index0. Ersetze PFAD durch deinen eigenen Kameralink.

cam="/dev/v4l/by-id/usb-HHWei_Technology_Co.__Ltd._Web_Camera_HHW006-video-index0"
v4l2-ctl -d "$cam" --list-formats-ext

Damit lassen sich unter anderem die unterstützten Pixelformate, Auflösungen und Bildraten des ausgewählten Videogeräts ausgeben.

Erste Formatabfrage am Qualcomm-Codec
Unterstützte Videoformate der Arduino USB Camera
Auszug aus der Formatliste der USB-Kamera

Type: Video Capture
MJPG: 640x480, 1280x720, 3840x2160 und 4656x3496 (jeweils bis 30 fps)
YUYV: 320x240 und 640x480 (jeweils bis 30 fps)

Die Formatliste meiner Kamera enthält zusätzlich einen MJPEG-Modus mit 4656 × 3496 Pixeln. Die Herstellerangabe von 3840 × 2160 Pixeln und der vom Treiber gemeldete Modus sind getrennte Angaben. Für spätere Computer-Vision-Anwendungen dürfte schließlich nicht die maximal mögliche Auflösung entscheidend sein, sondern welche Kombination aus Auflösung, Bildrate und Ressourcenverbrauch auf dem UNO Q sinnvoll funktioniert.

Erstes Livebild ohne eigenen Programmcode

Bevor wir OpenCV installieren oder eigenen Code schreiben, möchte ich zunächst ein Livebild sehen.

Damit können wir gleichzeitig überprüfen, ob die Kamera grundsätzlich funktioniert und ob der Videostream sauber ankommt.

Für eine schnelle Vorschau eignet sich ffplay. Öffne ein Terminal auf dem Debian-Desktop des UNO Q und installiere das Paket ffmpeg, falls es noch fehlt.

sudo apt update
sudo apt install ffmpeg

Starte die Vorschau mit dem Aufnahmegerät, das du im vorherigen Abschnitt mit v4l2-ctl --list-devices ermittelt hast. Verwende den zuvor ermittelten Kameralink. Falls du ein neues Terminal geöffnet hast, setze die Variable cam dort erneut.

ffplay -f v4l2 -input_format mjpeg -video_size 640x480 -framerate 30 "$cam"

Das Livebild erscheint in einem eigenen Fenster. Halte einen Gegenstand vor die Kamera und ändere den Abstand, um den Autofokus zu beobachten. Mit Q schließt du die Vorschau. Wenn du per SSH verbunden bist, brauchst du für diese Variante Zugriff auf den grafischen Desktop des UNO Q.

Für den eigentlichen Test interessieren mich dabei mehrere Punkte:

  • Wie schnell steht nach dem Start ein Kamerabild zur Verfügung?
  • Wie groß ist die sichtbare Verzögerung?
  • Wie zuverlässig arbeitet der Autofokus?
  • Wie verhält sich der Fokus bei kurzen Abständen?
  • Wie gut funktioniert das integrierte Ringlicht?
  • Wie verändert sich das Bild bei warmem und kaltem Licht?
Erstes Livebild der Arduino USB Camera
Erstes Livebild der Arduino USB Camera

Arduino USB Camera mit Python und OpenCV verwenden

Unter Debian installierst du das Python-Modul cv2 über das Paket python3-opencv. Verwende anschließend Debians System-Python (/usr/bin/python3), damit das Skript dieses Paket findet.

sudo apt update
sudo apt install python3-opencv

Wenn die Kamera unter Linux funktioniert, können wir den nächsten Schritt gehen und selbst auf die einzelnen Kamerabilder zugreifen. Genau dafür bietet sich OpenCV an.

import cv2

device = "/dev/v4l/by-id/usb-HHWei_Technology_Co.__Ltd._Web_Camera_HHW006-video-index0"
camera = cv2.VideoCapture(device, cv2.CAP_V4L2)
if not camera.isOpened():
    raise SystemExit(f"Kamera konnte nicht geöffnet werden: {device}")

camera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"MJPG"))
camera.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
camera.set(cv2.CAP_PROP_FPS, 30)

while True:
    ret, frame = camera.read()

    if not ret:
        print("Kein Kamerabild empfangen.")
        break

    cv2.imshow("Arduino USB Camera", frame)

    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

camera.release()
cv2.destroyAllWindows()

Die OpenCV-Vorschau verwendet denselben V4L2-Kameralink und dieselben Aufnahmeparameter wie ffplay. Passe device an deinen Aufbau an. Für cv2.imshow() brauchst du eine grafische Sitzung.

Der entscheidende Unterschied zum vorherigen Livebild besteht darin, dass wir jetzt jedes einzelne Bild als Datenstruktur innerhalb unseres Python-Programms erhalten. Ab diesem Punkt können wir anfangen, die Bilder zu verändern und auszuwerten.

Einzelnes Kamerabild speichern

Nicht jedes Computer-Vision-Projekt benötigt einen permanenten Videostream. Für einige Anwendungen reicht es vollkommen aus, in bestimmten Abständen ein einzelnes Foto aufzunehmen und anschließend auszuwerten.

Für mein Einzelbild verwende ich den Aufnahmeknoten der USB-Kamera unter /dev/v4l/by-id/. Das Skript fordert die höchste Auflösung an, die meine Kamera in der V4L2-Formatliste für MJPEG meldet (4656 × 3496 Pixel bei 30 fps). Vor dem Speichern verwirft es 60 Frames, damit der kontinuierliche Autofokus Zeit zum Scharfstellen hat.

Python-Skript takepicture.py anzeigen
import cv2

# Diesen Pfad an die eigene Kamera anpassen.
DEVICE = (
    "/dev/v4l/by-id/"
    "usb-HHWei_Technology_Co.__Ltd._Web_Camera_HHW006-video-index0"
)
OUTPUT = "aufnahme-max.jpg"

camera = cv2.VideoCapture(DEVICE, cv2.CAP_V4L2)

try:
    if not camera.isOpened():
        raise SystemExit(f"Kamera konnte nicht geöffnet werden: {DEVICE}")

    camera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"MJPG"))
    camera.set(cv2.CAP_PROP_FRAME_WIDTH, 4656)
    camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 3496)
    camera.set(cv2.CAP_PROP_FPS, 30)

    for _ in range(60):
        if not camera.grab():
            raise SystemExit("Kamera lieferte beim Start keinen Frame.")

    ok, frame = camera.read()
    if not ok or frame is None:
        raise SystemExit("Kein Kamerabild empfangen.")

    if not cv2.imwrite(OUTPUT, frame):
        raise SystemExit(f"Bild konnte nicht gespeichert werden: {OUTPUT}")

    height, width = frame.shape[:2]
    print(f"{OUTPUT} gespeichert ({width} × {height} Pixel).")
finally:
    camera.release()

Speichere das Skript als takepicture.py und starte es im Projektordner. Die Datei aufnahme-max.jpg landet im aktuellen Ordner. Die Terminalausgabe zeigt die tatsächlich empfangene Auflösung.

/usr/bin/python3 takepicture.py
ArduinoUNOQ aufnahme eines Bildes via Python Skript mit OpenCV
ArduinoUNOQ aufnahme eines Bildes via Python Skript mit OpenCV
Arduino CAM Bild in niedriger Qualität
Früher Test mit unscharfer Aufnahme. Im aktualisierten Skript bekommt der Autofokus vor dem Speichern mehr Zeit.

Das aufgenommene Bild können wir anschließend weiterverarbeiten oder an ein Modell zur Bilderkennung übergeben. Gerade für erste Experimente ist das deutlich einfacher, als sofort jedes einzelne Bild eines Videostreams analysieren zu wollen.

Troubleshooting bei der Einzelaufnahme

Die Kamera lässt sich nicht öffnen. Mit v4l2-ctl --list-devices und ls -l /dev/v4l/by-id/ findest du die Einträge der USB-Kamera. Prüfe den Kandidaten mit v4l2-ctl -d /dev/videoX --all. Unter Device Caps muss Video Capture stehen. Bei meinem Aufbau war der Link mit video-index0 der richtige Aufnahmeknoten.

Das Bild ist grün. Prüfe mit v4l2-ctl -d /dev/videoX --list-formats-ext, welche Kombination aus Pixelformat, Auflösung und Bildrate dein Aufnahmeknoten anbietet. Ein FFmpeg-Test mit dem bestätigten Kamerapfad und explizitem MJPEG lieferte bei mir ein sauberes Bild. Die genaue Ursache der grünen Aufnahme blieb offen.

Das Bild ist unscharf. Bei mir war focus_automatic_continuous bereits aktiv. Mit 60 verworfenen Startframes statt zehn hatte der Autofokus genug Zeit zum Scharfstellen.

Was kann man mit der Arduino USB Camera am UNO Q machen?

Wenn der grundlegende Kamerazugriff funktioniert, beginnt für mich der eigentlich interessante Teil.

Die Kamera ist zunächst nichts anderes als ein weiterer Sensor. Der Unterschied zu einem Temperatur- oder Abstandssensor besteht darin, dass der Messwert nicht aus einer einzelnen Zahl besteht. Die Kamera liefert ein komplettes Bild.

Schaubild in fünf Schritten. Der Arduino UNO Q nimmt ein Kamerabild auf, analysiert es, erkennt einen DHT22 und schaltet daraufhin eine LED ein.
Vom Kamerabild zur Aktion. Erkennt der Arduino UNO Q einen DHT22 im Bild, kann er als Reaktion eine LED einschalten.

Arduino nennt für die USB Camera in Arduino App Lab unter anderem YOLO-X, MediaPipe und Qwen VLM. Die Objekterkennung mit YOLO habe ich bereits mit der Shelly Camera und der ESP32-CAM ausprobiert. Damals habe ich einzelne Kamerabilder mit Ultralytics YOLO26 auf einem Dell OptiPlex ausgewertet. Beim UNO Q wäre für mich der nächste Schritt, die Bilder direkt von der USB-Kamera einzulesen und auf dem Board auszuwerten. Wie der Vergleich der beiden Kameras ausgefallen ist, zeige ich im Beitrag Bilderkennung mit der Shelly Camera und der ESP32-CAM.

Objekterkennung mit YOLOX-Nano auf dem Arduino UNO Q

Für einen ersten Test verwende ich YOLOX-Nano von Megvii. Das Modell verarbeitet das zuvor gespeicherte Kamerafoto lokal auf der CPU des UNO Q. Die Nano-Variante verwendet eine Eingabegröße von 416 × 416 Pixeln. Für dieses Beispiel lege ich eine Banane, einen Apfel und eine Orange vor die Kamera. Offizielle YOLOX-ONNX-Demo

ONNX Runtime und Modell installieren

Die virtuelle Umgebung übernimmt OpenCV und NumPy aus Debian. ONNX Runtime installiere ich separat in dieser Umgebung. Für Debian auf ARM64 und Python 3.13 steht ein passendes Paket zur Verfügung. ONNX Runtime auf PyPI

cd ~/arduino-cam
sudo apt install python3-venv curl
/usr/bin/python3 -m venv --system-site-packages .venv-yolox
source .venv-yolox/bin/activate
python -m pip install --only-binary=:all: onnxruntime
python -c 'import cv2, onnxruntime as ort; print(cv2.__version__, ort.get_available_providers())'
curl -fL -o yolox_nano.onnx https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano.onnx
Ausgabe in der Shell
arduino@draeger:~/arduino-cam$ sudo apt install python3-venv curl
python3-venv is already the newest version (3.13.5-1).
curl is already the newest version (8.14.1-2+deb13u7).
The following package was automatically installed and is no longer required:
  libwoff1
Use 'sudo apt autoremove' to remove it.

Summary:
  Upgrading: 0, Installing: 0, Removing: 0, Not Upgrading: 0
arduino@draeger:~/arduino-cam$ python3 -m venv --system-site-packages .venv-yolox
arduino@draeger:~/arduino-cam$ source .venv-yolox/bin/activate
(.venv-yolox) arduino@draeger:~/arduino-cam$ python -m pip install --only-binary=:all: onnxruntime
Collecting onnxruntime
  Downloading onnxruntime-1.31.1-cp313-cp313-manylinux_2_28_aarch64.whl.metadata (5.8 kB)
Collecting flatbuffers (from onnxruntime)
  Downloading flatbuffers-25.12.19-py2.py3-none-any.whl.metadata (1.0 kB)
Requirement already satisfied: numpy>=1.21.6 in /usr/lib/python3/dist-packages (from onnxruntime) (2.2.4)
Requirement already satisfied: packaging in /usr/lib/python3/dist-packages (from onnxruntime) (25.0)
Collecting protobuf>=4.25.8 (from onnxruntime)
  Downloading protobuf-7.36.2-cp310-abi3-manylinux2014_aarch64.whl.metadata (595 bytes)
Downloading onnxruntime-1.31.1-cp313-cp313-manylinux_2_28_aarch64.whl (21.4 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 21.4/21.4 MB 9.1 MB/s eta 0:00:00
Downloading protobuf-7.36.2-cp310-abi3-manylinux2014_aarch64.whl (344 kB)
Downloading flatbuffers-25.12.19-py2.py3-none-any.whl (26 kB)
Installing collected packages: flatbuffers, protobuf, onnxruntime
  Attempting uninstall: protobuf
    Found existing installation: protobuf 4.21.12
    Not uninstalling protobuf at /usr/lib/python3/dist-packages, outside environment /home/arduino/arduino-cam/.venv-yolox
    Can't uninstall 'protobuf'. No files were found to uninstall.
Successfully installed flatbuffers-25.12.19 onnxruntime-1.31.1 protobuf-7.36.2
(.venv-yolox) arduino@draeger:~/arduino-cam$ python -c 'import cv2, onnxruntime as ort; print(cv2.__version__, ort.get_available_providers())'
4.10.0 ['AzureExecutionProvider', 'CPUExecutionProvider']
(.venv-yolox) arduino@draeger:~/arduino-cam$ curl -fL -o yolox_nano.onnx https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_nano.onnx
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:03 --:--:--     0
100 3573k  100 3573k    0     0   876k      0  0:00:04  0:00:04 --:--:-- 9912k
(.venv-yolox) arduino@draeger:~/arduino-cam$

Objekte im Kamerafoto erkennen

Speichere das Skript als detect_yolox.py neben aufnahme-max.jpg und yolox_nano.onnx. Es verkleinert das Foto unter Beibehaltung der Proportionen und markiert die drei ausgewählten Objektklassen im Ergebnisbild.

Python-Skript detect_yolox.py anzeigen
from time import perf_counter

import cv2
import numpy as np
import onnxruntime as ort

image = cv2.imread("aufnahme-max.jpg")
if image is None:
    raise SystemExit("aufnahme-max.jpg konnte nicht gelesen werden.")

size = 416
height, width = image.shape[:2]
scale = min(size / width, size / height)
resized = cv2.resize(image, (int(width * scale), int(height * scale)))
padded = np.full((size, size, 3), 114, dtype=np.uint8)
padded[:resized.shape[0], :resized.shape[1]] = resized
tensor = np.ascontiguousarray(padded.transpose(2, 0, 1)[None], dtype=np.float32)

session = ort.InferenceSession(
    "yolox_nano.onnx", providers=["CPUExecutionProvider"]
)
inputs = {session.get_inputs()[0].name: tensor}
session.run(None, inputs)  # Aufwärmlauf
start = perf_counter()
prediction = session.run(None, inputs)[0][0]
print(f"Inferenz: {(perf_counter() - start) * 1000:.1f} ms")

# Der offizielle ONNX-Export liefert Boxen relativ zum Raster.
grids = []
strides = []
for stride in (8, 16, 32):
    y, x = np.indices((size // stride, size // stride))
    grids.append(np.stack((x, y), axis=-1).reshape(-1, 2))
    strides.append(np.full((x.size, 1), stride))

stride = np.concatenate(strides)
centers = (prediction[:, :2] + np.concatenate(grids)) * stride
sizes = np.exp(prediction[:, 2:4]) * stride
boxes = np.concatenate((centers - sizes / 2, sizes), axis=1) / scale
scores = prediction[:, 4:5] * prediction[:, 5:]
class_ids = scores.argmax(axis=1)
confidence = scores.max(axis=1)

# Die COCO-Indizes dieser drei Klassen sind nullbasiert.
names = {46: "Banane", 47: "Apfel", 49: "Orange"}
for class_id, name in names.items():
    candidates = np.flatnonzero((class_ids == class_id) & (confidence >= 0.25))
    if not candidates.size:
        continue
    selected = cv2.dnn.NMSBoxes(
        boxes[candidates].tolist(), confidence[candidates].tolist(), 0.25, 0.45
    )
    for index in candidates[np.asarray(selected, dtype=int).reshape(-1)]:
        x, y, w, h = boxes[index]
        left = max(0, int(x))
        top = max(0, int(y))
        right = min(width - 1, int(x + w))
        bottom = min(height - 1, int(y + h))
        if right <= left or bottom <= top:
            continue
        label = f"{name} {confidence[index]:.2f}"
        print(label)
        cv2.rectangle(image, (left, top), (right, bottom), (0, 255, 0), 3)
        cv2.putText(image, label, (left, max(25, top - 8)),
                    cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

if not cv2.imwrite("aufnahme-yolox.jpg", image):
    raise SystemExit("Ergebnisbild konnte nicht gespeichert werden.")
python detect_yolox.py
Ausführen von YOLOX auf dem Arduino UNO Q
Ausführen von YOLOX auf dem Arduino UNO Q

Das Skript gibt nach einem Aufwärmlauf die Dauer des ONNX-Aufrufs in Millisekunden aus und speichert aufnahme-yolox.jpg. Für den Vergleich mit meinem Fedora-Rechner verwende ich dieselbe Bilddatei und dasselbe ONNX-Modell. Die Aufnahme, Modellinitialisierung und Bildausgabe liegen außerhalb der Zeitmessung. Die Vergleichsmessung mit dem Fedora-Rechner steht noch aus.

Erkennt YOLOX-X auch die Banane?

Für meinen ersten Test lagen eine Mandarine und eine Banane nebeneinander vor der Kamera. YOLOX-Nano ordnete die Mandarine der Klasse Orange zu. Für die Banane gab mein Skript bei einer Konfidenzschwelle von 0,25 keine Erkennung aus. Deshalb probiere ich mit demselben Foto aus, ob das größere YOLOX-X beide Früchte erkennt.

Ich lade das offizielle ONNX-Modell herunter und kopiere das Nano-Skript. So kann ich beide Varianten mit demselben Bild testen und die Ergebnisbilder getrennt speichern.

cd ~/arduino-cam
source .venv-yolox/bin/activate

curl -fL -o yolox_x.onnx \
  https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_x.onnx

In detect_yolox.py ersetze ich yolox_nano.onnx durch yolox_x.onnx und setze size = 640. Damit verwendet das Skript die für diesen Export vorgesehene Eingabegröße von 640 × 640 Pixeln auch für das Raster der Boxen. Offizielle ONNX-Modellübersicht von YOLOX

python detect_yolox.py
Ausgabe des Ergebnisses von YoloX-X zum erkennen von Objekten
Ausgabe des Ergebnisses von YoloX-X zum erkennen von Objekten

Für beide Läufe verwende ich aufnahme-max.jpg und dieselbe Konfidenzschwelle von 0,25. YOLOX-Nano erkannte die Mandarine als Orange und brauchte 165,0 ms für die Inferenz. YOLOX-X erkannte auch die Banane, benötigte dafür aber 21.836,8 ms, also rund 21,84 Sekunden. Damit dauerte die Inferenz mit YOLOX-X in diesem Lauf etwa 132-mal so lange. Für ein einzelnes Foto kann sich die Wartezeit lohnen, wenn dadurch ein weiteres Objekt erkannt wird. Für eine laufende Vorschau wäre diese Inferenzzeit auf meinem UNO Q zu lang. Bei diesem Vergleich ändern sich Modellgröße und Eingabeauflösung gemeinsam. Beide Zeiten stammen aus je einem gemessenen Lauf nach dem Aufwärmen.

Objekte mit YoloX-X erkannt
Objekte mit YoloX-X erkannt

Fazit

Die Einrichtung der Arduino USB Camera am UNO Q lief bei mir eher holprig. Auf meinem Linux-Rechner und am Raspberry Pi hatte ich schnell ein Bild. Am UNO Q musste ich erst den richtigen V4L2-Aufnahmeknoten finden, MJPEG einstellen und dem Autofokus nach dem Start mehr Zeit geben. Nach ein paar Anläufen bekam ich damit eine scharfe Aufnahme.

Die Bildqualität hat mich dann überzeugt. Die Aufnahmen gefallen mir besser als die meiner Waveshare IMX708 und anderer Kameras, die ich bisher ausprobiert habe. Gerade bei der Waveshare hat mich das überrascht, weil sie deutlich mehr kostet als die Arduino USB Camera.

Bei der lokalen Objekterkennung zeigte sich, wie viel die Modellwahl auf dem UNO Q ausmacht. YOLOX-Nano brauchte für mein Testbild 165 ms und ordnete die Mandarine als Orange ein. YOLOX-X erkannte zusätzlich die Banane, brauchte dafür aber knapp 22 Sekunden. Für ein einzelnes Foto kann ich so lange warten. Soll ein Projekt direkt auf ein erkanntes Objekt reagieren, ist diese Wartezeit für mich zu lang.

Ausblick

Als Nächstes möchte ich mit der Kamera ein kleines Projekt bauen, bei dem der UNO Q auf ein erkanntes Objekt reagiert. Die Linux-Seite wertet das Kamerabild aus und gibt das Ergebnis über die Arduino Bridge an den STM32 weiter. Der Mikrocontroller kann dann zum Beispiel eine LED einschalten oder einen Servo bewegen.

Damit möchte ich meine Beitragsreihe zu Physical AI am Arduino UNO Q starten. Beim ersten Projekt interessiert mich vor allem, wie zuverlässig die Erkennung eine Aktion auslöst und wie viel Zeit vom Kamerabild bis zur Reaktion vergeht.

Transparenzhinweis: Dieser Beitrag wurde mit Unterstützung künstlicher Intelligenz erstellt und redaktionell geprüft. Mehr zur Nutzung von KI

Letzte Aktualisierung am: 10. November 2026

Foto von Stefan Draeger
Über den Autor

Stefan Draeger — Entwickler & Tech-Blogger

Ich zeige praxisnah, wie du Projekte mit Arduino, ESP32 und Smarthome-Komponenten umsetzt – Schritt für Schritt, mit Code und Schaltplänen.

Mehr Artikel von Stefan →

Schreibe einen Kommentar Antwort abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Kategorien

Kontakt & Hilfe

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden? Erstelle einfach ein Support-Ticket.

Support-Ticket erstellen
Keine Beiträge verpassen

Newsletter abonnieren

Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32, Smarthome und IoT direkt in dein Postfach.

Newsletter abonnieren
Videos & Tutorials

Draeger-IT auf YouTube

Entdecke meine Videos zu Arduino, ESP32, Raspberry Pi, Smarthome und spannenden Elektronikprojekten – mit Tutorials, Tests und Praxisbeispielen.

YouTube-Kanal besuchen
Freiwillige Unterstützung

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee. So hilfst du dabei, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

Auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kostenlose Online-Werkzeuge

Tools

Praktische Generatoren, Rechner und Hilfsmittel für deine Elektronik- und Entwicklungsprojekte.

Generatoren & Konverter

  • QR-Code Generator
  • Passwort Generator
  • PNG zu WebP konvertieren
  • Bilder online komprimieren
  • Code online formatieren

Rechner & Tabellen

  • Unix-Zeitstempel-Rechner
  • ASCII-Tabelle
  • ASCII Code umrechnen – Text, Dezimal, Hex & Binär
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner

LED-Matrix

  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix Generator
Kontakt

Anschrift & Kontaktdaten

Stefan Draeger

Königsberger Str. 13
38364 Schöningen

Telefon 01556 5432686

E-Mail info@draeger-it.blog

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com
Social Media

Folge mir auf

Weitere Projekte, Videos und Neuigkeiten findest du auch auf meinen Social-Media-Kanälen.

  • f Facebook
  • in LinkedIn
  • ▶ YouTube
  • ♪ TikTok
  • P Pinterest
  • ◎ Instagram
Rechtliche Informationen

Rechtliches

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
  • KI-Transparenz bei draeger-it.blog
©2026 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
  • Optionen verwalten
  • Dienste verwalten
  • Verwalten von {vendor_count}-Lieferanten
  • Lese mehr über diese Zwecke
Einstellungen anzeigen
  • {title}
  • {title}
  • {title}