Rekonstruktion einer Zeitreihe von Schneehöhen aus Fotos einer Wildtierkamera
Übersicht
Am Versuchsstandort Marquardt (10 km nördlich von Potsdam) wurde im Winter 2020/21 im Rahmen des Cosmic-Sense-Projektes ein Schneemonitoring betrieben. Dafür dienten Messstäbe, die in regelmäßigen Abständen von einer Wildtierkamera aufgenommen wurden.
Aufgabe ist es, Anhand der Länge der aus dem Schnee ragenden Stäbe auf den Fotos sowie deren Zeitstempel eine Zeitreihe der Schneehöhe zu ermitteln und diese mit den Aufzeichnungen eines Ultraschall-Schneepegels zu vergleichen.
Daten
Gegeben sind die Fotodaten der Wildtierkamera an Standort 02. An diesem Standort wurden 9 Stäbe beobachtet. Die Auswertung soll nur exemplarisch nur für einen Stab an diesem Standort erfolgen.
Die Daten liegen hier: https://boxup.uni-potsdam.de/s/WgoamrJjWBt6KAj Passwort: umweltdatenverarbeitung
fotos.zip: Archiv der Fotos
temp_precip_height.json: Beschreibung der Aufzeichnungen des Ultraschall-Schneepegels
temp_precip_height.txt : Aufzeichnungen des Ultraschall-Schneepegels
Ergebnisse
- examplarische Darstellung von Bildern (kein Schnee, viel Schnee)
- grafischer Vergleich1 der Schneehöhe an einem Messstab mit der Zeitreihe aus der Ultraschallmessung2
- kurze Beurteilung der Ergebnisse
Hinweise
- Die Auswertung soll halbautomatisch erfolgen. Dafür sollen alle Fotos des Verzeichnisses automatisch eingeladen 3 und dargestellt7 werden und die Lage der Spitze (einmalig, konstant) und des Fußpunkts des Stabs (variabel mit der Schneehöhe) durch Klicken4 des Nutzers bestimmt werden.
- Die Zeitpunkte der Fotoaufnahmen lassen sich aus dem Dateidatum oder (sicherer) deren EXIF-Informationen5 bestimmen.
- Die installierten Stäbe ragten 50 cm aus dem Boden. 5 cm vor der Spitze befindet sich eine weitere (rote) Referenzmarkierung, die ebenso genutzt werden kann.
- Die Erfassung soll vor allem für Phasen starker Änderung erfolgen; in Phasen gleicher Schneehöhe kann zwischen weiter auseinanderliegenden Aufnahmen interpoliert6 werden (muss aber nicht).
- Es ist evtl. sinnvoll, die Plots der Fotos auf den auszuwertenden Stab zu zoomen, um die Genauigkeit zu erhöhen.
- Die Koordinaten aufzunehmen ist natürlich etwas mühsam. Tipp: Speichere die aufgezeichneten Koordinaten als csv-Datei ab7 . Dann kannst Du sie immer wieder laden, wenn Du weiterarbeitest.
- Die Aufzeichnungen des automatischen Schneepegels sind als Vergleich einzuladen2 und Zeitstempel umwandeln9
- Achtung: Die Kameraperspektive driftet über den Messzeitraum hinweg nicht unerheblich (Kamera war evtl. nicht hinreichend stabil befestigt). Ihr dürft den daraus resultierenden Fehler aber im Kontext dieser Aufgabe einfach ignorieren: also ruhig mit einem konstantem Koordinatenpaar für die Spitze arbeiten, dann für jedes Bild den Fußpunkt registrieren und aus der Distanz zwischen beiden Punkten die freiliegende Pegellänge und somit die Schneehöhe approximieren.
Detailtipps für die Umsetzung in R
- 1 Lektion 2, Darstellung mit
plot()
- 2 Lektion 2,
read.table()
- 3 Lektion 5,
list.files()
, Lektion 3,for()
- 4 Funktion
locator()
- 5
file.info()
oder packageexiftool
- 6 Funktion
approx()
- 7 Funktion
write_table(...)
- 8 Lektion 5, ´load.image()´
- 9 ´strptime()´ und ´as.POSIXct()´
Detailtipps für die Umsetzung in Python
- 1 Bilder lesen mit
matplotlib.image.imread(...)
, plotten mitplt.imshow(...)
- 2 Lektion 2,
pandas.read_csv()
- 3 Lektion 5,
glob.glob()
, Lektion 3,for
- 4 Das ist in Python leider ein bisschen komplizierter…siehe unten.
- 5 In Python kannst Du den Zeitstempel einer Datei mittels
os.path.getmtime()
ermitteln. Der Zeitstempel kann dann mittelspd.to_datetime(..., unit="s")
in eindatetime
-Objekt umgewandelt werden. - 6 Funktion
scipy.interpolate.interp1d()
- 7 Funktion
pandas.to_csv(...)
Aufnahme von Abbildungskoordinaten in Python
Hier ist ein Beispiel, wie Du Punktkoordinaten aufnehmen kannst.
import matplotlib.pyplot as plt
import numpy as np
plt.ioff()
fig, ax = plt.subplots(1,1, figsize=(5,5))
myobj = plt.plot([2], [3], "k+", ms=15)
plt.xlim(0,10)
plt.ylim(0,10)
plt.title("Klicke auf den Punkt!")
coords = []
def onclick(event):
ix, iy = event.xdata, event.ydata
print("x = %d, y = %d" % (ix, iy) )
global coords
coords.append((ix, iy))
return coords
for i in range(2,5):
myobj[0].set_data((np.array([i]), np.array([i+1])))
plt.draw()
cid = fig.canvas.mpl_connect('button_press_event', onclick)
# Du hast 5 Sekunden
plt.pause(5)
fig.canvas.mpl_disconnect(cid)
plt.close()
print(coords)