Nie potrzebny będzie też żaden drogi sprzęt, ani nawet wysokiej klasy aparat cyfrowy. Zdjęcia na potrzeby wygenerowania modelu rękawiczki, który powinieneś widzieć poniżej, zostały zrobione tym antykiem. Kosztował on mnie 450 zł jakieś 12 lat temu. Telefon, który masz w kieszeni, pewnie robi znacznie lepsze zdjęcia.
Uwaga: poniższy tekst nie jest tutorialem, a raczej luźnymi notatkami, które mają tak samo służyć mi za kilka miesięcy lub lat, jak i innym czytelnikom. Może przestawiać nieoptymalny przebieg procesu.
Jeśli nie widzisz obracalnego modelu 3D (bo przeglądarka nie obsługuje WebGL lub serwis ShareMy3D padł), to poniżej znajduje się statyczny zrzut ekranu.
Oprogramowanie - kompilacja
Opis bazuje na założeniu, że użytkownik korzysta z jakiejś współczesnej dystrybucji Linuksa. W moim przypadku jest to Kubuntu 16.04 64-bit.Utworzyłem jeden katalog dla całego oprogramowania do fotogrametrii. W tym katalogu skompilowałem dwa pakiety:
- openMVG, zgodnie z oficjalnymi instrukcjami,
- openMVS, zgodnie z oficjalnymi instrukcjami,
- dodatkowo zainstalowałem MeshLab - wygodną przeglądarkę i edytor chmur punktów oraz modeli 3D, znajdziesz go w swoim ulubionym menedżerze pakietów.
Pierwszym problemem w Ubuntu 16.04 jest niestabilna wersja (3.3-beta) pakietu libeigen-dev. Obszedłem ten problem pożyczając od Debiana paczkę deb w wersji 3.2.
Drugim okazało się vcglib i błąd związany z przestrzenią nazw:
error: ‘isinf’ was not declared in this scope error: ‘isnan’ was not declared in this scopeWystarczyło odszukać plik vcglib/vcg/math/base.h i zamienić
templatenaint IsNAN(T t) { return isnan(t) || isinf(t); }
templateint IsNAN(T t) { return std::isnan(t) || std::isinf(t); }
Ogólny model postępowania
Pakiet oprogramowania openMVG będzie karmiony wykonanymi przez nas zdjęciami, próbując znaleźć położenie punktów składających się na obiekt i stworzyć rzadką chmurę. Etap ten opisany jest w dokumentacji SfM: Structure from Motion. Chmura punktów będzie podstawą do pracy openMVS, które kolejno zagęści chmurę, utworzy siatkę wielokątów i w końcu oteksturuje ją.Na początek potrzebujemy kilku zdjęć przy dobrym oświetleniu, bez użycia flesza, najlepiej z niezbyt dużym przesunięciem między nimi.
Sprytnym trikiem jest podłożenie pod obiekt czegoś o charakterystycznym wzorze, jak gazeta, czy (w moim przypadku) mapa. To znacznie poprawia skuteczność algorytmów SfM. Problematyczne okazują się za to obiekty o znacznych powierzchniach w jednolitym kolorze, odbijających światło lub częściowo przezroczystych.
Proces krok po kroku
Zakładam że openMVS i openMVG zostały skompilowane w wspólnym katalogu:ls -l razem 28 drwxrwxr-x 7 adi adi 4096 cze 10 20:49 ceres_build drwxrwxr-x 12 adi adi 4096 cze 9 18:54 ceres-solver drwxrwxr-x 6 adi adi 4096 cze 9 19:44 openMVG drwxrwxr-x 12 adi adi 4096 cze 9 21:07 openMVG_Build drwxrwxr-x 8 adi adi 4096 cze 9 18:42 openMVS drwxrwxr-x 8 adi adi 4096 cze 9 19:41 openMVS_build drwxrwxr-x 9 adi adi 4096 cze 9 18:34 vcglibWykonałem 10 zdjęć rękawiczki położonej na mapie Polski i wrzuciłem je (niezbyt elegancko) do katalogu openMVG_Build/software/SfM/lapka_in
Kolejny krok to uruchomienie skryptu Pythona:
python SfM_GlobalPipeline.py lapka_in lapka_global_outI już tutaj pojawił się pierwszy zgrzyt. OpenMVG poinformowało o braku modelu aparatu cyfrowego w bazie:
Warning & Error messages: IM000217" model "Photosmart M407" doesn't exist in the databaseWystarczyło otworzyć plik openMVG/src/openMVG/exif/sensor_width_database/sensor_width_camera_database.txt i dodać odpowiednią pozycję.
W konsoli powinniśmy zobaczyć m.in.:
Structure estimation took (s): 1.861. #landmark found: 12600 ...Generating SfM_Report.html Found a sfm_data scene with: #views: 10 #poses: 10 #intrinsics: 1 #tracks: 1260010 zdjęć i 10 rozpoznanych pozycji, to dobry znak. Otwierając chmurę punktów lapka_global_out/reconstruction_global/colorized.ply w programie MeshLab zobaczymy coś takiego:
To chmura rzadka, stąd nie przypomina jeszcze naszego fotografowanego obiektu, ale warto zwrócić uwagę na zielone punkty. To pozycje aparatu podczas robienia zdjęć.
Musimy wyeksportować wyniki z openMVG do formatu przyjaznego openMVS (dokumentacja):
../../Linux-x86_64-RELEASE/openMVG_main_openMVG2openMVS -i \ lapka_global_out/reconstruction_global/sfm_data.bin -d lapka_out -o lapka_out/scene.mvsTeraz, już używając openMVS, zagęszczamy chmurę:
../../../openMVS_build/bin/DensifyPointCloud lapka_out/scene.mvsTak wygląda chmura gęsta otwarta w MeshLab (plik lapka_out/scene_dense.ply):
Pozostało tylko wygenerować siatkę wielokątów i oteksturować ją:
../../../openMVS_build/bin/ReconstructMesh lapka_out/scene_dense.mvs ../../../openMVS_build/bin/TextureMesh lapka_out/scene_dense_mesh.mvsEfekt końcowy powinien być taki jak na początku wpisu.
Q&A:
Q: Ile trwa cały proces?A: Kilkanaście sekund do kilku minut, dla zadań jak w powyższym opisie.
Q: Nie masz ładniejszego przykładu niż zmiętoszona rękawiczka?
A: 30-letni misiu może być?
Q: W czym jest to lepsze od popularnych rozwiązań "w chmurze"?
A: Nie ma ograniczenia co do liczby zdjęć (np. Autodesk 123D Catch pozwala tylko na 70 zdjęć), nie trzeba czekać na wysłanie zdjęć na serwer, łatwiej zdiagnozować problem w razie niepowodzenie i nie trzeba zaptaszać żadnych cyrografów podczas instalacji. Bardziej zaawansowani użytkownicy mogą usprawnić proces pisząc skrypty czy przyjazne GUI (pewnie już ktoś to zrobił).
Q: Czy opisywane oprogramowanie działa na Windows?
A: Oczywiście, że tak.
Q: Coś jeszcze?
A: Obracaj modelem rękawiczki lub misia od patrząc na niego od wewnątrz a ulegniesz złudzeniu optycznemu.