Arbeitsplan Masterarbeit (Stand August)

21.05.2025 · von Claude Widmer · 12 Min Lesezeit

Arbeitsplan Masterarbeit (Stand August)

Arbeitsplan Masterarbeit

In diesem Blogbeitrag stelle ich meinen geplanten Arbeitsablauf für die Masterarbeit vor.

Im Folgenden findest du einen visuellen Arbeitsplan mit den wichtigsten Schritten:

1. Erarbeitung eines Modells (Vektor)
Input:
  • Bounding Box von Zürich
  • Netzwerk von Zürich
  • OSM Zugriff
Output:
  • Vollstaendig bereinigtes und harmonisiertes Fusswegnetz von Zürich
  • Knoten- und Kantenstruktur (Graph-Modell) mit konsistenten IDs
  • Dokumentierte Attribute pro Segment (Laenge, Zugang, Quelle, Klassifikation)
Herausforderungen:
  • Unterschiedliche Datenqualitaet und Abdeckung zwischen OSM und OGD-Zürich
  • Topologische Konsistenz: Lücken, Ueberschneidungen und Duplikate sauber bereinigen
  • Automatisierte Abgrenzung von irrelevanten Segmenten (z. B. kurze Artefakte, private Wege)
  • Skalierbarkeit bei grossen Datenmengen und effiziente Geoprocessing-Workflows
1.1 OSM-Netzwerkaufbereitung
Blog Einführung 3 - Bild 2.3
Input:
  • Bounding Box von Zürich (LV95)
  • Geofabrik/OSM Fussweg-Daten (Ways & Nodes)
  • EPSG:2056 Ziel-Koordinatensystem
Algorithmus:
  • Download des aktuellen OSM-Extrakts und Filtern auf fussrelevante highway-Typen (footway, path, steps, living_street, service mit Fusszugang)
  • Transformation in EPSG:2056 und Zuschnitt auf die Bounding Box
  • Aufteilen multiliner Geometrien; Normalisierung von Richtungen
Output:
  • Bereinigtes, auf Zürich zugeschnittenes Liniennetz (GPKG)
  • Konsistente Attribute: highway, surface, foot, name
1.2 Integration Stadt Zürich & OSM
Blog Einführung 3 - Bild 2.3
Input:
  • OGD-Stadt Zürich Fussweg-/Trottoir-Layer
  • OSM-Liniennetz aus 1.1
  • Snap-Toleranz (z. B. 0.5–1.0 m)
Algorithmus:
  • Beide Datensätze nach EPSG:2056 transformieren
  • Vereinheitlichung der Attribute (Feldmapping) und Verschneiden/Union der Layer
  • Schliessen kleiner Lücken & Höhlen (< 10 m²) und Liniensnap an Knoten im Toleranzradius
  • Aufloesen von Duplikaten, dissolve nach relevanten Attributen
Output:
  • Zusammengeführtes, topologisch sauberes Fusswegnetz
  • Dokumentierte Feldliste (Datenkatalog) und Herkunftskennzeichen pro Segment
1.3 Graph-Erstellung & Qualitätsprüfung
Blog Einführung 3 - Bild 2.3
Input:
  • Bereinigtes Liniennetz aus 1.2
  • Schwellwerte für Längen-/Qualitaetsfilter
Algorithmus:
  • Erzeugung eines ungerichteten Graphen (Knoten=Endpunkte, Kanten=Liniensegmente)
  • Berechnung von Kantenlaenge
  • Entfernung sehr kurzer Artefaktkanten (Projekt-spezifischer Schwellwert von 20m)
  • Prüfung zusammenhaengender Komponenten; Sicherstellen globaler Erreichbarkeit
  • Export der Graph-Struktur (Knoten/Kanten) inkl. eindeutiger IDs
Output:
  • Routbares Fusswegnetz mit Attributen (Länge)
  • Knoten-/Kantentabellen (GPKG) als Basis für 2.x Erkennung & 3.x Analysen
Output:
  • Vollstaendig bereinigtes und harmonisiertes Fusswegnetz von Zürich
  • Knoten- und Kantenstruktur (Graph-Modell) mit konsistenten IDs
  • Dokumentierte Attribute pro Segment (Laenge, Zugang, Quelle, Klassifikation)
Herausforderungen:
  • Unterschiedliche Datenqualitaet und Abdeckung zwischen OSM und OGD-Zürich
  • Topologische Konsistenz: Lücken, Ueberschneidungen und Duplikate sauber bereinigen
  • Automatisierte Abgrenzung von irrelevanten Segmenten (z. B. kurze Artefakte, private Wege)
  • Skalierbarkeit bei grossen Datenmengen und effiziente Geoprocessing-Workflows
2. Feature-Erkennung & Geolokalisierung
Input:
  • Bounding Box von Zürich
  • Mapillary API Token(s)
  • Stammverzeichnis (z. B. ROOT_PATH = ./)
Output:
  • Vollständig bereinigtes und harmonisiertes Fusswegnetz von Zürich
  • Knoten- und Kantenstruktur (Graph-Modell) mit konsistenten IDs
  • Dokumentierte Attribute pro Segment (Länge, Zugang, Quelle, Klassifikation)
Herausforderungen:
  • Unterschiedliche Datenqualität und Abdeckung zwischen OSM und OGD-Zürich
  • Topologische Konsistenz: Lücken, Überschneidungen und Duplikate sauber bereinigen
  • Automatisierte Abgrenzung von irrelevanten Segmenten (z. B. kurze Artefakte, private Wege)
  • Skalierbarkeit bei grossen Datenmengen und effiziente Geoprocessing-Workflows
2.0 Mapillary Data Retrieval
Blog Einführung 3 - Bild 2.0
Input:
  • Bounding Box von Zürich
  • GPKG_PATH = ./data/images_bbox_fullmeta.gpkg
  • Spalte thumb_1024_url mit 1024p-URLs
  • LAPLACIAN_THRESHOLD: Threshold für die Bildunschärfen-Erkennung (100)
Algorithmus:
  • Laden von Geodaten: Das Notebook lädt Geodaten und Metadaten über die Mapillary API herunter (über 1,2 Millionen Bilder) und bereitet sie für die Analyse vor.
  • Erkennung von unscharfen Bildern: Es überprüft die Bildqualität, um unscharfe Bilder zu identifizieren via Laplacian Methode (mit einem Threshold).
  • Zuordnung der Ergebnisse: Die Ergebnisse der Unschärfeprüfung werden den Bildern zugeordnet.
  • Speichern der Daten: Die aktualisierten Geodaten werden in einer neuen GeoPackage-Datei gespeichert.
Output:
  • Geopackage mit allen Metadaten von den 1.2 Millionen Bildern und die Information, ob das Bild unscharf ist.
2.1 YOLO Image Recognition Training
Blog Einführung 3 - Bild 2.1
Input:
  • Mapillary Segmentation and Object Detection Dataset
  • YOLO-kompatible Labeldateien (YOLOv8 Format)
Algorithmus:
  • Laden von Trainings- und Validierungsdaten aus YOLO-kompatiblen Pfaden
  • Verwendung eines YOLOv8-Medium-Modells (yolo11m-seg.pt) mit vortrainierten Gewichten
  • Durchführung eines Segmentierungs- und Objekterkennungs-Trainings mit Mixed Precision (AMP)
  • Anwendung von Transfer Learning und Feinjustierung über 100+ Epochen mit Early Stopping
  • Optimizer automatisch gewählt (AdamW) mit automatischer Lernratenanpassung
  • Evaluation nach jeder Epoche mit mAP, Precision und Recall
  • Training und Vergleich unterschiedlicher Modellgrössen (n, s, m, l)
  • Über 12 Stunden Trainingszeit für das Medium-Modell, insgesamt über 48 Stunden zur Modellevaluierung (RTX 4080, 64 GB RAM)
Output:
  • Trainiertes YOLO-Modell (best.pt)
  • Evaluationsmetriken (Precision, Recall, mAP50, mAP50-95)
  • Trainingsplots und Ergebnisvisualisierungen
Herausforderungen:
  • Aufgrund des sehr grossen Datensatzes (über 18'000 Bilder) konnte nicht der gesamte Umfang für das Training genutzt werden.
  • Die verfügbare Rechenleistung (GPU/VRAM) war limitiert, was zu kleineren Batchgrössen und kürzeren Trainingszeiten führte.
  • Dadurch litt insbesondere der Recall (Erkennungsrate), da das Modell viele Objekte nicht zuverlässig detektierte.
  • Zusätzlich erschwerten die grosse Klassenvielfalt und unbalancierte Verteilung die Generalisierung.
2.2 Depth Estimation Processing
Blog Einführung 3 - Bild 2.2
Input:
  • Die 1.2 Millionen Bilder vom Schritt 2.0
  • Pfadliste aller validen Bilder (vorvalidiert via PIL)
Algorithmus:
  • Scannen aller .jpg-Dateien im Datensatzordner
  • Parallelvalidierung mittels PIL, um defekte Bilder zu filtern
  • Reduktion der Bildauflösung (50 %) zur Performance-Optimierung
  • Batchweise Tiefenschätzung mittels depth-anything Pipeline (HuggingFace)
  • Optionales Invertieren der Tiefenwerte für GIS-Konsistenz
  • Export der Tiefendaten als .npz (komprimiert, float16)
  • Optional: Export von Tiefenbildern und Histogrammen zur visuellen Kontrolle
  • Speicherbereinigung und GPU-Freigabe nach jeder Batch für stabile Laufzeit
Output:
  • Tiefenkarten im .npz-Format (komprimiert, float16)
  • Optional: Visualisierungen der Tiefenbilder (.png)
  • Optional: Histogramme der Tiefenverteilung pro Bild
  • Gespeichert im Unterordner depth_processed/
Herausforderungen:
  • Volle Auflösung führte zu Out-of-Memory-Fehlern → Downscaling nötig
  • Einige Bilder konnten trotz vorheriger Validierung nicht verarbeitet werden (Pipeline-Fehler)
  • Speicherfreigabe und Garbage Collection war nötig, um GPU-Nutzung stabil zu halten
  • Laufzeit von über 12 Stunden für alle Bilder (RTX 4080, 64 GB RAM, 128er Batch-Grösse)
  • Hohe Modellqualität, aber keine Echtzeitverarbeitung möglich
2.3 YOLO Object Detection Processing
Blog Einführung 3 - Bild 2.3
Input:
  • Gefilterte Bildliste aus Schritt 2.2 (inkl. validem Tiefendatenpfad)
  • Vortrainiertes YOLO-Modell (.pt)
  • Konfigurationsdatei mit Schwellenwerten, Pfaden und Parametern
Algorithmus:
  • Filterung aller Bilder ohne Tiefenkarte oder bei Unschaerfe
  • Batchweises Kopieren der Bilder in temporären Inferenzordner
  • Ausführung der YOLO-Inferenz (ultralytics.YOLO) in Batches
  • Speichern der Ergebnisse als .npz pro Bild (BBox, Klassen, Konfidenzen, Maske)
  • Zusammenführung von Tiefen- und YOLO-Daten pro Objekt (inkl. Tiefenwertbestimmung)
  • Kategorisierung der Objekte anhand der Tiefe (z.B. "near", "medium", "far")
  • Optional: Visualisierung der Objekte mit Tiefenklassen
  • Speichern aller Objekte in .parquet-Datei (schnell + komprimiert)
  • Geometrie-Zuordnung via GeoPackage & Polars für performantes Join
Output:
  • YOLO-Ergebnisse als komprimierte .npz-Dateien
  • Vereinte Objektliste mit Tiefe, Klasse, Konfidenz und Koordinaten (.parquet)
  • Optional: Visualisierte Objekte mit Bounding Boxes und Tiefenklassen (.jpg)
  • Finale Objekt-Geodaten mit X/Y-Koordinaten aus GPKG
Herausforderungen:
  • Inferenzzeit über 30 Stunden bei 1.2 Mio Bildern → kein Echtzeitbetrieb
  • Fehlerhafte oder fehlende .npz-Dateien mussten manuell gefiltert werden
  • Initial hohe RAM/GPU-Auslastung – Speicherbereinigung und batchweises Laden notwendig
  • Konvertierung von GPKG zu Parquet nötig für effizientes Polars-Join
  • Batch-Grösse musste angepasst werden, um stabile Performance auf RTX 4080 zu erreichen
2.4 Object Geolocation
Objekt-Geolokalisierung: von Bild-Detektion zu LV95-Koordinaten
Input:
  • YOLO-Detektionen als .parquet (BBox, Klasse, Konfidenz, z_class)
  • Mapillary GPKG mit Kameraposition und Metadaten (z. B. id, is_pano, computed_compass_angle, computed_geometry)
  • Parameter: Bildbreite (image_width) und Sichtfeld (fov)
Algorithmus (ohne OSM):
  • Join YOLO ↔ Mapillary:

    • Match über image_id (YOLO) und id (Mapillary); Filtere irrelevante Labels und sehr ferne z-Klassen.
    • Erzeuge Geometrie aus computed_geometry (WGS84) und projiziere nach LV95 (EPSG:2056).
  • Winkel- und Distanz-Adjustierung pro Objekt:

    • Bestimme BBox-Zentrum (cx) und berechne Blickrichtungs-Offset: ((cx / image_width) − 0.5) * fov.
    • Finaler Azimut = computed_compass_angle + Offset.
    • Verschiebe den Kamera-Punkt entlang dieses Winkels um eine z-klassenabhängige Distanz (z. B. very near: 5 m, near: 7.5 m, medium: 20 m).
  • Parallelisierung in Chunks, Schreiben als .parquet (LV95-Punkte mit x_adj/y_adj).
Output:
  • joined_dataset.parquet – verknüpfte Rohdaten (Kamerapositionen)
  • adjusted_dataset.parquet – geolokalisierte Objektpunkte (LV95) mit Adjustierung
Herausforderungen:
  • Approximative Distanzen aus z-Klassen → Positionsfehler abhängig von FOV und BBox-Lage
  • Unterschiedliche Bildtypen (Panorama vs. Nicht-Panorama)
  • Performance bei sehr grossen Datensätzen → Multiprocessing, Parquet einsetzen
2.5 YOLO Objekterkennung auf SWISSIMAGE Orthofotos
Blog Einführung 3 - Bild 2.5
Input:
  • SWISSIMAGE Orthofotos von Zürich (170 km² ≈ 120'000 px × 140'000 px)
  • 8'000 manuell digitalisierte Trainingsfeatures für das YOLO-Modell
  • OSM-Daten für Tramlinien und Tramnetz im Kanton Zürich
Algorithmus:
  • Entwicklung von vier YOLO-Modellen:

    • Modell 1: YOLOv11L – 100 Epochs – Klassen: 30er-Zone, Auto, Fussgängerstreifen, Pfeilmarkierung, Schule, Tram, Vortritt und Zug
    • Modell 2: YOLOv11X – 70 Epochs – Fokus Tram im Kanton Zürich
    • Modell 3: YOLOv11X – 100 Epochs – Fokus Strassenmarkierungen in Luzern
    • Modell 4: YOLOv11L – 100 Epochs – Fokus Tram in der Stadt Bern (mit OSM-Daten)
Output:
  • YOLO-Ergebnisse als .gpkg-Dateien
Herausforderungen:
  • YOLO-Training dauerte über 6 Stunden
  • Interferenzzeit aller vier Modelle inkl. Zusammenführung: mehr als 11.5 Stunden
  • Hohe RAM/GPU-Auslastung – viel Ausprobieren nötig für optimale Batchgrösse, Bildgrösse und Modellwahl
  • Allgemeine Big-Data-Probleme (alles wurde lokal auf dem PC berechnet)
Output:
  • Geopackage-Datei mit Metadaten zu über 1.2 Millionen Bildern (inkl. Unschärfe-Information)
  • Trainiertes YOLO-Modell zur Objekterkennung (best.pt)
  • Tiefenkarten zu validen Bildern im .npz-Format (komprimiert, float16)
  • Gefilterte Liste valider Bilder mit vorhandener Tiefenkarte und guter Bildqualität
  • YOLO-Erkennungsergebnisse pro Bild als .npz-Dateien (BBox, Klassen, Konfidenzen)
  • Kombinierte Objektdaten mit Tiefe und Kategorisierung ("near", "medium", "far") als .parquet
  • Finale Objektliste mit zugeordneten Koordinaten (via Geometrie-Join) für Mapping-Tools
  • Optional: Visualisierte Objekte mit Tiefenklassifikation (.jpg) für Qualitätsprüfung
Probleme & Aufwand:
  • Extrem hoher Rechenaufwand: Die gesamte Verarbeitung von Bild-Download, Tiefenschätzung und YOLO-Inferenz dauerte mehrere Tage, trotz RTX 4080 und 64 GB RAM.
  • Der Schritt 2.2 (Tiefenschätzung) benötigte über 12 Stunden allein für die validen Bilder.
  • Die Inferenz mit YOLO in Schritt 2.3 dauerte über 30 Stunden, was Echtzeitverarbeitung ausschliesst.
  • Hohes Risiko von Out-of-Memory-Fehlern, insbesondere bei voller Auflösung → Reduktion der Bildgrösse war zwingend.
  • Manuelle Filterung notwendig bei fehlerhaften oder leeren .npz-Ergebnissen
  • Speicherfreigabe und Garbage Collection mussten explizit eingebaut werden, um GPU-Laufzeit zu stabilisieren.
  • Join von Geometrien auf über 1 Million Objekte erforderte Konvertierung von GPKG zu Parquet und Einsatz von Polars für Performance.

Fazit: Die Datenverarbeitung in Phase 2 war technisch erfolgreich, aber extrem zeit- und ressourcenintensiv. Ich bin sehr froh, hat es geklappt.

3. Klassifikation der Schulwegsicherheit

Ziel dieses Schritts ist es, aus den vorbereiteten Daten (YOLO-Detektionen auf Orthofotos und Street-Level-Fotos, Ground-Truth aus Zürich sowie Netzwerkdaten) Sicherheitsbewertungen für einzelne Strassen- und Wegsegmente zu berechnen. Diese Bewertungen werden auf zwei Arten erstellt:

  • Machine Learning – das Modell lernt aus den echten Bewertungen der Stadtpolizei Zürich.
  • Regelbasiert – ein einfaches Punktesystem mit Abzügen und Boni.

Am Ende lassen sich mit diesen Bewertungen sichere Routen berechnen. Dafür wird eine Kostenfunktion genutzt, die Länge und Sicherheit kombiniert. Zusätzlich wurde ein einfaches API erstellt, das auf Basis von Start- und Zielpunkten die Route mit den genutzten Kanten zurückgibt.

3.1 Datenabgleich SWISSIMAGE (YOLO-Polygone)
SWISSIMAGE: von YOLO-Polygonen zu Anteilen je Strassen-Segment
Input:
  • Strassennetz (Kanten/Segmente)
  • YOLO-Detektionen auf SWISSIMAGE-Orthofotos als Polygone (z. B. 30er-Zonen, Velowege, Tramgleise, Markierungen)
  • Parameter: Buffer je Klasse
Algorithmus:
  • Polygone bereinigen und je Klasse pufferen
  • Overlay mit Kanten → Coverage je Klasse (Längenanteil)
  • Pivot zu Feature-Spalten; fehlende Werte = 0
Output:
  • edges_poly.parquet – Kanten mit Klassenanteilen (0–1) und länge_m
Bildvorschlag:
  • Orthofoto-Hintergrund, farbige YOLO-Polygone (z. B. 30er-Zone grün, Tramgleis violett)
  • Strassensegmente mit Popups „Anteil 30er-Zone = 0.6“
  • Kleine Legende der Klassenfarben
3.2 Datenabgleich Street-Level (YOLO-Punkte)
Street-Level: YOLO-Punkte zu Heatmaps und Zonal-Statistik je Segment
Input:
  • YOLO-Detektionen auf Street-Level-Fotos als Punkte (Autos, Busse, Velos, Fussgänger ...)
  • Raster-Parameter: Pixelgrösse, Radius, min_conf
Algorithmus:
  • Qualitätsfilter (Nachbarn/Effort)
  • Heatmaps je Objektgruppe (Perzentil + Glättung)
  • Zonal-Statistik entlang Kanten → rast_* je Gruppe
Output:
  • GeoTIFF-Heatmaps
  • edges_raster.parquet – Kanten mit rast_*
Bildvorschlag:
  • Heatmap „Autos“ als halbtransparente Fläche
  • Strassensegmente mit Tooltip „rast_car = 0.82“
  • Beispiel-Street-Level-Foto (klein) als Einblendung
3.3 Klassifikation mit ML (inkl. Monte Carlo)
ML-Klassifikation: Features → Safety-Score mit Monte-Carlo-Unsicherheit
Input:
  • Features aus 3.1 und 3.2 (Klassenanteile, rast_*, Länge)
  • Ground-Truth der Stadtpolizei Zürich (Übergänge mit Schwierigkeit)
Algorithmus:
  • Preprocessing (Imputation, One-Hot wo nötig, ggf. Klassengewichte)
  • Modelle: z. B. RandomForest / HistGradientBoosting, 5-Fold CV
  • Vorhersage: prob_unsafesafety_score = 1 - Risiko
  • Monte Carlo: Modell mehrfach mit kleinen Zufallsvariationen laufen lassen → p05/p95 als Unsicherheitsintervall
Output:
  • edges_with_safety_ml.parquetsafety_score, prob_unsafe, mc_p05, mc_p95
Bildvorschlag:
  • Kartenansicht mit Segmentfärbung nach safety_score
  • Kleines Histogramm/Violinplot der Monte-Carlo-Verteilung für ein Beispielsegment
  • Legende: sicher ↔ unsicher
3.4 Klassifikation regelbasiert (Punktabzug)
Regelbasiertes Scoring: Abzüge/Bonis aus YOLO-Polygonen und Heatmaps
Input:
  • Features aus 3.1 und 3.2
  • Einfache Gewichte und Schwellwerte (Regelset)
  • Übergangs-Flag/Kreuzungslogik (markiert, Ampel, Insel)
Algorithmus:
  • Startscore = 1.0
  • Abzüge: z. B. rast_car hoch −0.25, Tram/Bus −0.10, kein markierter Übergang −0.30
  • Bonis: 30er-Zone +0.10, Veloweg +0.08, Zebrastreifen +0.15, Ampel +0.25
  • Clipping/Normalisierung → safety_score_rule ∈ [0,1]
Output:
  • edges_with_safety_rule.parquetsafety_score_rule + Kategorie
Bildvorschlag:
  • Zwei nebeneinander: Karte „ML“ vs. „Regeln“ für dasselbe Gebiet
  • Ein Segment mit Overlay der Faktoren (Badges: 30er-Zone +0.10, kein Zebrastreifen −0.30 …)
  • Minilegende der Punkteabzüge/Bonis
3.5 Routing mit Kostenfunktion & API
Routing: Kosten = Alpha*Länge + Beta*(1-Safety); API mit Start- und Zielpunkt
Input:
  • Kanten + safety_score (ML) und/oder safety_score_rule
  • Start- und Zielpunkt (API-Request)
  • Parameter: alpha (α) für Länge, beta (β) für Risiko
Algorithmus:
  • Kosten je Kante: cost = α · länge_m + β · (1 - safety)
  • k-alternative Pfade (z. B. Yen) berechnen
  • Praxiswerte: α = 1.0, β = 2.0 (Sicherheit doppelt so wichtig wie 100 m)
API:
  • Einfaches Endpoint: Input = 2 Punkte (Start, Ziel)
  • Output = Route als Liste von Kanten mit länge_m, safety, cost
  • Optional: Varianten „kürzester“ vs. „sicherster“ Weg
Output:
  • GPKG/GeoJSON: routes_*, segments_*
  • Tabelle pro Route: Länge, mittlere Safety, Anzahl Kreuzungen
Bildvorschlag:
  • Karte mit zwei hervorgehobenen Routen (blau = kürzester, grün = sicherster)
  • Popup je Segment mit länge, safety, cost
  • Kleiner Kasten „API-Beispiel“ mit obigem JSON-Snippet
4. Visualisierung
Input:
  • ...
Output:
  • ...
  • ...
  • ...
Herausforderungen:
  • ...
  • ...
4.1 QGIS Web Client
Input:
  • wird ergänzt
Algorithmus:
  • wird ergänzt
Output:
  • wird ergänzt
4.3 Website
Input:
  • wird ergänzt
Algorithmus:
  • wird ergänzt
Output:
  • wird ergänzt
Output:
  • ...