GPIO Reloaded III: Kamera

Das ist der dritte Teil einer Mini-Serie zur GPIO-Nutzung am Raspberry Pi 5:

  • GPIO Reloaded I: Python (gpiozero, lgpio, gpiod, rpi-lgpio)
  • GPIO Reloaded II: Bash (gpiod, gpioget, gpioset, pinctrl)
  • GPIO Reloaded III: Kamera (rpicam-xxx, Picamera2)

Genau genommen hat die Kamera-Nutzung nicht unmittelbar etwas mit GPIOs zu tun. Allerdings ist für die Kommunikation mit der Kamera ebenfalls der neu im Pi 5 integrierte RP1-Chip verantwortlich. Der Chip ist der Grund, weswegen alte Kamera-Tools auf dem Raspberry Pi 5 nicht mehr funktionieren. Bevor Sie zu schimpfen beginnen: Der RP1 hat viele Vorteile. Unter anderem können Sie nun zwei Kameras gleichzeitig anschließen und nutzen und höhere Datenmengen übertragen (wichtig für Videos).

Beachten Sie, dass Sie beim Raspberry Pi 5 zum Kamera-Anschluss ein neues, schmaleres Kabel benötigen!

Kamera-Modul 3 mit neuem, FPC-kompatiblen Kabel
Kamera-Modul 3 mit einem neuen, schmäleren Anschlusskabel

Veraltet: raspistill, raspivid, picamera2

Im Terminal bzw. in Bash-Scripts funktionieren raspistill, raspivid usw. nicht mehr. Sie müssen stattdessen rpicam-still, rpicam-vid etc. einsetzen.

In Python-Scripts müssen Sie Abschied vom picamera-Modul nehmen. Stattdessen gibt es das vollkommen neue Modul Picamera2. Es bietet (viel) mehr Funktionen, ist aber in der Programmierung komplett inkompatibel. Vorhandene Scripts können nicht portiert werden, sondern müssen neu entwickelt werden.

Sowohl die rpicam-xxx-Kommandos als auch das Picamera2-Modul greifen auf die ebenfalls neue Bibliothek libcamera2 zurück.

Im einfachsten Anwendungsfall erzeugen Sie ein Picamera2-Objekt, machen mit der Methode start_and_capture_file ein Foto und speichern dieses in eine Datei. Dabei kommt die volle Auflösung der Kamera zur Anwendung, beim Camera Module 3 immerhin fast 4600×2600 Pixel.

#!/usr/bin/env python3
# Beispieldatei camera.py
from picamera2 import Picamera2
cam = Picamera2()
# ein Foto machen und speichern
cam.start_and_capture_file("test.jpg")

Anstelle von start_and_capture_file gibt es zwei weitere Methoden, um ebenso unkompliziert Bilderfolgen bzw. Videos aufzunehmen:

# 10 Bilder im Abstand von 0,5 Sekunden aufnehmen
# mit Dateinamen in der Form series-0003.jpg
cam.start_and_capture_files("series-{:0>4d}.jpg", 
                            num_files=10, 
                            delay=0.5)
# Video über 10 Sekunden aufnehmen (640x480 @ 30 Hz, H.264/AVC1)
cam.start_and_record_video("test.mp4", duration=10)

rpicam-xxx-Kommandos

Zum Test der Kamera sowie zur Aufnahme von Bildern und Videos stehen die folgenden neuen Kommandos zur Auswahl:

  • rpicam-hello: zeigt für fünf Sekunden der Preview-Fenster mit dem Bild der Kamera an
  • rpicam-jpeg: nimmt ein Foto auf und speichert es als JPEG-Datei
  • rpicam-still: nimmt ein Foto auf und speichert es (mehr Optionen als rpicam-jpeg, Optionen etwas kompatibler zu raspistill)
  • rpicam-vid: nimmt ein Video auf und speichert es oder gibt den Video-Stream an externe Tools (livav/ffmpeg) weiter
  • rpicam-raw: speichert RAW-Videomaterial in einer Datei

Die Kommandos sind mit all ihren Optionen großartig dokumentiert. Es gibt zwar keine man-Seiten, aber dafür liefern die Kommandos mit der Option -h eine lange Liste aller Optionen (z.B. rpicam-still -h). Ich beschränke mich hier auf einige einfache Anwendungsbeispiele.

# fünf Sekunden lang ein Vorschaufenster anzeigen, dann 
# ein Foto aufnehmen und speichern
rpicam-jpeg -o image.jpg

# ohne Vorschau, Aufnahme nach einer Sekunde (1000 ms)
rpicam-jpeg -n -t 1000 -o image.jpg

# wie oben, aber Debugging-Ausgaben nicht anzeigen
rpicam-jpeg -n -t 1000 -v 0 -o image.jpg 

# Bildgröße 1280x800
rpicam-jpeg --width 1280 --height 800 -o image.jpg

# heller/dunkler (EV Exposure Compensation)
rpicam-jpeg --ev 0.5  -o brighter.jpg
rpicam-jpeg --ev -0.5 -o darker.jpg

# erstellt ein 10 Sekunden langes Video (10.000 ms) 
# 640x480@30Hz, H264-Codec
rpicam-vid -t 10000 -o test.mp4

# wie vorher, aber höhere Auflösung
rpicam-vid --width 1024 --height 768 -t 10000 -o test.mp4

Falls Sie mehr als eine Kamera angeschlossen haben, können Sie diese mit rpicam-hello --list-cameras auflisten. Die bei einer Aufnahme gewünschte Kamera können Sie mit der Option rpicam-xxx --camera <n> festlegen.

picamera2-Modul für Python-Scripts

picamera2 ist ein relativ neues Python-Modul. Es ersetzt das früher gebräuchliche Modul picamera. Der Hauptvorteil von picamera2 besteht darin, dass das Modul zu aktuellen Raspberry-Pi-Modellen kompatibel ist. Beim Raspberry Pi 5 kommt picamera2 auch mit dem Fall zurecht, dass Sie zwei Kameras gleichzeitig an Ihren Minicomputer angeschlossen haben.

Eine umfassende Referenz aller Klassen und Methoden finden Sie in der exzellenten Dokumentation (nur im PDF-Format verfügbar), die allerdings weit mehr technische Details behandelt, als Sie jemals brauchen werden. Eine Menge Beispiel-Scripts finden Sie auf GitHub.

Mit create_still_configuration können Sie in diversen optionalen Parametern Einstellungen vornehmen. Das resultierende Konfigurationsobjekt übergeben Sie dann an die configure-Methode. Wichtig ist, dass Sie das Foto nicht mit start_and_capture_file aufnehmen, sondern dass Sie die Methoden start und capture_file getrennt ausführen. Die folgenden Zeilen zeigen, wie Sie ein Bild in einer Auflösung von 1024×768 Pixel aufnehmen. Die sleep-Aufforderung verbessert die Qualität des Bilds. Sie gibt der Kamera-Software etwas Zeit, um die Aufnahme zu fokussieren und richtig zu belichten.

#!/usr/bin/env python3
from picamera2 import Picamera2, Preview
import time

# ein Foto in reduzierter Auflösung aufnehmen
cam = Picamera2()
myconfig = cam.create_still_configuration(
  main={"size": (1024, 768)} )
cam.configure(myconfig)
cam.start()
time.sleep(0.5)
cam.capture_file("1024x768.jpg")

Mit Transformationen können Sie das aufgenommene Bild vertikal und horizontal spiegeln. Falls Sie die Kamerakonfiguration während der Ausführung eines Scripts ändern möchten, müssen Sie die Kamera vorher stoppen und danach neu starten.

# (Fortsetzung des obigen Listings)
cam.stop()
from libcamera import Transform
mytrans = Transform(hflip=True)
myconfig = cam.create_still_configuration(
  main={"size": (1024, 768)},
  transform=mytrans)  
cam.configure(myconfig)
cam.start()
time.sleep(0.5)
cam.capture_file("1024x768-hflip.jpg")

Massive Video-Probleme

Bei der Aufnahme von Videos haben Sie die Wahl zwischen drei Encodern, die die aufgenommenen Bilder in Video-Dateien umzuwandeln:

  • H264Encoder (Hardware-Encoder für H.264, kommt per Default zum Einsatz, max. 1080p@30 Hz)
  • MJPEGEncoder (Hardware-Encoder für Motion JPEG = MJPEG)
  • JpegEncoder (Software-Encoder für MJPEG)

Hardware-Encoding steht nur auf dem Raspberry Pi 4 (H.264 und MJPEG) und dem Raspberry Pi 5 (nur H.264) zur Verfügung. Beim Raspberry Pi 5 läuft der MJPEGEncoder also per Software.

Das folgenden Script soll ein Video im Format 720p aufnehmen und gleichzeitig ein Vorschaubild anzeigen. Dabei soll der H.264-Codec eingesetzt werden.

#!/usr/bin/env python3
from picamera2 import Picamera2, Preview
from picamera2.encoders import H264Encoder, Quality
import time
cam = Picamera2()
myconfig = cam.create_video_configuration(
    main={"size": (1280, 720)})        # Auflösung 720p
myencoder = H264Encoder()
cam.configure(myconfig)
cam.start_preview(Preview.QTGL)
time.sleep(0.5)
cam.start_recording(myencoder, 
                    "test-720p.mp4", 
                    quality=Quality.MEDIUM)
time.sleep(10)
cam.stop_recording()
cam.stop_preview()

Das Script zeigt zwar keine Fehlermeldungen an, allerdings lässt sich die Video-Datei nicht abspielen, weder mit VLC am Raspberry Pi noch mit anderen Video-Playern auf anderen Rechnern. Ich habe tagelang mit den Video-Funktionen von Picamera2 experimentiert, aber die resultierenden Videos waren meist schwarz oder enthielten nur ein Bild, das am Beginn der Aufnahme entstanden ist. Auch die auf der folgenden Seite gesammelten Beispiel-Scripts zum Video-Recording funktionierten bei meinen Tests entweder gar nicht oder nur mit Einschränkungen:

https://github.com/raspberrypi/picamera2/tree/main/examples

Fazit: Die Video-Funktionen von Picamera2 sind aktuell (Anfang 2024) ebenso ambitioniert wie unausgereift. Es ist zu hoffen, dass neue Versionen von libcamera und Picamera2 und eine bessere Dokumentation der Grundfunktionen in Zukunft Abhilfe schaffen. Was nützen coole Spezial-Features, wenn es schon bei den einfachsten Grundfunktionen Probleme gibt?

Quellen/Links