Raspberry Pi Kamera - Raspistill Cheat Sheet und andere Dinge

Eine unsortierte Zusammenfassung von diversen Themen um die Kamera des kleinen Computers:

1. Parameter

Unter https://www.raspberrypi.org/documentation/raspbian/applications/camera.md findet man eine Übersicht, hier meine Erkenntnisse dazu:

--output, -o: Zieldateiname für das Bild. "-" schickt die Daten nach StdOut. Variable Namen erlauben Serienaufnamen (mittels timelapse, signal oder keypress), z.B. image%04d.jpg für image0001.jpg, image0002.jpg, ... bis image9999.jpg.

--latest, -l: Erstellt einen Hardlink unter diesem Namen zum letzten Bild einer (Serien-)Aufnahme. Achtung, wenn die einzelnen Bilder z.B. nach /dev/null geschoben werden, so verweist auch "latest" nach /dev/null!

--timeout, -t: setzt in Millisekunden eine Verzögerung vor dem Auslösen fest. Diese ist (leider) per default auf 5000 (5 Sekunden) gesetzt. Sinnvollerweise sollte man also immer --timeout 1 angeben, da eine 0 hier ein endloses Timeout angibt. Das wiederum macht nur Sinn, wenn man andere Auslösermethoden oder Serienaufnahmen machen will (siehe unten).

--timelapse, -tl: Abstand von Serienaufnahmen in Millisekunden. Man beachte, dass hier ein dynamischer Filename (-o image%04d) angeraten ist. Achtung, der Standardwert ist 10 Sekunden. Wenn das Timeout also auf 0 steht, und man sonst keine Angaben gemacht hat, dann wird alle 10 Sekunden ein Bild gemacht. Timelapse wird ignoriert, wenn man andere Auslöser wie Signal oder Keyboard verwendet.

--signal, -s: Die Kamera wartet auf ein USR1 oder USR2 Signal innerhalb des Timeouts. Eine eventuell gesetzte Timelapse wird daruch überschrieben. Raspistill wird dadurch nicht abgebrochen. Ein neues Signal erzeugt ein neues Bild (auch hier ergeben dynamische Namen oder ein Link-Latest Sinn).

--keypress, -k: Ähnlich dem Signal wird hier auf einen Tastendruck gewartet. "X" beendet das Programm vor Ablauf des Timeouts.

--annotate, -a/--annotateex,-ae: ermöglicht es, Text im Bild einzublenden. "annotate" erlaubt zwar viele Presets (Datum, Zeit, Kamera-Settings), hat aber keine Einstellungen für Schriftart, Position, etc.. Alternativ kann (sollte) man auch imagemagick dafür verwenden (siehe unten).

2. Performance

Ohne Parametertuning scheint es eine Ewigkeit zu dauern, bis ein Foto entsteht. Das liegt am unglücklichen default-timeout (siehe oben). Daher sollte man dringend (außer man will die Verzögerung so haben) das timeout auf 1 (Millisekunde) setzen.

Auf meinem Pi-Zero mit Raspbian (Stretch) dauert es dann 1,2 - 1,3 Sekunden ein Bild zu erstellen.

date +%T.%N; raspistill  --timeout 1 -o /mnt/ramdisk/latest.jpg; date +%T.%N; sleep 1; stat /mnt/ramdisk/latest.jpg
15:48:46.848899000
15:48:48.109720000
Datei: /mnt/ramdisk/latest.jpg
Größe: 5086071 Blöcke: 9936 EA Block: 4096 reguläre Datei
Gerät: 1eh/30d Inode: 109607 Verknüpfungen: 1
Zugriff: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Zugriff : 2018-03-06 15:48:47.135698000 +0100
Modifiziert: 2018-03-06 15:48:47.925698000 +0100
Geändert : 2018-03-06 15:48:47.925698000 +0100
Geburt : -

(Ich speichere die Bilder auf eine RAM-Disk, um hier 1. die SD-Karte nicht zu verschleißen und 2. Performanceeinbußen durch Schreibvorgänge auszuschließen. Dasselbe Ergebnis erhält man auch mit time raspistill ..., aber diese Methode funktioniert nicht beim zweiten Ansatz, der jetzt folgt.)

Schneller wird es, wenn man statt einmaligem direkten Auslösen ein Signal verwendet. Dadurch ist der Zugriff auf die Kamera nämlich schon aufgebaut und es wird nur noch der Chip ausgelesen und gespeichert. Dadurch lässt sich die Zeit auf ca. 0,5 Sekunden exklusive (!) Speichervorgang auf der SD-Karte reduzieren.

Dazu macht man 2 Sitzungen auf. Die erste hält sich und die Kamera bereit:

time raspistill --timeout 0 -s -o /mnt/ramdisk/image.jpg

Die zweite gibt das Signal (hier gleich mit der Performancemessung, etwas Umständlich, da wir nicht einfach time verwenden können):

pid=$(pgrep raspistill); date +%T.%N;  kill -USR1 $pid; date +%T.%N; sleep 1; stat /mnt/ramdisk/latest.jpg;

16:05:48.592178000
16:05:48.610335000
Datei: /mnt/ramdisk/latest.jpg
Größe: 4170058 Blöcke: 8152 EA Block: 4096 reguläre Datei
Gerät: 1eh/30d Inode: 111225 Verknüpfungen: 1
Zugriff: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Zugriff : 2018-03-06 16:05:48.585698000 +0100
Modifiziert: 2018-03-06 16:05:49.085698000 +0100
Geändert : 2018-03-06 16:05:49.085698000 +0100
Geburt : -

Man sieht die Steigerung auf ca. 0,5 Sekunden (zwischen dem kill Command um 16:05:48.6 und dem Änderungsdatum der Datei um 16:05:49.08)

Alternativ kann man das alles auch mittels Python oder anderen Programmiersprachen machen. Mir ging es darum, das alles mit einfachen Mitteln zu realisieren und aufzuzeigen!

Beispiele dafür gibt es hier: https://raspberrypi.stackexchange.com/a/75464/31029

Textoverlay mittels ImageMagick

Das kann man auch ohne Raspberry-Pi brauchen, aber ich sammel es einstweilen hier:

Das Tool convert aus dem Imagemagick Paket erlaubt einige Spielereien mit Bildern, wie z.B. aus der Kamera des Pis:

Inputfile: Der erste Parameter. Ein "-" liest von StdIn (z.B. von raspistill -o - | convert - [...])

Outputfile: Der letzte Parameter. Ein "-" schreibt nach StdOut (z.B.convert [...] - | convert - [...] /output/file.jpg)

-font Helvetica -fill white -stroke black
definieren z.B weißen Text mit schwarzem Rand in Helvetica. Der schwarze Rand ist sinnvoll bei Overlays über Kameras, da man nie weiß, welchen Hintergrund man hat.

-pointsize: Bei Bildern, deren Größe man nicht kennt, sollte man per Variable die Bildhöhe speichern und z.B. mit -pointsize $(($h/20)) eine relative Höhe angeben

-gravity: optional, Standardwert "Northwest". Definiert den Nullpunkt für Koordinatenangaben (normalerweise also links oben).

-annotate: Ist für Text etwas sympathischer, als das klassiche -draw. Hier wird gravity als Bezugspunkt genommen. Ein schnelles Beispiel: -annotate +0+$(($h/20)) positioniert unseren Text links oben mit variabler Schriftgröße (siehe oben).

Unser komplettes Beispiel für eine "Überwachungskamera" mit dem Raspberry-Pi mit Bildern in variabler Höhe (und Breite) sieht daher so aus:

h=1200; w=$(($h/3*4));raspistill -w $w -h $h --timeout 1 -o - | convert - -font Helvetica -fill white -stroke black -pointsize $(($h/20)) -annotate +0+$(($h/20)) "$(date +"%F %X")" /mnt/ramdisk/image.jpg

Weitere Infos zu ImageMagick:
https://www.imagemagick.org/script/command-line-options.php
https://www.imagemagick.org/Usage/files/
https://www.imagemagick.org/Usage/text/

Fokusieren der Kamera

Die Pi-Cam hat tatsächlich einen manuellen Fokus! Dieser lässt sich vorsichtig mit einer Spitzzange ändern (auf eigene Gefahr!), indem man das innere des "Objektives" in seinem Gehäuse dreht. Ein Video dazu gibts hier: https://www.youtube.com/watch?v=u6VhRVH3Z6Y