E57 bez tajemnic: "PDF dla chmur punktów"
Wyobraź sobie zdjęcie pokoju, które zamiast płaskiego obrazu zapisuje dokładne położenie miliona drobnych punktów na ścianach, krzesłach i kubkach do kawy. Szybko obracający się laser mierzy odległość do każdej powierzchni. Tak powstaje chmura punktów — trójwymiarowe "zdjęcie" złożone ze zmierzonych punktów. Bez technicznego żargonu pokażemy, co kryje plik E57 i jak nasza aplikacja sprytnie wykorzystuje jego dane.
Po co w ogóle osobny format?
Zwykłe zdjęcie to siatka kolorowych pikseli — prosta sprawa. Skan 3D jest bardziej złożony. Dla każdego z milionów punktów trzeba zapisać jego położenie w przestrzeni (trzy liczby: X, Y, Z), kolor, siłę odbitego sygnału lasera (czyli intensywność — coś jak czarno-białe "zdjęcie laserowe"), a często także zdjęcia panoramiczne wykonane w tym samym czasie przez skaner.
Wyobraź sobie, że jedna osoba skanuje urządzeniem Faro, druga używa skanera Leica, a klient otwiera wynik w oprogramowaniu Autodesk. Trzy urządzenia, trzy programy — wszystkie muszą odczytać ten sam plik, nawet po latach, bez proszenia producenta o tajny dekoder. Ten problem rozwiązuje E57: otwarty standard niezależny od producenta, opublikowany jako ASTM E2807 i oparty na bibliotece libE57 o otwartym kodzie źródłowym. Nazywa się go "PDF dla chmur punktów": to jeden przenośny plik, który każdy program odczytuje według tych samych zasad.
Główna idea: tekstowy spis i binarne dane
Plik E57 to połączenie dwóch zupełnie różnych części: niewielkiego fragmentu XML — czytelnego dla człowieka tekstu pełniącego rolę spisu treści — oraz dużych bloków danych binarnych, w których miliony surowych wartości liczbowych są zapisane w zwartej postaci, by można je było szybko odczytać.
Dlaczego spis znajduje się na końcu? Podczas zapisywania pliku skaner nie wie jeszcze, ile miejsca zajmą dane. Najpierw zapisuje więc surowe dane, a po zakończeniu dodaje uporządkowany spis. To znacznie przyspiesza dostęp: aby pobrać jeden skan z pliku o wielkości 20 GB, program odczytuje niewielki nagłówek, przechodzi do spisu XML, znajduje wpis "skan nr 3 zaczyna się od bajtu 4 812 000 000" i od razu przechodzi we wskazane miejsce.
Dyskretny mechanizm ochrony: cały plik jest podzielony na "strony" po 1024 bajty. Ostatnie 4 bajty każdej strony zajmuje suma kontrolna — cyfrowy odcisk, dzięki któremu program może wykryć uszkodzenie pliku.
Wszystko zaczyna się od jednego korzenia
Spis XML ma strukturę drzewa, podobną do folderów na komputerze. Ma jeden korzeń root i dwie główne gałęzie: data3D to numerowana lista skanów, a images2D — numerowana lista zdjęć (zwykle panoram 360° wykonanych przez skaner).
Dwa sposoby zapisu punktu
Skaner laserowy nie posługuje się bezpośrednio współrzędnymi X, Y, Z. Stoi w jednym miejscu i obraca się, a dla każdego punktu określa trzy wartości: odległość (jaką przebyła wiązka), azymut (kąt obrotu w poziomie) i kąt elewacji (odchylenie w górę lub w dół). To współrzędne sferyczne — naturalny sposób opisu pomiarów skanera. Większość programów woli jednak kartezjańskie współrzędne X, Y, Z. E57 pozwala zapisać punkty w obu układach, a przeliczenie między nimi wymaga tylko prostych obliczeń trygonometrycznych.
Trzy rodzaje osadzonych zdjęć
Zdjęcia w images2D nie są linkami do plików w osobnym folderze — dane JPEG lub PNG znajdują się bezpośrednio w pliku E57. Istnieje też kilka rodzajów osadzonych zdjęć. Każde z nich E57 zapisuje jako "reprezentację", która informuje program, na ile może polegać na geometrii obrazu. Różnica sprowadza się do jednego pytania: jak dokładnie opisano kamerę?
sphericalRepresentation— pełna panorama 360° × 180°, czyli znany rozciągnięty obraz ekwirektangularny o proporcjach 2:1. Ponieważ odwzorowanie jest znane, każdemu pikselowi odpowiada dokładny kierunek, co pozwala precyzyjnie dopasować obraz do chmury punktów. To główna ścieżka naszego przetwarzania: odczytujemy obraz, nadajemy mu proporcje 2:1 i przekazujemy go do przeglądarki panoram.pinholeRepresentation— zdjęcie wykonane zwykłym obiektywem, opisane klasycznym modelem kamery otworkowej (ogniskowa, rozmiar matrycy, środek optyczny). Dzięki temu program zna kierunek każdego piksela, ale tylko w węższym polu widzenia. W praktyce tak działa przede wszystkim Leica: zapisuje bezpośrednio w pliku E57 gotową mapę sześcienną — sześć płaskich ścian sześcianu skierowanych na zewnątrz. Nasz moduł łączy te ściany w pełną panoramę. To jeden z najprostszych przypadków przekształcenia danych w poprawny obraz 360°.visualReferenceRepresentation— zdjęcie bez żadnego modelu aparatu, przeznaczone wyłącznie do oglądania. Nie można na nim wykonywać pomiarów ani rzutować go na chmurę punktów; służy tylko jako obraz poglądowy. Nasz importer zachowuje takie zdjęcia jako załączone komentarze zamiast umieszczać je w przestrzeni 3D.
Jest jednak pewien haczyk. sphericalRepresentation to popularny wybór, ale zaskakująco łatwo o drobny błąd w jego zastosowaniu. Dlatego ten sam skan może wyglądać inaczej w różnych programach.
- Przycinanie martwych stref. Każdy skaner ma obszar, którego nie widzi — zwykle bezpośrednio pod sobą, w miejscu, gdzie stoi jego statyw. Niektóre programy eksportujące po prostu przycinają tam panoramę, pozostawiając lukę lub obraz o niestandardowej wysokości.
- Niekwadratowe piksele. Prawidłowa panorama ma kwadratowe piksele (
pixelWidth=pixelHeight). W niektórych plikach tak nie jest, przez co obraz wygląda na rozciągnięty, dopóki nie zostanie przeskalowany. - Problemem bywa kierunek "do przodu". Obrót zapisany z panoramą określa, jaki kierunek znajduje się w środku obrazu. Nie ma jednak jednej definicji tego, co oznacza "do przodu" — niektóre programy eksportujące ustawiają tam północ, inne wschód. Drobna pomyłka obraca cały widok.
- Narzędzia do edycji mogą powodować utratę danych. Na przykład po otwarciu i ponownym zapisaniu pliku E57 w programie CloudCompare może zniknąć pozycja, z której wykonano obrazy
pinholeRepresentation— zdjęcia pozostaną, ale bez informacji o miejscu ich wykonania.
W praktyce różne programy często wyświetlają ten sam plik E57 inaczej. Nasz importer próbuje korygować typowe rozbieżności: zmienia skalę niekwadratowych pikseli, poprawia orientację panoramy i ujednolica proporcje obrazu do 2:1. Dzięki temu wirtualny spacer wygląda prawidłowo niezależnie od programu, w którym powstał plik.
Gdy panorama jest zapisana w samej chmurze punktów
To jeden z najbardziej eleganckich — i najmniej docenianych — pomysłów w całym formacie. Panorama nie musi być zapisana jako osobny obraz: może też kryć się w samej chmurze punktów. Skaner laserowy nie wysyła wiązki na chybił trafił — omiata regularną siatkę kierunków, wiersz po wierszu i kolumna po kolumnie, podobnie jak dawny telewizor tworzący obraz na ekranie. E57 pozwala zachować tę kolejność: każdemu punktowi przypisuje rowIndex i columnIndex, które wskazują jego komórkę w siatce. Zapisany w ten sposób skan nazywa się uporządkowanym.
Korzyść jest prosta: jeśli punkty leżą na siatce, chmura jest już obrazem. Wystarczy odczytać ją wiersz po wierszu, a każdy punkt trafi na piksel — panorama powstanie bez ponownego rzutowania. Plik zawiera też rozmiar siatki w indexBounds (columnMaximum, rowMaximum), więc program zna rozdzielczość z góry. Nasz moduł tworzący panoramę wyznacza szerokość obrazu bezpośrednio z columnMaximum + 1.
Siatka musi jednak tworzyć idealny prostokąt, a skanowany świat nie jest tak regularny. Co z kierunkami, w których wiązka pobiegła w otwarte niebo i nie wróciło żadne odbicie? Rozwiązanie jest proste: wypełnić te komórki fikcyjnymi punktami — często o odległości równej dokładnie 0, co oznacza "wysłano wiązkę, ale w nic nie trafiła". Dzięki nim siatka pozostaje prostokątna, lecz punkty te nie reprezentują rzeczywistej geometrii i trzeba je pomijać. Nasz importer oznacza każdy punkt o zerowej odległości i przypisuje mu umowną dużą odległość, aby obliczenia na siatce nadal działały. Przy tworzeniu mapy głębi i eksportowaniu chmury punktów nigdy nie traktuje tych fikcyjnych punktów nieba jako rzeczywistych powierzchni.
Jak zamienić skan w panoramę, którą możesz oglądać od środka
Nie każdy skan ma gotową siatkę — niektóre są po prostu nieuporządkowanymi zbiorami punktów. Dobra wiadomość: panoramę nadal można odtworzyć i właśnie tu zaczyna się nasza praca. Skan to w istocie "pełna sfera punktów zmierzonych pod różnymi kątami z jednego stanowiska", którą można rozwinąć w płaską panoramę.
Każdemu punktowi przypisz piksel na podstawie jego położenia kątowego — od lewej do prawej wzdłuż szerokości obrazu i od góry do dołu wzdłuż jego wysokości. Tak powstaje rozciągnięta panorama ekwirektangularna o proporcjach 2:1. Kluczowa jest mapa głębi: gdy z każdym pikselem powiązana jest odległość, panorama wyglądająca na płaską pozwala wykonywać pomiary i przemieszczać się po skanowanej przestrzeni. Kliknij dwa punkty na ścianie, a program obliczy rzeczywistą odległość między nimi, ponieważ zachowuje dane 3D, na których opiera się panorama.
Dlaczego więc E57 jest ważny?
Bo pozwala wymieniać dane niezależnie od producenta. Geodeta skanuje most sprzętem jednej marki, inżynier otwiera dane w innym programie, a architekt archiwizuje je na kolejne dwadzieścia lat. Wszyscy mogą polegać na tym samym pliku E57, bez uzależnienia od jednego dostawcy. Ten otwarty standard, który każdy może wdrożyć, przechowuje w jednym pliku kolory, intensywność odbicia lasera, geometrię, panoramy i niezwykle ważne pozycje czujników.
Na koniec ciekawostka: czas wykonania skanu zapisany w pliku E57 jest podawany jako czas GPS — liczba sekund od 6 stycznia 1980 roku, kiedy rozpoczęto jego odmierzanie — a nie od roku 1970, jak zwykle w komputerach. Jeśli pomylisz te sposoby liczenia czasu, skan wykonany dziś będzie wyglądał na wykonany w 2013 roku.
Chcesz dowiedzieć się więcej?
- libE57.org — referencyjna biblioteka o otwartym kodzie źródłowym i główna strona formatu
- ASTM E2807 — oficjalna specyfikacja
- libE57Format · Image2D — dokładne definicje reprezentacji sferycznej, reprezentacji kamery otworkowej i reprezentacji odniesienia wizualnego
- Paul Bourke’s E57 notes — zwięzły opis techniczny nagłówka i struktury pliku