Frühlingserwachen im Zeitraffer

Vor ein paar Wochen, als es noch Winter war, fiel mir ein Bild in die Hand, das ich letzten Sommer aus dem Fenster im Arbeitszimmer geschossen habe. Ich war über den Unterschied extrem erstaunt! Zum Vergleich zwei aktuelle Bilder aus diesem Jahr:

Garten im Winter Garten im Frühjahr

Zwischen den beiden Bildern liegt ein Unterschied von 44 Tagen. Oder um genau zu sein, 29. März zu 12. Mai. Da die Prozesse in der Flora nur sehr langsam ablaufen, ist für den Menschen an sich kaum möglich, den Blumen beim wachsen zuzusehen. Hier helfen nur technische Hilfsmittel. Also schaute ich mich in meinem Haushalt um, womit ich eine Zeitrafferaufnahme über mehrere Wochen laufen lassen kann.

Man nehme:

  • Raspberry Pi (Modell B Rev. 2)
  • Logitech C525 HD Webcam
  • 16GB SD-Card
  • 10W USB-Netzteil (in diesem Fall das Apple iPad Ladegerät)
  • Doppel- und Gewebeklebeband

Als Betriebssystem ist ein ganz normales Raspbian von Anfang 2013 auf der SD-Card installiert. Der Kernel ist sogar noch ein 3.2.27 vom Oktober 2012. Aber er enthält bereits das für diese Kamera notwendige Modul uvcvideo, sodass nicht noch ein neuer Kernel kompiliert werden muss. Die einzigen beiden nachträglich installierten Pakete sind uvcdynctrl und motion. Ersteres, um die Webcam einzustellen und letzteres für die regelmäßigen Bilder.

Mit dem ersten Befehl werden die verfügbaren Kameras angezeigt (hier die „HD Webcam C525“ an video0) und mit dem zweiten Befehl die verfügbaren Einstellungen.

root@raspberrypi:~# uvcdynctrl -l
Listing available devices:
video0 HD Webcam C525
Media controller device /dev/media0 doesn\'t exist
ERROR: Unable to list device entities: Invalid device or device cannot be opened. (Code: 5)
root@raspberrypi:~# uvcdynctrl -c
Listing available controls for device video0:
Exposure, Auto
Exposure (Absolute)
Exposure, Auto Priority
Pan (Absolute)
Tilt (Absolute)
Focus (absolute)
Focus, Auto
Zoom, Absolute
root@raspberrypi:~#

Mit der Option -f lassen sich die verfügbaren Auflösungen anzeigen, um die Auswahl für das andere Tool, motion, einfacher zu machen.

Nach dem ersten Aufnahmetag stellte ich fest, dass die Bilder zu stark “pumpen”, was der Kameraautomatik verschuldet war. Insbesondere bei starken Kontrastwechseln durch Wolken waren die aufeinander folgenden Bilder sehr unterschiedlich. Mit uvcdynctrl lassen sich beide Werte fest einstellen.

root@raspberrypi:~# uvcdynctrl -s 'Focus, Auto' 0
root@raspberrypi:~# uvcdynctrl -s 'Focus (absolute)' 0
root@raspberrypi:~# uvcdynctrl -s 'Exposure (Absolute)' 35
ERROR: Unable to set new control value: A Video4Linux2 API call returned an unexpected error 5. (Code: 12)
root@raspberrypi:~# uvcdynctrl -s 'Exposure, Auto' 1
root@raspberrypi:~# uvcdynctrl -s 'Exposure (Absolute)' 35

Die Namen der Controls können mit der bereits vorher schon genannten Option -c herausgefunden werden. Da die Namen Leerzeichen oder andere komische Zeichen enthalten, den Namen in einfache Anführungsstriche setzen.

Der Wert ‚Exposure (Absolute)‘ lässt sich beispielsweise im ersten Anlauf nicht setzen, da bei ‚Exposure, Auto‘ noch nichts gesetzt ist. Der Wert ‚1‘ schaltet ‚Exposure, Auto‘ nicht ein, wie sich vermuten lässt, sondern schaltet dieses auf den ‚Manual Mode‘. Das lässt sich mit den Optionen -c -v herausfinden, so wie auch alle anderen möglichen setzbaren Werte:

Exposure, Auto
ID : 0x0000000f,
Type : Choice,
Flags : { CAN_READ, CAN_WRITE },
Values : { 'Manual Mode'[1], 'Aperture Priority Mode'[3] },
Default : 0

Mit dem Wert von ’35‘ bei Exposure schaltet die Kamera beispielsweise nicht auf einen sensitiveren Wert in der Nacht um, sodass es tatsächlich ab der Dämmerung auf dem Bild dunkel und nachts gar ganz dunkel ist. Laternen oder Wohnungsbeleuchtungen reichen nicht aus, um ein Bild wahrzunehmen. Die eingestellten Werte lasse sich mit den Optionen -S und -L in eine Datei speichern und laden, da sie beim Abstöpseln der Kamera oder einem Reboot verloren gehen würden.

Am besten einfach mal mit den Werten herumspielen und das Ergebnis anschauen – Stopp! Bisher ist ja nur die Kamera angeschlossen und kein Ergebnis zu sehen. Da ich den Raspberry Pi headless betreibe, also ohne Monitor, brauche ich irgendwie eine Ausgabe. Das bringt uns zu motion.

Das Tool motion ist ein Daemon, der die Webcam ansprechen kann und diverse Aktionen durchführt. Wie der Name vermuten lässt, wurde es entwickelt, um so etwas wie eine Überwachungskamerafunktionalität mit Linux aufzubauen. Es kann regelmäßig Bilder aufnehmen, vergleichen und bei einer einstellbaren Schwelle an Änderungen Aktionen durchführen, wie beispielsweise Bilder aufnehmen oder irgend etwas anderes per Kommandozeile steuern.

In meinem Fall wollte ich drei Funktionen:

  1. Regelmäßige Aufnahme von Bildern
  2. Automatisches Erstellen eines Videos aus den Bildern
  3. Ansicht im Browser zur Überprüfung des Bildes

Bei Debian bzw. raspbian wird der motion Daemon in der Datei /etc/default/motion eingeschaltet. Die Datei /etc/motion/motion.conf dient zur Konfiguration. Als Beispiel, meine Änderungen gegenüber der Default-Configdatei:

# YU12 bzw. YUV520 Palette
# MJPEG lässt sich nicht aktivieren
v4l2_palette 8
# 720p ist mit dieser Kamera ohne Probleme möglich und da nur
# Standbilder aufgenommen werden, reicht der raspi
width 1280
height 720
# Generelle maximale Framerate für die Kamera
framerate 10
# Einstellungen für das automatische Video, hier:
# alle 300 Sekunden ein Bild und daraus täglich ein
# mpeg4 Video in der höchsten Bitrate/Qualität erstellen
ffmpeg_cap_new off
ffmpeg_timelapse 300
ffmpeg_timelapse_mode daily
ffmpeg_variable_bitrate 2
ffmpeg_video_codec mpeg4
# Intervall für jpg-Snapshots, hier alle 60 Sekunden
snapshot_intervall 60
# Text, der unten rechts im Video eingeblendet wird (Datum, Zeit)
text_right %Y-%m-%d\n%T
# Datei zum speichern; Motion speichert per default nach /tmp, was
# bei einem Reboot gelöscht wird!
target_dir /srv/motion
# die JPGs sortiert speichern, um nicht zu viele Dateien in einem
# Ordner zu haben (1 Tag = 60 Bilder ⨉ 24 Stunden = 1440 Dateien)
snapshot_filename %Y/%m/%d/%H-%M-%S
# Dateiname für die mpg-Dateien
timelapse_filename %Y%m%d-%H%M-timelapse
# Port für die Browser-Funktion angeben, um diese einzuschalten
webcam_port 8081
webcam_maxrate 10
webcam_localhost off
# Motion nicht über einen Browser-Interface konfigurieren lassen
control_port 0

LangzeitaufnahmeMotion kann einfach mit dem Init-Script gestartet werden. Jetzt kann via HTTP im Browser auf der IP des Raspi und dem Port 8081 das aktuelle Bild betrachtet werden. Die Aktualisierung braucht durchaus ein paar Sekunden, insbesondere, wenn an uvcdynctrl-Werten etwas geändert wird. Die Kamera habe ich mit Doppelklebeband von innen an die Scheibe geklebt und mit Gewebeklebeband gefixt. Das ganze Setup baute ich am 10. April auf. Am 11. und 12. April machte ich ein paar Einstellungen an motion und uvcdynctrl, um Exposure und Focus unter Kontrolle zu bekommen. Außerdem verwendete ich die Funktionen für Pan und Tilt, um nur den Ausschnitt rechts oben mit Bäumen ins Bild zu holen statt den Garten mit den Sandkästen. Am 4. Mai beendete ich die Aufnahmen, was 22 Tagen entspricht. Der raspi lief die ganze Zeit ohne Reboot oder Zucken durch. Auch wenn motion mit der Webcam-Funktion die CPU nahezu am Anschlag laufen lässt, gab es keine Hitzeprobleme oder ähnliches. Ich bin von der Stabilität dieses Kleincomputers sehr erstaunt! Selbst die Installation eines FTP-Daemons zum besseren Download der Bilddateien statt über sftp hat des raspi nicht gestört.

Nun ging ich davon aus, dass ich einfach die täglichen, von motion erstellten Videos nehmen könnte, um eine schöne Timelapse-Aufnahme zu erstellen. Doch leider stellte sich heraus, dass entweder motion oder der raspi Probleme verursachen und recht häufig Artefakte aus sich überschneidenden Bildern dargestellt werden. Außerdem sind die schwarzen Nächte recht lang, sodass ich die Videos eh hätte schneiden müssen.

Glücklicherweise hatte ich ich in der motion-Config angegeben, dass minütlich ein JPG-Bild aufgenommen werden soll. Pro Tag kommen dort so 100MiB bis 150MiB für die 1440 Bilder zusammen, je nach Sonnenscheindauer, Wetter und der damit verbundenen Anzahl an Farben. Von diesen Bilder habe ich erstmal getrost gelöscht, was wirklich Nacht ist. Also, alles zwischen 22 und 04 Uhr. Da Sonnenauf- und -untergang nicht nur vom Tag sondern auch vom Wetter abhängig sind, konnte ich keine fixen Uhrzeiten raussuchen, welche Bilder ich löschen konnte. Stattdessen benutzte ich das Tool identify aus der ImageMagick Suite. Mit der Option -format %k gibt identify die Anzahl der Farben in einem Bild aus. Stichproben ergaben, dass selbst in schwarzer Nacht die Kamera immer noch so etwa 75 Farben zurück gibt. Mit Einsetzen der Dämmerung nimmt die Anzahl der Farben schlagartig auf mehrere Tausend zu. Als guten Schwellwert ermittelte ich 100 Farben. In einer Schleife sieht das so aus:

for pic in *.jpg; do colors=$(identify -format %k ${pic}); echo "${pic}: ${colors}"; [[ "${colors}" -lt "100" ]] && rm ${pic}; done;

Zum Erstellen des Videos las ich noch mehrere Stunden lang ffmpeg-Parameter und testete diverse Einstellungen aus. Das beste Ergebnis bekam ich mit

ffmpeg -r 30 -f image2 -pattern_type glob -i "*-?0-00.jpg" -crf 18 -preset slow springtime.mp4

Das erstellt ein Video mit einer Framerate von 30 Bildern pro Sekunde (also etwas mehr als die üblichen 25 im Fernsehen oder 24 im Kino), die einem Pattern entsprechen. Das Pattern löst sich zu „alle Bilder, die zu einer Minute mit 0 am Ende aufgenommen wurden“, also „alle 10 Minuten“ auf. Mit -crf 18 -preset slow wird eine variable Bitrate mit hoher Qualität verwendet. Das Umkodieren der 1925 verwendeten Bilder hat knapp 9 Minuten gedauert; dabei sind 64 Sekunden an Film heraus gekommen. Das kommt auch von den eingegebenen Bildern hin: Bei „ein Bild alle 10 Minuten“ sind das 6 Bilder pro Stunde. Bei 30fps ist das 1/5 Sekunde pro Stunde. Im April sind es etwa 14,5 Stunden von der Morgen- bis zur Abenddämmerung, was ungefähr 2,9 Sekunden für einen Tag (die Nacht habe ich ja entfernt) ausmacht. Bei 22 Tagen mit 2,9 Sekunden komme ich auf die 64 Sekunden Film.

Viel geredet, hier ist der Film:


Link zu Vimeo

Im Laufe der Zeit neigte sich die Kamera immer weiter nach oben, da morgens die direkte Sonne auf das Fenster schien und das Klebeband gelöst hat. Aber es ist sehr schön zu beobachten, wie es von unten herauf immer grüner wurde. Der richtige Durchbruch kam dieses Jahr um den 21. April.

Update:

Die im Hintergrund zu sehende Schwarzpappel wurde am 8.8.2013 gefällt. Sie war morsch geworden und bei jedem Sturm ließ sie große Äste fallen. Es gab wohl Befürchtungen, dass sie ganz umstürzt und dabei das denkmalgeschützte Haus (der erste Nachkriegsplattenbau der DDR) zerstört. Anhand der Jahresringe konnte ich ablesen, dass sie etwa 60 Jahre alt wurde – in dieser Zeit aber enorm mit einem Umfang von über 5m wuchs.

Gefällte SchwarzpappelIm Video habe ich damit zufälligerweise den letzten Frühling dieses Baumes aufgenommen.