Jedno zdjęcie. Niewielka, tropikalna wyspa z kurortem, otoczona błękitną wodą i dwoma innymi skrawkami lądu. Zadanie wydaje się proste: zidentyfikować to miejsce. Pierwszym odruchem byłoby wrzucenie obrazu do Google Lens i oczekiwanie na odpowiedź w kilka sekund. Co jednak, jeśli zrezygnujemy z tej drogi na skróty? Co, jeśli potraktujemy to zdjęcie nie jako obraz do rozpoznania, ale jako geometryczną zagadkę do rozwiązania siłą obliczeniową?
Prześledziliśmy właśnie taką ścieżkę. Zamiast polegać na algorytmach rozpoznawania obrazu, sięgnęliśmy po matematykę, publiczne dane geograficzne i moc obliczeniową procesorów graficznych (GPU). To historia o tym, jak przeszukać całą planetę w mniej niż sekundę, by znaleźć jeden trójkąt złożony z wysp.
Co badamy
Przedmiotem naszej analizy jest wyzwanie OSINT (Open Source Intelligence — biały wywiad, czyli analiza informacji z publicznie dostępnych źródeł) znane jako gralhix 004 1. Jego celem jest geolokalizacja miejsca ze zdjęcia, a konkretnie podanie nazwy kurortu, współrzędnych geograficznych wyspy oraz kierunku, w którym patrzyła kamera 1. Kluczowym założeniem, które przyjęliśmy, było świadome zignorowanie najprostszych narzędzi, takich jak Google Lens, aby zbadać alternatywną, znacznie bardziej techniczną metodę opartą na programowaniu i analizie geometrycznej 2.
Metoda
Cały proces można podzielić na kilka logicznych kroków, od analizy obrazu po zmasowany, zautomatyzowany research w globalnej bazie danych. Prześledźmy go krok po kroku.
Krok 1: Ekstrakcja „odcisku palca” z obrazu
Pierwszym krokiem była próba znalezienia jakichkolwiek metadanych w pliku ze zdjęciem. Analiza za pomocą narzędzia exiftool nie przyniosła jednak żadnych użytecznych informacji poza podstawowymi danymi o obrazie, takimi jak jego wymiary 3. To typowa sytuacja dla obrazów publikowanych w internecie, które często są pozbawiane danych EXIF.
Skoro metadane zawiodły, musieliśmy skupić się na samej treści zdjęcia. Zidentyfikowaliśmy na nim trzy kluczowe, oddzielne masy lądu: wyspę z kurortem (nazwijmy ją P0), wyspę po prawej stronie (P1) oraz wyspę z charakterystycznym szczytem po lewej (P2) 4. Te trzy punkty tworzą trójkąt, którego geometria może być unikalna w skali globu.
Problem polegał na tym, że zdjęcie zostało najprawdopodobniej wykonane z drona, a nieznana wysokość i kąt nachylenia kamery uniemożliwiały stworzenie precyzyjnego modelu perspektywy 5. Zamiast tego, autor analizy postanowił oprzeć się na względnych odległościach i kątach między wyspami 6.
Aby precyzyjnie zmierzyć te relacje, stworzono prosty interfejs graficzny, który pozwalał na kliknięcie w każdy z trzech punktów na zdjęciu i automatyczne obliczenie geometrii wynikowego trójkąta 7. W ten sposób powstał geometryczny „odcisk palca” miejsca. Aby uwzględnić niedokładności, założono margines błędu na poziomie ±20% dla mierzonych odległości i kątów 8.
Krok 2: Przygotowanie danych geograficznych
Mając „odcisk palca”, potrzebowaliśmy globalnej bazy danych, w której moglibyśmy go szukać. Wybór padł na publicznie dostępny zbiór danych z OpenStreetMap, a konkretnie land-polygons-split-4326 9. Jest to plik o rozmiarze 882 MB, zawierający wektorowe reprezentacje wszystkich linii brzegowych na Ziemi 9. Naszym celem było znalezienie w tym ogromnym zbiorze trójki wysp, której geometria pasuje do naszego odcisku palca.
Krok 3: Filtrowanie heurystyczne
Przeszukiwanie całego globu metodą brute force byłoby nieefektywne. Dlatego zastosowano serię filtrów heurystycznych, aby radykalnie zmniejszyć liczbę potencjalnych kandydatów.
- Filtr szerokości geograficznej: Wygląd wyspy sugerował, że znajduje się ona w strefie tropikalnej. Ograniczono więc obszar poszukiwań do szerokości geograficznych między -30° a 30° 10. Ten prosty krok zredukował liczbę poligonów (fragmentów lądu) do analizy do 141 131 11.
- Filtr gęstości lokalnej: Zdjęcie przedstawia stosunkowo odizolowaną grupę wysp. Odrzucono więc kandydatów znajdujących się w gęstych archipelagach. Filtr usuwał każdą wyspę, która w promieniu 5 km miała więcej niż 10 sąsiadów 12. Liczba kandydatów spadła do 51 576 12.
- Klastrowanie: Następnie wyszukano grupy (klastry) składające się z co najmniej trzech wysp, których środki (centroidy) znajdowały się w promieniu 20 km od siebie 13. Po tym kroku pozostało 23 500 potencjalnych klastrów 14.
Krok 4: Eksplozja kombinatoryczna i ratunek z GPU
Z każdego klastra wygenerowano wszystkie możliwe kombinacje trzech wysp, które mogłyby tworzyć poszukiwany przez nas trójkąt 15. To doprowadziło do kombinatorycznej eksplozji: 23 500 klastrów wygenerowało łącznie aż 80 690 777 trójek do sprawdzenia 16.
Przetworzenie takiej liczby kombinacji na standardowym procesorze (CPU) zajęłoby bardzo dużo czasu. Dlatego zadanie to zostało przeniesione na procesor graficzny (GPU), wykorzystując technologię CUDA 17. Każda z ponad 80 milionów trójek została przypisana do jednego wątku na karcie NVIDIA GeForce RTX 3050 17 18.
Każdy wątek wykonywał następujące operacje:
- Sortował trzy punkty według powierzchni, aby zidentyfikować najmniejszą wyspę jako P0 (tę z kurortem) 19.
- Obliczał kąt i stosunek odległości dla danej trójki 20.
- Porównywał obliczone wartości z geometrycznym „odciskiem palca” pobranym ze zdjęcia, uwzględniając okna tolerancji 21.
Cały proces na GPU zajął zaledwie 204,1 milisekundy 18. W jego wyniku z 80,7 miliona trójek wyłoniono 158 784, które wstępnie pasowały do wzorca 18. Po usunięciu duplikatów lista skurczyła się do 8 915 unikalnych kandydatów 22.
Krok 5: Weryfikacja kontekstowa
Ostatnim etapem było dalsze filtrowanie, tym razem oparte na dodatkowych cechach widocznych na zdjęciu.
- Test „otwartego prostokąta”: Na zdjęciu widać otwartą przestrzeń wody obok linii łączącej wyspy P0 i P1. Dla każdego z 8 915 kandydatów sprawdzono, czy w odpowiadającym mu obszarze na mapie nie znajdują się żadne inne lądy 23. Ten test zredukował liczbę kandydatów do 948 24.
- Test kształtu wyspy: Ostatni filtr weryfikował, czy kształt wyspy P0 przypomina koralową wysepkę (tzw. cay) 25. Do oceny kształtu użyto wskaźnika Polsby-Popper, który mierzy kompaktowość figury geometrycznej 26.
Po tych wszystkich krokach lista potencjalnych lokalizacji została zawężona do liczby, która umożliwiała już ręczną weryfikację.
Sygnatura / wzorzec
Kluczem do całego procesu było stworzenie unikalnej, geometrycznej sygnatury dla układu wysp widocznego na zdjęciu. Zamiast analizować piksele, kolory czy kształty budynków, skupiliśmy się na relacjach przestrzennych. Nasz wzorzec opierał się na trójkącie utworzonym przez trzy kluczowe masy lądu 4:
- Wyspa z kurortem (P0): Centralny punkt naszego śledztwa.
- Wyspa po prawej (P1).
- Wyspa z górskim szczytem po lewej (P2).
Sygnatura geometryczna składała się z dwóch głównych elementów, obliczonych na podstawie kliknięć w narzędziu GUI 7:
- Kąt przy wierzchołku P0: Kąt zawarty między liniami prowadzącymi od wyspy z kurortem do dwóch pozostałych wysp.
- Stosunek odległości: Proporcja długości ramion trójkąta, czyli
dystans(P0, P2) / dystans(P0, P1).
Aby uwzględnić niedokładności wynikające z rzutowania perspektywicznego zdjęcia z drona 5 oraz ręcznego zaznaczania punktów, do każdej z tych wartości dodaliśmy bufor tolerancji na poziomie ±20% 8. Taki „odcisk palca” – para liczb z marginesem błędu – stał się naszym kryterium wyszukiwania w globalnej bazie danych wybrzeży.
Co to znaczy
Analiza tego wyzwania to coś więcej niż tylko akademickie ćwiczenie z geolokalizacji. Pokazuje ona fundamentalną zmianę w podejściu do OSINT, gdzie umiejętności programistyczne i analityczne stają się równie ważne, co znajomość wyszukiwarek. Zamiast pytać „co widać na zdjęciu?”, zadaliśmy pytanie „jakie niezmienniki geometryczne można z niego wyekstrahować i jak je znaleźć w globalnej skali?”.
Metoda ta ma kilka istotnych implikacji:
- Skalowalność: Przetworzenie ponad 80 milionów potencjalnych lokalizacji w ułamku sekundy na konsumenckiej karcie graficznej 18 pokazuje, że analizy na skalę planetarną są w zasięgu nawet niewielkich zespołów czy indywidualnych badaczy.
- Odporność na niską jakość danych: Podejście geometryczne jest mniej wrażliwe na niską rozdzielczość, artefakty kompresji czy nietypowe warunki oświetleniowe, które mogłyby zmylić algorytmy rozpoznawania obrazu. Liczą się względne pozycje, a nie detale.
- Zastosowania poza OSINT: Taka technika może być używana w badaniach naukowych (np. monitorowanie zmian w środowisku naturalnym, takich jak erozja wybrzeży czy zmiany w archipelagach, co jest szczególnie istotne dla Polski, która posiada własne wybrzeże i mierzy się z wyzwaniami związanymi z jego ochroną i monitorowaniem. Możliwe jest również wykorzystanie podobnych metod do analizy zmian w infrastrukturze portowej lub przybrzeżnej, co ma znaczenie dla gospodarki morskiej kraju.) [INSUFFICIENT_PL_ANGLE]
Źródła
Zobacz też
- ShadowBroker: OSINT-owy „boski widok” z publicznych danych
- Biały wywiad (OSINT): Przewodnik po 100+ darmowych narzędziach do analizy
- Bellingcat: deanonimizacja z mapy strony WordPress
Przypisy
-
Wyzwanie gralhix 004 polegało na zidentyfikowaniu nazwy kurortu, współrzędnych wyspy oraz kierunku, w którym skierowana była kamera podczas robienia zdjęcia. — yassa9.github.io › gralhix 004 ↩ ↩2
-
Autor zdecydował się rozwiązać wyzwanie gralhix 004 za pomocą matematyki i programowania, zamiast używać Google Lens. — yassa9.github.io › gralhix 004 ↩
-
Analiza metadanych pliku
main.pngza pomocąexiftoolnie dostarczyła użytecznych informacji, pokazując jedynie typ pliku (WEBP), wymiary obrazu (736x515). — yassa9.github.io › gralhix 004 ↩ -
Na zdjęciu widoczne są trzy masy lądowe: wyspa z kurortem (P0), prawa wyspa (P1) i lewa przednia wyspa z górskim szczytem (P2). — yassa9.github.io › gralhix 004 ↩ ↩2
-
Autor nie mógł stworzyć poprawnego modelu perspektywicznego, ponieważ zdjęcie zostało wykonane dronem, a wysokość nie była znana ani dostępna w metadanych. — yassa9.github.io › gralhix 004 ↩ ↩2
-
Do określenia względnych odległości między trzema wyspami i kątów trójkąta użyto intuicyjnych szacunków. — yassa9.github.io › gralhix 004 ↩
-
Stworzono mały interfejs GUI (01_triangle_gui.py) do rejestrowania współrzędnych pikseli i obliczania geometrii trójkąta. — yassa9.github.io › gralhix 004 ↩ ↩2
-
Wyszukiwanie uwzględniało tolerancję ±20% dla wartości odległości i kątów, aby skompensować niedokładność klikania. — yassa9.github.io › gralhix 004 ↩ ↩2
-
Jako zbiór danych do porównania użyto zestawu podzielonych poligonów lądowych OpenStreetMap (land-polygons-split-4326) w WGS84, o rozmiarze 882 MB. — yassa9.github.io › gralhix 004 ↩ ↩2
-
Pierwszy filtr heurystyczny ograniczył wyszukiwanie do szerokości geograficznych tropikalnych (od -30° do 30°), ponieważ wyspa na zdjęciu wyglądała na tropikalną. — yassa9.github.io › gralhix 004 ↩
-
Po zastosowaniu filtra szerokości geograficznej pozostało 141 131 poligonów lądowych. — yassa9.github.io › gralhix 004 ↩
-
Drugi filtr, gęstości lokalnej, odrzucał kandydatów, jeśli w promieniu 5 km znajdowało się więcej niż 10 innych centroidów, redukując liczbę do 51 576. — yassa9.github.io › gralhix 004 ↩ ↩2
-
Klastrowanie polegało na znajdowaniu punktów, które miały co najmniej dwóch sąsiadów w promieniu 20 km, tworząc klastry składające się z co najmniej 3 punktów. — yassa9.github.io › gralhix 004 ↩
-
Po klastrowaniu pozostało 23 500 klastrów. — yassa9.github.io › gralhix 004 ↩
-
Z każdego klastra generowano trójki punktów, przy czym klastry były ograniczane do 60 punktów, aby uniknąć nadmiernego wzrostu liczby kombinacji. — yassa9.github.io › gralhix 004 ↩
-
Łącznie 23 500 klastrów wygenerowało 80 690 777 trójek. — yassa9.github.io › gralhix 004 ↩
-
Dopasowywanie trójek odbywało się na GPU, gdzie każdy wątek CUDA przetwarzał jedną trójkę. — yassa9.github.io › gralhix 004 ↩ ↩2
-
Proces na GPU (NVIDIA GeForce RTX 3050) trwał 204.1 ms i przetworzył 80.7 miliona trójek, z czego 158 784 przeszło wstępną maskę. — yassa9.github.io › gralhix 004 ↩ ↩2 ↩3 ↩4
-
Wątki sortowały 3 punkty według powierzchni lądu, aby wybrać P0 (najmniejszą wyspę kurortu), a następnie używały kierunku nawijania pozostałych dwóch do przypisania P1 i P2. — yassa9.github.io › gralhix 004 ↩
-
Kąt przy P0 i stosunek odległości były obliczane niezależnie przez każdy wątek. — yassa9.github.io › gralhix 004 ↩
-
Trójka była uznawana za pasującą, jeśli kąt, stosunek, rozmiar P0, separacja między P0 i P1 oraz długości obu boków mieściły się w oknach tolerancji odcisku palca. — yassa9.github.io › gralhix 004 ↩
-
Po deduplikacji pozostało 8 915 unikalnych trójek. — yassa9.github.io › gralhix 004 ↩
-
Każda pozostała trójka była testowana pod kątem otwartej wody w sąsiedztwie, poprzez sprawdzenie, czy prostokąt zbudowany wzdłuż krawędzi P0→P1 (po stronie, gdzie nie ma P2) nie przecina innych mas lądowych. — yassa9.github.io › gralhix 004 ↩
-
Po teście otwartego prostokąta liczba unikalnych trójek spadła do 948. — yassa9.github.io › gralhix 004 ↩
-
W kolejnym etapie sprawdzano kształt wyspy P0 (kurortu), aby upewnić się, że przypomina koralową wysepkę (cay). — yassa9.github.io › gralhix 004 ↩
-
Kompaktowość kształtu mierzono za pomocą wskaźnika Polsby-Popper (PP), gdzie 1.0 oznacza idealne koło, a niższe wartości oznaczają bardziej postrzępiony lub wydłużony zarys. — yassa9.github.io › gralhix 004 ↩
// Komentarze ...
Dodaj komentarz