Tehtiin tossa Junctioniin kahden kaverin (shaiggon, tkln) kanssa pikainen häx yhdestä ideasta, jota oli tullut pyöriteltyä päässä jo jonkin aikaa. Lentsikoissa on kivat näkymät vain ikkunapaikallisille, ja niillekin tasan yhteen suuntaan. Mitä jos laitettaisiin koneeseen kameroita joka suuntaan niin, että ne kattaisivat kaikki suunnat ("360°" tai täysi avaruuskulma), ja streamattaisiin tätä kullekin haluavalle matkustajalle vapaavalintaiseen mobiilipäätelaitteeseen eli vaikka kännykkään? Tehtiin proto ja ajateltiin samalla noita muodissa olevia 3d-virtualreality-kameroita maan pinnallekin.
Vastaavaan väsäykseen maan pinnalla alkaa olla nykyään aika useita kameroita (gopro, nokia ozo, point grey ja muita) joista ainakin useimmat näyttävät prosessoivan useammasta kamerasta kuvatun videon jälkeenpäin jotenkin yhteen, mutta eiköhän noita ala reaaliajassakin toimivia tulla. Lentokoneessa kamerat tulisi varmaan asetella ympäriinsä koneen runkoa, kun runko tulisi tielle johonkin suuntaan katsoessa jos kuva tuotettaisiin tuollaisella useamman kameran pienellä pallolla. Tai sit vaihtoehtoisesti riittäisi varmaan asentaa kameroita rungon pohjaan ja ylälaitaan, kun kaikki on niin kaukana ettei sijainnilla oikeastaan ole kauhean tarkkaan väliä. Meillä siis oli ideana se, että kännykän voi kääntää haluamaansa suuntaan ja tiirailla sitten siitä vaikka auringonlaskua tai jotain maamerkkiä. Samaan videokuvaan voisi sitten esim. annotoida jotain ekstratietoa, niin tätä voitaisi kutsua vaikka augmented realityksi.
Tuollaisessa 360-aste-kamerassahan pointtina lienee se, että kun video soitetaan jälkeenpäin sellaisena että sitä voi pyörittää mihin kulmaan tahansa, virtuaalinen kamera sijaitsee mielellään siinä missä kaikkien kameroiden polttopiste on (ideaalisesti kaikilla sama, mut enpä osaa sanoa voisiko jollain linssiviritelmällä kikkailla polttopistettä kuvakennon taakse jotta se olisi kameramöntin keskellä). Lentokoneesta katsottuna voidaan tehdä triviaalisti oletus, että kaikki mitä kuvataan on äärettömän kaukana (paitsi sellainen kurja erikoistapaus kuin pilvet). Tästä johtuu, että mikään mitä lentokoneen ikkunasta tai tästä virtuaali-ikkunasta näkee ei juurikaan muutu lokaalin sijainnin perusteella, vaan pelkästään katsomissuunnan. Tökätään siis niitä kameroita johonkin päin koneen runkoa kunhan niiden kuva-ala kattaa kaiken, ja sitten soitetaan tuloksena syntyvä video kännykässä.
Kännykkäänhän kuvan saa vaikka wifillä, jota lentokoneissakin tuntuu nykyään joissain olevan, ja videon voi koostaa eri kameroista yhdeksi jonkun sortin serverillä koneessa ja tää sit streamataan kännyköihin. Kaikenlaiset yksityiskohdat datan yläilmoissa siirtelystä sivuutettiin triviaalina, ja keskityttiin siihen, että mitenkäs nuo kuvat stitchataan yhteen reaaliajassa ja miten tuloksena saatu 360-asteinen video soitetaan kännykässä/tabletissa reaaliajassa.
Olin Junctionissa osallistumisen lisäksi edustamassa Nvidiaa sponssiständillä, ja hommasin firmalta tuonne Jetson TK1-kittejä osallistujien käytettäväksi. Otin moisen meillekin ja kameroiksi noita ps3eye-halpiksia kun niitä löytyi neljä (viidennen olin vahingossa piilottanut johonkin hyvään talteen). Jetsonin Tegra-piilastu on siitä kiva, ettei varmaan laskentateho ainakaan lopu kesken vaikka onkin pieni mobiilialusta, kun löytyy neljä modernia ARM-corea ja Kepler-GPU.
Päädyttiin keksimään tekniikan ideaksi (muita kameroita tutkimatta, arvottiin vaan yhtenä iltana että mitähän tehtäis ja miten) skybox-tyylinen rendaus (eli cubemap), eli piirretään tasan yksi kuutio keskitettynä kameran ympärille. Kuution tahkoissa on tekstuurit siten, että ikäänkuin jokaisen tahkon suunnasta näkyvä näkymä olisi kuvattu 90° x 90° FOVilla. Tekstuurien muodostus tapahtuu siten, että jokainen fyysinen kamera ajatellaan taas kuution keskelle, ja kameran näkymä projisoidaan kuution tekstuureille sen mukaan, mihin päin kamera on suunnattu. Skybox on ns. sairaan nopee ja helppo rendata about millä vaan mobiililaitteella, kameroiden projisointi tekstuureille on myös suhteellisen halpa operaatio, ja tällä lailla piirtäminen tuottaa varmaan käyttäjän mielestä luonnollisen kuvan. Skyboxin asento luetaan piirtolaitteen gyroskoopista.
Yöllä koodia tunkatessa tuli tehtyä muutama virheoletus minkä selvittelyyn meni vähän ylimääräistä aikaa, eli jossain vaiheessa mm. unohtui tuo fakta että kaikki kuvaavat kamerat voi ajatella origoon, ja pähkäilin että mites nämä projektiomatriisit nyt sitten muka noin. Myös sillä lailla suunnatut kamerat, että näkymä leikkaantuu tahkojen saumassa tietyllä lailla (kameran katsesuunta suunnilleen tasan tahkon pinnan suuntaisesti), ovat ainakin yhdellä tavalla piirrettynä vähän hankala miettiä, mutta keksin järkevänkin tavan jälkeenpäin.
Tekstuurien renderöinti käy siis sillä lailla, että kamerat oletetaan kaikki cubemapin keskelle, niiden suunnat on kalibroitu keskenään siten että yksi sovitaan vaikka katsomaan suoraan yhtä tahkoa päin ja lopuille määritellään pyöritysmatriisi suhteessa tähän, ja jokaisen näkymä projisoidaan niille tahkoille, joihin se osuu. Tätä ennen tietysti pitää korjata mm. epätäydellisten linssien aiheuttama radiaalinen vääristymä. Projisointi tehtiin tässä niin, että katsotaan missä kukin kamerasta lähtevä ja kameran sensorin kuvatason nurkan läpi kulkeva suora leikkaa projisoitavan pinnan, ja näistä neljästä muodostetaan OpenCV:llä matriisi jolla warpataan kameran näkymä tahkolle. Ehkä mukavampi tapa olisi rendata jokainen tahko GPU:lla (ihan OpenGL:llä, tai sit vaikka CUDAlla) niin, että kullekin tahkon pikselille katsotaan, että mikä jokaisen sitä päin törröttävän kameran pikseli tähän tulee ja blendataan ne. Jos näkymä leikkaantuu tuolla yllämainitulla tietyllä lailla, niin tahkosta poispäin suuntaavia nurkkia päin menevät suorat leikkaavat tietysti tason kameran takana, mutta sekin tuntui tuottavan ihan järkevän projektiomatriisin kun tulos näytti toimivalta. Kai se sit menee noinkin. Tarvitsee vain katsoa, ettei kameran kuva projisoidu tasan kameran takana olevaan tahkoon väärin päin, vaan jättää takana olevat tahkot piirtämättä.
Asiakaspäässä piirtäminen on triviaalia, kuten mainittu. Tehtiin natiivi Android-sovellus, koska ei saatu videotekstuuria toimimaan WebGL:llä vielä kunnolla. (Lopulta ei saatu videon streamausta toimimaan ja piirrettiin ennalta talletettua videota ja/tai täyttä taivastekstuuria, mut eipä sen väliä demossa.) Softa on simppeli OpenGL-rendaaja joka vaan lukee frameja videosta jollain Androidin videoplayerilla, tuuttaa niitä tekstuuriksi ja piirtää kuution, jonka uv-tekstuurikoordinaatit on laskettu niin, että oheisen kuvan näköisestä luetaan korrekti neliö. Pyörittelykulma luetaan gyroskoopista ja sitä ylläpidetään matriisina. (Tätä matriisia tulisi varmaan normalisoida ajan kanssa pidemmän päälle.)
Videon streamaaminen serveriltä (Jetson) asiakkaalle (Android-laite) osoittautui kosmisen kinkkiseksi. Kun suunnilleen vuorokauden päänraapimisen jälkeen tunkattiin läppärillä toimimaan saatu videostreamaus ffmpegillä ja gstreamerillä Jetsonille, huomattiin mm. että ugly-gstreamerplugarit vaativat deppiketjussaan jonkun OpenCV-kirjaston, joka konfliktaa opencv4tegra-paketin kanssa, eli sen OpenCV:n joka on optimoitu just tälle raudalle Nvidian toimesta. No eipä tuo kameranluku ja projisointi ja streamaus lopulta käyttänytkään kuin muutaman prosentin CPU-tehoista, mutta kurjaa silti. Ja noiden ffmpeg-taikavipujen arpominen nopeasti vaatisi suunnilleen jonkun automaagisen geneettisen algoritmin. Lisäksi kun Androidin playerille koitettiin syöttää omakeksimää sdp-tiedostoa, niin se vain jotenkin tukehtui. Läppärillä saatiin kuitenkin vapaavalintainen videoplayeri eli vaikka mpv tai vlc toimimaan. Asiaa ei auttanut myöskään se, että usb-wifi-tikku tai sen ajurit oli vähän kehno ja yhteys pätki ja lagasi.
Softa löytyy githubista ja hackathon-submitti tehtiin jonkun tommosen devpostin kautta.
Jatkokehityksenä vois olla vaikka ostaa noita kameroita läjä, hommata niille laajemmat linssit, ja 3d-tulostaa niille joku pallomainen pidike, koska täyden kattavuuden kuvaa olisi kiva kokeilla ja tuo virtuaalitodellisuus on nykyään muutenkin muodissa, niin vois katsoa että mikä siinä nyt on niin siistiä. Isoin ongelma toistaiseksi on saada kameroista reaaliajassa tarpeeksi pikseleitä irti, kun USB 2 ei ihan riitä. Tästä jotain mietteitä tuolla repon TODOssa. Jetsonista löytyisi mm. USB 3. Kaverin linkkaama konseptivideo isommista virtuaali-ikkunoista on myös aika jännä, eli ei rajoituta kännykkään vaan piirretään tuo kuva kaikkiin koneen sisäpintoihin.
0 kommenttia
Oma kommenttisi
Mielipide tämän sivun asiasta? Kirjoita toki. Älä raapusta kuitenkaan ihan asiattomia juttuja.
Jos on yksityisempää asiaa, tarkkaa kysyttävää tai aihetta pidemmälle keskustelulle, käytä yhteydenottolomaketta kommentoinnin sijaan.
Hölmöt kommentit saatetaan moderoida pois jälkikäteen.