TIL: Mein Mapillary Workflow

Hin und wieder nehme ich beim Rad fahren mit einer GoPro die Umgebung vor meinem Lenker für Mapillary auf. Dabei ist die GoPro so eingestellt, dass sie ein Foto pro Sekunde erstellt.

Um diese Bilder mit korrekten Geodaten zu versehen und zu Mapillary hochzuladen, nutze ich das Command Line Utility von Mapillary. Dieses hat unfassbar viele Optionen und Möglichkeiten – es hat einen Moment gedauert, bis ich mir die notwendigen Schalter herausgesucht hatte.

Mein Workflow ist momentan teilautomatisch, einige Schritte sind noch nicht geskriptet – das werde ich aber ggf. noch nachholen. Prinzipiell lässt sich der Ablauf wie folgt beschreiben:

Vor der Aufnahme

  • Systemzeit der GoPro mit dem Telefon synchronisieren
  • die μSD-Card formatieren
  • (beides lässt sich über die GoPro iOS App erledigen)

Während der Aufnahme

  • Foto-Modus
  • ein Bild pro Sekunde

Bereitstellung für Mapillary

Ich habe ein Makefile, welches bei einigen der folgenden Schritte hilft:

  • μSD-Card aus der GoPro entnehmen und in den Kartenleser am Rechner stecken
  • make import kopiert jetzt alle Fotos von der Speicherkarte in ein Directory auf dem Rechner, dieses hat das aktuelle Datum als Namen, z. B. 2021-05-07
  • GPX von Strava herunterladen und ebenfalls mit Datum als Namen speichern, z. B. 2021-05-07.gpx
  • make process_and_upload versieht jetzt alle Bilder des aktuellen Tages-Directories mit den Geodaten (Länge, Breite, Blickrichtung) aus dem GPX-Track und lädt diese anschließend zu Mapillary hoch (die erzeugten Bilder und Log-Files liegen in einem versteckten Sub-Directory, in diesem Beispiel 2021-05-07/.mapillary)

Ausschnitt aus dem Makefile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
VOLUME=/Volumes/GOPRO
DATE=$(shell date "+%Y-%m-%d")
TARGET=$(DATE)
GPX=$(DATE).gpx
OFFSET_TIME=0
MAPILLARY_USER=<username>

.PHONY: import
import:
	mkdir -p "$(TARGET)"
	find "$(VOLUME)/DCIM" -iname '*.JPG' -print0 | xargs -0 -I % cp -v % "$(TARGET)/"

.PHONY: process_and_upload
process_and_upload:
	[[ -f "$(GPX)" ]] || { echo "GPX not found: $(GPX)" ; exit 1 ; }
	./mapillary_tools \
		process_and_upload \
		--advanced \
		--verbose \
		--import_path "$(TARGET)" \
		--geotag_source gpx \
		--geotag_source_path "$(GPX)" \
		--user_name "$(MAPILLARY_USER)" \
		--summarize \
		--keep_original \
		--local_time \
		--offset_time $(OFFSET_TIME) \
		--overwrite_EXIF_gps_tag \
		--overwrite_EXIF_direction_tag \
		--overwrite_EXIF_orientation_tag

Die Variable OFFSET_TIME lässt sich direkt auf der Command Line überschreiben – das kann hilfreich sein, wenn die GoPro-Uhrzeit und die GPX-Uhrzeit eine Abweichung voneinander haben Der Wert ist in Sekunden anzugeben. Normalerweise ist das nicht notwendig. Was hilfreich ist: Das GPX-Gerät (in meinem Fall ein Garmin Edge) so einstellen, dass es einen Punkt pro Sekunde schreibt und nicht versucht „smart“ zu sein. Dann passen die Positionen der Bilder am Ende sehr gut.

Ausblick

Das Herunterladen des GPX-Files von Strava möchte ich noch über die Strava-API automatisieren. Dann würde sich der Ablauf noch einmal deutlich vereinfachen: Karte in Kartenleser stecken und einmal make ausführen.