Sinisävyinen aaltomainen kuvio

Syvyys­ku­van visua­li­soin­nista: trigo­no­met­riaa pistepilvipöllyssä

Tässä artik­ke­lissa kuva­taan Base Camp –hank­keen etätek­no­lo­gia­ko­kei­lun vaati­maa jatko­ke­hi­tystä virtu­aa­li­ho­lo­gram­mien visua­li­soin­ti­rat­kai­suun. Edel­li­sessä artik­ke­lissa käsi­tel­tiin, miten piste­pil­velle luodaan staat­ti­nen 3D-malli proji­soin­tia varten.  Tässä artik­ke­lissa johde­taan projek­tio­al­go­rit­min toteu­tus matemaattisesti.

Mistä projek­tiossa on kyse?

2D-kuva­pis­teen projek­tioon tarvi­taan kuvan koko vaaka- ja pysty­suun­nassa. Tämän lisäksi on tiedet­tävä kameran polt­to­väli. Polt­to­väli esite­tään kulmayk­si­köinä; tässä artik­ke­lissa sitä käsi­tel­lään asteina. Kameran ajatel­laan tällöin olevan kuvan keskipisteessä.

Asioi­den yksin­ker­tais­ta­mi­seksi käsit­te­lemme aluksi vain yhtä leveys­suun­taista projek­tiota, mutta vastaava toimin­nal­li­suus on toki laajen­net­ta­vissa myös pysty­suun­taan. Kuva­pis­teen leveys­suun­tai­nen koor­di­naatti kuva­taan etäi­syy­tenä kuvan keski­pis­teestä suhteel­li­sella arvo­vä­lillä [1,-1]. Kuten kuvasta 1 havai­taan, projek­tiosta löytyy suora­kul­mai­nen kolmio, jolloin sivun z pituus on lasket­ta­vissa trigo­no­met­rista kaavaa hyödyntämällä.

Kolmio johon liitetty matemaattisia merkintöjä.
Kuva 1. Projek­tiossa hyödyn­ne­tään trigonometriaa. 

Miten yksit­täi­sen pisteen proji­sointi toimii?

Yksit­täi­sen pisteen proji­soin­tia varten kuvasta on valit­tava mieli­val­tai­nen piste, jonka suhteel­li­nen etäi­syys keski­pis­teestä esite­tään symbo­lilla x’. Pisteen ja z-sivun muodos­ta­man suora­kul­mai­sen toista kolmion kulma esite­tään symbo­lilla β. Tällöin voimme muodos­taa kuvassa 2 näkyvät yhtälöt.

Matemaattinen laskukaava.
Kuva 2. Kulman tangentti säilyy samana, jos sivujen pituu­det muut­tu­vat samassa suhteessa.

Jos syvyys­suun­taa z kasva­te­taan mieli­val­tai­sella arvolla d, myös arvon x’ täytyy kasvaa samassa suhteessa, jotta kolmion kulma pysyy samana. Tästä voimme päätellä, että jos sivun z pituus on yksi, saamme lasket­tua syvyy­sar­von perus­teella leveys­suun­tai­sen etäi­syy­den keski­pis­teestä kerto­malla suhteel­li­sen etäi­syy­den arvolla d. Näppä­rää!

Koska kuvassa 1 näkyvä arvo z ei ole aina pituu­del­taan vält­tä­mättä yksi, meidän on muokat­tava se sellai­seksi. Olkoon olemassa S, joka kerrot­tuna sivun z pituu­della antaa arvon yksi. Koska jo aiemmin esitet­tiin z:n arvo riip­pu­vaksi kulmasta α, voimme ratkaista S:n yhtä­löstä kuvassa 3 esite­tyllä tavalla.

Matemaattinen kaava.
Kuva 3. Sivun z pituutta skaa­laa­van muut­tu­jan S ratkaisu. 

Tämän avulla saamme uudet suhteel­li­set etäi­syy­det keski­pis­teestä vaaka­suun­tai­sille kuva­pis­teille, kuten kuvassa 4 on havain­nol­lis­tettu. Sivun z pituu­deksi muodos­tuu aina yksi. Koska vaaka­suun­tai­set minimi- ja maksi­miar­vot kuvassa 1 olivat välillä [1, 1], voimme sijoit­taa S:n suoraan reuna­pis­tei­siin. Pysty­suun­tai­nen etäi­syys saadaan lasket­tua täysin samalla mene­tel­mällä, mutta α:n paikalla käyte­tään pysty­suun­taista kulmaa.

Kolmio ja matemaattisia merkintöjä.
Kuva 4. Kuva­pis­tei­den suhteel­li­set maksi­mie­täi­syy­det kuvan keski­pis­teestä sovi­tet­tuna norma­li­soi­tuun syvyysarvoon. 

Miten tästä luodaan algoritmi?

Asioi­den esit­tä­mi­sen helpot­ta­mi­seksi koodista on jätet­tävä pois mahdol­li­set kame­ra­vää­ris­ty­mien korjauk­set. Edel­li­sessä artik­ke­lissa kuvatun projek­tio­pis­te­mal­lin neliöi­den proji­sointi tapah­tuu seuraavasti.

Ensiksi laskemme kuva­pis­teen suhteel­li­sen sijain­nin kameran keski­pis­teestä. Syvyys­ka­me­ran toteu­tuk­sesta johtuen oikea keski­piste ei vält­tä­mättä ole kuvan keski­piste. Tämän vuoksi on tiedet­tävä vielä kameran linssin keski­pis­teen sijainti kuvassa. Nämä tiedot saamme onneksi selville Intel Real­sense SDK:n raja­pin­ta­funk­tioi­den avulla rs2_intrinsics-tieto­ra­ken­teesta.

Vektori kuva­pis­teen­Si­jainti on pikse­lin (x,y)-koordinaatti kuvan vasem­masta yläkul­masta katsot­tuna. Syvyy­sarvo syvyys näyt­teis­te­tään tallen­teen video­teks­tuu­rin korkeus­kart­ta­ku­vasta. kame­ran­si­jain­ti­Ku­vassa toimii keski­pis­teenä. Vektori polt­to­Vali sisäl­tää­suh­teel­li­set etäi­syys­ker­toi­met x sekä y kerrot­tuna kuvan levey­den ja korkeu­den puolik­kailla. Tällöin lopul­li­nen sijainti on lasket­ta­vissa suoraan kuva­pis­te­koor­di­naat­tien avulla, eikä muun­nosta suhteel­li­siin koor­di­naat­tei­hin tarvitse välissä tehdä. Listauk­sessa 1 näkyvä pseu­do­koo­din C++-toteutus on tarkas­tel­ta­vissa Intel Real­sense SDK:n funk­tiossa rs2_deproject_pixel_to_point.

float3 piste­pro­jek­tio(   float2 kuva­pis­teen­Si­jainti, float syvyys,

float2 kame­ran­si­jain­ti­Ku­vassa, float2 polttoVali)

{

        float x = (kuvapisteenSijainti.x – kameransijaintiKuvassa.x) / polttoVali.x;

        float y = (kuvapisteenSijainti.y – kameransijaintiKuvassa.y) / polttoVali.y;

        return float3(syvyys* x, syvyys* y, syvyys);

}

Listaus 1. Piste­pil­ven projek­tio­al­go­ritmi pseudokoodina.

Virtu­aa­li­ho­lo­gram­meja varten listauk­sen pseu­do­koodi toteu­tet­tiin Unity-sovel­lus­ke­hit­ti­men GLSL-vertek­si­var­jos­ti­noh­jel­mana, joka suori­te­taan kaikille projek­tio­pis­te­mal­lin neliöi­den vertek­seille. Kameran sijain­ti­tieto sekä polt­to­väli oli helpoin välit­tää uniform-tyyp­pi­sinä vain-luku-muut­tu­jina edito­rista käsin neli­kom­po­nent­ti­vek­to­rissa. Kuva­pis­te­koh­tai­nen syvyys­tieto on näyt­teis­tet­tä­vissä video­teks­tuu­rin korkeus­kart­taa kuvaa­vasta osiosta.

Syvyys­kar­tan ja kameran väri­ku­van kokoe­ro­jen vuoksi varjos­ti­noh­jel­maan toteu­tet­tiin myös koor­di­naat­tien sovitus kuvien kesken, jolloin samat suhteel­li­set koor­di­naa­tit toimi­vat molem­mille kuva­tyy­peille. Toteu­tuk­sen tarkempi läpi­käynti jäte­tään tois­tai­seksi väliin sen varsin tekni­sen luon­teen vuoksi.

Yhteen­veto

Tässä artik­ke­lissa on kuvattu piste­pil­vi­pro­jek­tion teke­mi­sen sekä siitä algo­rit­min johta­mi­sen mate­maat­ti­nen tausta. Seuraa­vassa artik­ke­lissa käsi­tel­lään mene­tel­miä piste­pil­ven yhte­näis­tä­mi­seen sekä loppu­tu­losta selkeästi heiken­tä­vien kohtien poisrajaamiseen.


Kirjoit­taja:

Anssi Gröhn, lehtori, Karelia-ammattikorkeakoulua

Base Camp -Opis­ke­li­jay­rit­tä­jyy­sa­lus­to­jen kehit­tä­mi­nen -hanke

Artik­ke­li­kuva: Richard Horvath on Unsplash