Zeitrafferaufnahmen mit dem RaspberryPi

Heute möchte ich einmal vorstellen wie man Zeitrafferaufnahmen mit dem Raspberry Pi machen kann.

Einzelbilder aufnehmen

Bevor ein Zeitraffer-Film erzeugt werden kann müssen erstmal die Einzelbilder dafür aufgenommen werden. Dazu gibt es natürlich mehrere Möglichkeiten, zwei davon möchte ich nun vorstellen.

1. Mit raspistill

Die erste und einfachste Möglichkeit besteht darin einfach das mitgelieferte Programm „raspistill“ zu verwenden. z.B.:

raspistill -o bild_%04d.jpg -t 40000 -tl 5000

Das erzeugt 40 Sekunden lang (40000 ms) alle 5 Sekunden (5000 ms) ein Bild.
Die Dateinamen haben dabei folgendes Muster: „bild_0000.jpg“, „bild_0001.jpg“ usw.

Dabei ist mir aufgefallen, das raspistill wenn es im timelapse Modus arbeitet andere Parameter wie z.b. (-ex, -sh, -ev usw.) ignoriert.
Daher ist es nicht möglich die Helligkeit, die Schärfe, den Kontrast oder andere Eigenschaften so einzustellen wie man es gerne hätte.

2. Mit einem Python Skript

ACHTUNG der folgende abschnitt ist VERALTET, er bleibt nur der Vollständigkeit halber bestehen !!
Eine verbesserte neue Version dieses Skriptes findet Ihr hier !

Das hat mich dazu gebracht ein Python3 Skript zu schreiben welches das Aufrufen von raspistill besorgt.
Durch dieses Skript ist es dann auch möglich die Aufnahmen mit allen Parametern die raspistill hergibt so einzustellen wie man es gerne haben möchte.

Hier der Code des Python3 Skriptes:

#!/usr/bin/python3

# Dieses Skript dient zur Erstellung von Zeitrafferaufnahmen mit dem Raspberry Pi.
# Das Skript speichert die Einzelbilder im Ordner des Skriptes und löscht vor dem aufnehmen neuer Bilder
# zunächst alle Bild Dateien mit gleichen Namen (Daran Denken !).
# Einstellschrauben sind die Variablen tl_name und die Einstellungen darunter.
# tl_name ist der Dateiname der Erzeugten Bilder, dort wird noch ein Zähler angehangen.
# Die Einstellung welche man benötigt testet man am besten vorher durch ausprobieren mit raspistill aus.

import os
import time
import subprocess
 
# Funktion zum löschen aller *.jpg Dateien die das Pattern enthalten.
def loeschen(path, pattern):
	for each in os.listdir(path):
		if (each.find(pattern) != -1 & each.find("jpg") != -1):
			name = os.path.join(path, each)
			try: 
				os.remove(name)
				print(name + " wurde gelöscht.")
			except:
				print("Löschen fehlgeschlagen")
				pass
	print("Alle Bilder erfolgreich gelöscht\n\n")
 
# Name für die Bilderreihe.
tl_name = 'Cobra11' 

# Kamera Einstellungen (siehe raspistill Manpage für genauere Infos).
photo_ex  = 'auto'
photo_awb = 'auto'
photo_effect = 'sketch'
#Exposure mode options :
#off,auto,night,nightpreview,backlight,spotlight,sports,snow,beach,verylong,fixedfps,antishake,fireworks
#AWB mode options :
#off,auto,sun,cloud,shade,tungsten,fluorescent,incandescent,flash,horizon
#Image Effect mode options :
#none,negative,solarise,sketch,denoise,emboss,oilpaint,hatch,gpen,pastel,watercolour,film,blur,saturation,colourswap,washedout,posterise,colourpoint,colourbalance,cartoon

# EV Level.
photo_ev = -5
 
# Auflösung und Qualität (max 2592 x 1944).
photo_width  = 2592
photo_height = 1944
photo_quality = 75

photo_sharpness = 50
photo_contrast = 10
 
photo_interval = 10 # Intervall zwischen den Fotos (Sekunden).
total_photos =   25 # Anzahl Fotos Gesamt.



photo_counter  = 1    	# Foto Zähler.

# Alle eventuell vorhandenen gleichnamigen Bilder Löschen.
try:
  loeschen("./", tl_name)  
except OSError:
  print(OSError)
  pass
 
# Fotos machen!
try:
  print("Raspistill Einstellungen:")
  print("Dateinamen:" + tl_name)
  print("Exposure:" + photo_ex)
  print("AWB:" + photo_awb)
  print("Effekt:" + photo_effect)
  print("EV:" + str(photo_ev))
  print("Auflösung:" + str(photo_width) + "x" + str(photo_height))
  print("jpg Qualität:" + str(photo_quality))
  print("Zeitabstand Einzelbilder:" + str(photo_interval) + "s" + "(Auslösezeit der Kamera kommt dort noch hinzu. ca 250ms)")
  print("Anzahl Bilder:" + str(total_photos) + "\n\n")
  print("Fotoserie gestartet\n")
  
# Solange der Zähler noch nicht das Ende erreicht hat neue Fotos machen.
  while(photo_counter < = total_photos):      
      filename = (tl_name + "_%.4d.jpg"%photo_counter)
      cmd = ('raspistill -t 250 -w ' + str(photo_width) +
            ' -h ' + str(photo_height) +
            ' -q ' + str(photo_quality) +
            ' -sh ' + str(photo_sharpness) +
            ' -co ' + str(photo_contrast) +
            ' -awb ' + photo_awb +
            ' -ev ' + str(photo_ev) +
            ' -ex ' + photo_ex +
            ' -ifx ' + photo_effect +
            ' -o ' + filename)
      pid = subprocess.call(cmd, shell=True)
      
      # Berechnung der Verbleibenden Zeit.
      rest_bilder = total_photos - photo_counter
      rest_sekunden = rest_bilder * photo_interval
      
      rest_zeit = rest_sekunden
      einheit = " Sekunden"
      if rest_sekunden > 86400:
          rest_zeit = rest_sekunden/86400
          einheit = " Tage"
      elif rest_sekunden > 3600:
          rest_zeit = rest_sekunden/3600
          einheit = " Stunden"
      elif rest_sekunden > 60:
          rest_zeit = rest_sekunden/60
          einheit = " Minuten"
      # Statusmeldung ausgeben.
      print(time.strftime("|--%d.%m.%Y - %H:%M:%S\n") + '|   [' +
            str(photo_counter) + ' von ' +
            str(total_photos) +
            '] ' + filename + '   ' +
            "%.2f"%rest_zeit + einheit + ' verbleibend\n|')
      time.sleep(photo_interval)
      photo_counter = photo_counter + 1
 
  print("Fotoserie beendet")
 
except KeyboardInterrupt:
  # Abbruch durch den Benutzer.
  print("\nAbgebrochen!")

timelapse.py3

Dieses Skript muss einfach in dem Verzeichnis wo die Einzelbilder aufgenommen werden sollen gespeichert werden.
Anschließend gibt man noch den gewünschten Dateinamen der Einzelbilder in der Variablen tl_name an und konfiguriert die Variablen für die Einstellungen an die eigenen bedürfnisse (welche man am besten erstmal mit ein paar Einzelbilder mit raspistill ausprobiert).

Jetzt muss man das Skript nur noch ausführen:

python3 ./timelapse.py3

Aber Achtung !
Soll das Skript über eine SSH Verbindung ausgeführt werden funktioniert das so nicht, denn sobald die SSH Verbindung unterbrochen wird bricht auch das Skript ab.
Dasselbe gilt natürlich auch für den normalen raspistill Aufruf im Timelapse Modus !

Um also über eine SSH Verbindung das Skript zu starten bedient man sich des Befehls „nohup“ wodurch die Ausführung des Skriptes nicht mehr von der SSH Verbindung abhängt.
Dadurch bekommt man dann allerdings die Statusmeldungen des Skriptes nicht mehr im Terminal angezeigt, weswegen ich diese dann in eine Datei umleiten.
Diese Datei kann ich dann jederzeit auslesen und habe alle Statusmeldungen des Skriptes parat und weiß wie lange es noch benötigt.

nohup python3 -u ./timelapse.py3 | tee ausgabe.txt &

Der Parameter -u von Python sorgt dafür das die Ausgaben nicht gepuffert werden. Das ist notwendig, damit die Umleitung in eine Datei mittels tee funktioniert.

Möchte man zwischenzeitlich einmal sichergehen, dass das Skript noch läuft, kann man das folgendermaßen überprüfen:

ps -ax | grep timelapse

steht das Skript in der Liste drin ist alles gut.

Die Einzelbilder zu einem Video zusammensetzen (LINUX)

Eine Möglichkeit die Einzelbilder zu einem Video zusammenzusetzen ist das Programm „avconv“.
Dazu sollte man sich die Bilder am besten erstmal auf einen normalen Linux PC kopieren, denn auf dem Raspberry kann dieser Vorgang je nach Anzahl der Bilder sehr, sehr lange dauern.

Zuerst muss avconv und ein Videocodec installiert sein, dazu:

sudo apt-get install libav-tools

um nun die Einzelbilder zu einer timelapse.mp4 zusammenzusetzen:

avconv -r 30 -i Video_%04d.jpg -r 30 -vcodec libx264 -g 15 -qscale 5 timelapse.mp4

Die einzelnen Parameter bedeuten hier:

  • -r setzt die fps. Es steht doppelt dort um avconv anzuweisen keine Frames auszulassen, auch wenn sie gleich aussehen.
  • -i Die Bilderserie die zusammengesetzt werden soll (hier video_0001.jpg , video_0002.jpg usw.)
  • -vcodec für den zu verwendenden Videocodec. (Verfügbare Codecs können mit avconv -codecs angezeigt werden)
  • -g gop Einstellung, hälfte der fps funktioniert meist gut.
  • -qscale Qualitätseinstellung (vom 1 bis 31, 1 excellent, 31 am schlechtesten)
  • Beispielaufnahmen


    Links

    6 Gedanken zu „Zeitrafferaufnahmen mit dem RaspberryPi

    1. Hallo,
      vielen Dank für dieses Skript.
      Es hilft mir als interresiertem Laien, die Raspi-Cam zu nutzen, obwohl ich vom Programmieren keinen echten Plan habe!

      Ich kann meinen Kindern coole Zeitraffer-Aufnahmen zeigen, wie sie sonst nur in
      der „Sendung mit der Maus“ kommen;-))

      Gruß
      Micha

    2. Moin.

      Das Skript gefällt mir sehr gut!
      Da ich leider von Python Skript Programmierung nicht viel Ahnung habe, hätte ich eine Bitte.
      Ist es möglich die Aufnahmen auch nach einem bestimmten Zeitablauf zu steuern?!
      Sprich; ich möchte das die Kamera von Montag bis Samstag von 10:00 bis 19:30 Uhr alle 10 Sekunden ein Foto macht. Die Bilder sollten dann jeweils in einem Ordner gespeichert werden der als Namen das aktuelle Datum (z.B. heute 230214 und morgen 240214) trägt.
      Für Unterstützung wäre ich dankbar.

      1. Hallo.

        Es freut mich das dir dieses Skript gefällt.
        Ich habe es vor kurzem „generalüberholt“. Angeregt durch deinen Kommentar hab ich es gerade auch Online gestellt (Link Unten). Leider habe ich gerade keine Zeit dazu deine gewünschte Funktionalität einzubauen, aber da ich in der neuen Version aber Bereits die Systemzeit verwende um die Intervalle zu realisieren, dürfte es kein Problem sein dort einfach auf die start bzw. Endzeit einen Offset zu Addieren um zu einer bestimmtem Zeit zu beginnen.
        Eventuell kann man auch direkt mit Absoluten Zeiten arbeiten, wobei das bei dem RaspberryPi nicht so viel Sinn macht, da er keine echte Hardware Uhr hat und man sich nicht so ohne weiteres auf Zeit und Datum verlassen kann.

        Vielleicht hast du ja Lust da selbst ein wenig weiterzubasteln. Ich weiß noch nicht wann ich wieder Zeit finde dort weiterzumachen.
        Hier der Link zur neuen Version: Version2

        1. Moin!


          aber da ich in der neuen Version aber Bereits die Systemzeit verwende um die Intervalle zu realisieren, dürfte es kein Problem sein dort einfach auf die start bzw. Endzeit einen Offset zu Addieren um zu einer bestimmtem Zeit zu beginnen.

          Bin sehr beeindruckt von dem Programm! Habe erst jetzt (2017) Dein Skript entdeckt und möchte fragen, ob Du zwischenzeitlich eine Progammergänzung entwickelt hast, die es ermöglicht, die Zeitrafferaufnahme zu einem bestimmten Zeitpunkt zu starten.
          Viele Leute, die sich so wie ich nicht mit Programmierungssprachen auskennen, würden sich wahrscheinlich über ein solches Feature enorm freuen.

          Beste Grüße
          ludi

    Schreibe einen Kommentar

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


    *