2d to 2 5d

Jak wyciągnąć rzeźbę terenu Księżyca z jednego zdjęcia — eksperymentalny pipeline 2.5D

Krótki opis: Opisuję projekt badawczy, który próbuje estymować względną mapę wysokości powierzchni Księżyca z pojedynczego zdjęcia orbitalnego. Bez stereoskopii, bez uczenia maszynowego — tylko klasyczna analiza cieni, gradientów jasności i danych georeferencynych.


Problem: 3D z 2D

Każde zdjęcie powierzchni Księżyca to rzut 3D na 2D. Informacja o wysokości terenu zostaje „spłaszczona”. Żeby ją odtworzyć, mamy do dyspozycji kilka poszlak:

  • Cienie — im dłuższy cień, tym wyższy obiekt (przy znanych parametrach oświetlenia)
  • Gradienty jasności — nagłe zmiany jasności wskazują na zbocza
  • Albedo — materiał powierzchni też zmienia jasność, co komplikuje oba powyższe

Problem polega na tym, że albedo i topografia są ze sobą splątane. Jasna plama na zdjęciu może być równiną z jasnego regolitu albo stokiem nachylonym w stronę Słońca. Nie da się ich rozdzielić w 100% z jednego ujęcia — to fundamentalne ograniczenie fizyczne. Projekt jawnie to przyznaje i buduje wokół tego ograniczenia cały system zaufania do wyników.


file screenshot

Architektura pipeline’u

Kod jest podzielony na 7 etapów, każdy produkujący własny obraz diagnostyczny:

Etap 1 — Detekcja cieni

Maska cienia generowana jest metodą percentylową (domyślnie: najciemniejsze 15% pikseli) lub odchylenia standardowego. To metoda heurystyczna — ciemny materiał może zostać mylnie zakwalifikowany jako cień.

01_shadow_mask.png

Etap 2 — Wysokości z cieni

Z maski cienia mierzy się długości cieni i przelicza na względne wysokości:

height = shadow_length_px × pixel_scale_m × tan(sun_elevation°)

Przyjęte założenie: obiekty rzucające cień są pionowe. To przybliżenie, ale wystarczające dla skał i krawędzi kraterów.

02_shadow_length_map.png
03_shadow_height_map.png

Etap 3 — Mapa albedo

Algorytm interpoluje „oczekiwaną” jasność tła z tzw. inspect boxów — małych okien próbkujących jasność materiału w znanych punktach geograficznych. W wersji 2.6 pozycje tych okien są wyznaczane z prawdziwych współrzędnych księżycowych (lat/lon) z danych QuickMap, nie losowo.

04_albedo_reference_map.png

Etap 4 — Normalizacja jasności

Jasność obserwowana dzielona jest przez oczekiwaną jasność albedo, żeby wyizolować wpływ topografii:

normalized = observed / expected_albedo
05_normalized_brightness.png

Etap 5 — Gradienty

Na znormalizowanej jasności liczone są przestrzenne gradienty (magnitude i kierunek). Silny gradient wskazuje na zbocze; kierunek gradientu informuje o orientacji stoku.

06_gradient_magnitude.png
07_gradient_direction.png  ← wizualizacja HSV: barwa = kierunek

Etap 6 — Mapa zaufania (confidence map)

To jest serce projektu. Mapa zaufania łączy 5 niezależnych składowych:

SkładowaCo mierzy
Shadow distanceBliskość do krawędzi cienia
GradientSiła gradientu jasności
Texture varianceLokalna variancja (tekstura)
Albedo stabilityBliskość do inspect boxów
Failure penaltyKara za obszary z góry nienadające się do analizy

Ostateczna mapa zaufania = ważona suma składowych × kara za regiony nieudane.

08_confidence_map.png  ← zielony = wysoka pewność, czerwony = niska

Etap 7 — Końcowa mapa wysokości

Wysokości z cieni i ze stoków gradientowych są łączone. W obszarach niskiego zaufania wyniki są wygładzane w kierunku mediany — żeby nie prezentować szumu jako terenu.

09_height_map.png
10_height_map_confidence_overlay.png  ← wysokości + zaufanie jako krycie

Dane wejściowe: QuickMap

Projekt używa danych z QuickMap (LROC, Arizona State University):

  • Obraz LROC NAC — zdjęcie orbitalne w wysokiej rozdzielczości (~1 m/piksel przy pełnej rozdzielczości)
  • Region Data CSV — punkty pomiarowe z QuickMap zawierające: współrzędne geograficzne (lat/lon), wysokość terenu (TerrainHeight), nachylenie (Slope), skład optyczny i inne

Plik .vrt (GDAL Virtual Dataset) dostarcza metadane georeferencyje: układ współrzędnych, transformację geograficzną, skalę pikselową.


Iteracje projektu

Kod przeszedł trzy iteracje, każda dodając nową warstwę:

Iteracja 2 — podstawowy pipeline (cienie + gradienty + mapa zaufania)

Iteracja 2.5 — warstwa diagnostyczna: rozkład mapy zaufania na 5 składowych, histogram gradientów, nakładka outlierów, interakcja cień–gradient. Cel: „Czy ufam pipeline’owi z właściwych powodów?”

Iteracja 2.6 — prawdziwe współrzędne: inspect boxy wyznaczane z danych QuickMap, a nie losowo. Mapowanie lat/lon → piksel z liniowym przybliżeniem (bez korekcji projekcji kartograficznej).

Iteracja 3 (validate_iteration3.py) — walidacja trendów: porównanie kierunków gradientów z zewnętrznym DEM (LOLA/LROC). Nie optymalizuje — tylko odpowiada na pytanie: „Czy rekonstruowane trendy zbieżne są z prawdziwą topografią?”


Czego projekt nie robi

To jest lista równie ważna jak lista funkcji:

  • Nie generuje DEM — wysokości są względne, bez bezwzględnej referencji
  • Nie stosuje uczenia maszynowego — każdy krok jest interpretowalny przez człowieka
  • Nie jest fotogrametrią — brak par stereo, brak triangulacji
  • Nie działa dobrze na równinach — jednolite obszary nie dają sygnału topograficznego
  • Nie rozdziela w pełni albedo od topografii — to niemożliwe z jednego zdjęcia

Wyniki i walidacja

Przy teście na przykładowym regionie księżycowym (7.63°N, 6.53°E), w pełnej rozdzielczości LROC NAC (1 m/px), używając syntetycznego DEM (brak dostępu do LOLA w czasie testów), walidacja Iteracji 3 klasyfikuje:

  • ok. 3.6% obszarów z wysoką pewnością jako zgodne z trendem DEM
  • ok. 17.7% jako niezgodne
  • reszta: zbyt niska pewność, żeby wyciągać wnioski

Wyniki są uczciwie raportowane — projekt nie próbuje tych liczb tłumaczyć ani „naprawiać”. Niezgodność jest informacją, nie błędem do ukrycia.


Potencjał i zastosowania

Warto tu wspomnieć o szerszym kontekście danych, z których korzysta projekt.

Zdjęcia powierzchni Księżyca wykonane przez LROC NAC to najbardziej szczegółowe mapowanie powierzchni ciała niebieskiego poza Ziemią. Przy rozdzielczości ~1 m/piksel każdy piksel odpowiada powierzchni jednego metra kwadratowego — to poziom szczegółowości nieosiągalny dla żadnej innej planety czy księżyca w Układzie Słonecznym. Brak atmosfery na Księżycu eliminuje rozmycie i zniekształcenia optyczne, co dodatkowo podnosi jakość zdjęć.

QuickMap oferuje też widok 3D rekonstruowany z danych LOLA (LRO Laser Altimeter). Daje on rozszerzone pojęcie o ukształtowaniu terenu, ale podobnie jak ten pipeline, przedstawia topografię w ograniczonym zakresie — nie jest to pełna, precyzyjna fotogrametria.

Co jeszcze można by z tego wyciągnąć

Główna ograniczająca przesłanka tego projektu to jedno zdjęcie z jednego kąta. Gdyby dostępne były dwa lub więcej zdjęć tego samego obszaru w zbliżonej rozdzielczości i różnych kątach oświetlenia, możliwości analizy rosną istotnie:

Ocena ścieżek poruszania się — identyfikacja terenów z minimalnym nachyleniem i małą liczbą głazów przydatna przy planowaniu tras łazika.

Ocena grubości regolitu — cienie głazów i ich relacja do otoczenia mogą wskazywać na głębokość luźnej warstwy powierzchniowej.

Analiza formacji skalnych — rozmieszczenie i morfologia głazów pod różnymi kątami oświetlenia pozwala na wstępną klasyfikację litologiczną.

To wszystko na razie obszar badawczy, nie gotowe narzędzie. Ale punkt wyjścia jest tu wyjątkowo dobry: dane są publiczne, darmowe i najwyższej możliwej jakości.


Kod i licencja

Kod Python (~1600 linii, bez zewnętrznych frameworków AI) używa wyłącznie: numpy, opencv-python, scipy, matplotlib

Kod źródłowy narzędzia jest dostępny publicznie na GitHubie: github.com/MarcinSFox/Lunar_2.5D

Wszystkie kroki są jawne i udokumentowane. Każdy etap generuje własny obraz diagnostyczny, co pozwala zrozumieć, gdzie pipeline działa dobrze, a gdzie się myli.

Dane testowe: przykładowy region księżycowy (~7.63°N, 6.53°E), obraz LROC NAC z QuickMap, skala ~1 m/px.


Projekt traktuję jako eksperyment badawczy i narzędzie do nauki. Wyniki to hipotezy o kształcie terenu, nie pomiary. Wartość projektu leży w przejrzystości metody i jawnym modelowaniu niepewności — nie w dokładności wyników.

Podobne wpisy