Categories
Pulssi Älykästä tuotantoa

Open Broadcast System -liitän­näinen Intel Realsense-kameroille

Base Camp – opiske­li­jay­rit­tä­jyy­sa­lus­tojen kehit­tä­minen -hankkeessa on tavoit­teena pilotoida erilaisia etätek­no­lo­gioita mento­roinnin tukena. Tätä silmällä pitäen aiemmin luotu sovellus Intel Realsense -kameroiden video- sekä syvyys­kuvan tallen­ta­miseen muunnetaan Open Broadcast System (OBS)-liitännäiseksi, jolloin tallen­teiden tekeminen yksin­ker­taistuu. Samalla saadaan aikaan mahdol­lisuus livestrii­mauk­selle. Tässä artik­ke­lissa käyn läpi keskei­simpiä osa-alueita OBS-liitän­näisen kehit­tä­mi­sestä ohjel­mis­to­ke­hit­täjän näkökulmasta.

Yleis­katsaus

Liitän­näiset (engl. plugins) ovat ohjel­ma­kir­jastoja, joita käytetään toisten ohjelmien sisällä. Tässä esitelty liitän­näinen mahdol­listaa RGB- ja syvyys­kuvien strii­maa­misen tai tallen­ta­misen OBS-ohjel­malla. Liitän­näisen luominen vaatii jonkin verran ymmär­rystä Intel Realsense SDK:sta, sekä OBS-ohjelman liitän­näisten kehittämisestä.

Kehit­tämäni liitän­näinen koostuu pääosin viidestä tiedostosta.

  • realsense-device.h – alustaa realsense-kameran, ja käynnistää datan tallennuksen
  • obs_frame_processor.h/cpp – kameran tallen­tamien yksit­täisten ruutujen käsit­te­ly­lo­giikka. Suodat­timet ja syvyy­sar­vojen koodaus harmaa­sä­vy­ku­vaksi, RGB- ja syvyys­ku­va­pis­teiden sijoittelu rinnakkain.
  • realsense-d400-plugin.cpp – rekis­teröi liitän­näisen OBS-sovellukseen
  • realsense-d400-source.cpp – kytkee OBS-sovel­luksen liitän­näisen tapah­tu­ma­kutsut aiempiin, määrittää sovel­luksen säätö­arvot ja piirtää kuvapis­te­datan liitän­näisen tekstuuriin.

Liitän­näinen tarvitsee osalta ohjel­mis­to­ke­hykset OBS-ohjel­mis­tolle, sekä Realsense-kameroille.  Molemmat ovat avoimen lähde­koodin ohjel­mistoja, ja niiden asenta­minen on varsin yksin­ker­taista. Liitän­näisen kääntä­minen useam­malle käyttö­jär­jes­tel­mälle vaatii alusta­koh­taiset kehitystyökalut.

Liitän­näisen ohjel­mal­li­sesta toteutuksesta

Liitän­näisen lähde­koo­dissa on monta osaa, jotka kaikki ovat tarpeel­lisia toimin­nal­li­suuden ja sen laajen­ta­misen kannalta. Video­kuvan luominen olemassa olevasta pikse­li­da­tasta on ohjel­moitu olennai­silta osin realsense-d400-source.cpp-tiedoston funktioihin realsense_d400_source_update, realsense_d400_source_tick sekä realsense_d400_source_render. Tarkas­tellaan niiden toimin­nal­li­suutta seuraavaksi.

realsense_d400_source_update luo gs_texture_create-kutsulla sovel­tuvan dynaa­mi­sesti päivi­tet­tävän tekstuurin, jos sitä ei ole vielä luotu. Tekstuu­rilla tarkoi­tetaan näytö­noh­jaimen muistissa olevaa kuvaa. Kameran tuottamat RGB- ja syvyys­kuvat yhdis­tetään vierekkäin. Yksit­täisen kuvan resoluutio on rajattu 848×480 kuvapis­teeseen, joten yhdis­tetyn kuvan viemä tila on 1696×480 kuvapistettä.

Kaikki grafiikan päivit­tä­miseen tai piirtä­miseen liittyvien operaa­tioiden on tapah­duttava obs_enter_graphics() ja obs_leave_graphics() -funktio­kut­sujen sisällä. Silloin OBS-ohjelman abstra­hoima alemman tason grafiik­ka­ra­ja­pinnan piirto­kon­teksti on käytet­tä­vissä. Tämä liittyy grafiik­ka­ra­ja­pin­tojen toteu­tukseen käyttö­jär­jes­tel­missä toimivien ikkunoin­ti­jär­jes­telmien osalta. Yksin­ker­tais­tettuna voimme todeta, että obs_enter_graphics välittää grafiik­ka­ra­ja­pin­nalle viestin “nyt OBS-ohjelman ikkunaan ruvetaan piirtämään”, ja obs_leave_graphics välittää viestin ”nyt OBS-ohjelman ikkunaan piirtä­minen on päättynyt”.

static void realsense_d400_source_update(void *data, obs_data_t *settings)

{

     struct realsense_d400_source *context = reinterpret_cast<realsense_d400_source*>(data);

    obs_enter_graphics();

    if ( context->texture == nullptr )

    {

     …

      context->texture = gs_texture_create( 848*2, 480, GS_RGBA, 1, nullptr, GS_DYNAMIC);

    }

    obs_leave_graphics();

}

realsense_d400_source_tick puolestaan päivittää jokaisen ruudun­päi­vi­tyksen yhtey­dessä video­teks­tuurin keskus­muistiin tallen­ne­tusta kuvada­tasta gs_texture_set_image-funktio­kutsun avulla. frame_processor-olio käsit­telee kamerasta tallen­netut kuvatiedot, ja muodostaa niistä sovel­tuvan esityksen hyödyn­net­tä­väksi tekstuu­rissa. Tässä yhtey­dessä on hyvä muistaa, että koneen väylä­no­peu­della on osittain merki­tystä tekstuurien päivi­tys­no­peuteen, koska tiedon on siirryttävä keskus­muis­tista näytö­noh­jaimen muistiin.

static void realsense_d400_source_tick(void *data, float seconds)

{

  struct realsense_d400_source *context = reinterpret_cast<realsense_d400_source*>(data);

  …

      const uint8_t *tmp = context->frame_processor.tmp_data.data();

      obs_enter_graphics();

      gs_texture_set_image( context->texture,

                            context->frame_processor.tmp_data.data(),

                            848*2*4, false);

       obs_leave_graphics();

  …

}

realsense_d400_source_render –funktio piirtää päivi­tetyn video­teks­tuurin ruudulle. Funktiossa sidotaan tekstuuri muodos­tet­tavaan kuvaan, sekä piirretään tekstuuri ruudulle.

 static void realsense_d400_source_render(void *data, gs_effect_t *effect)

{

  struct realsense_d400_source *context = reinterpret_cast<realsense_d400_source*>(data);

  obs_enter_graphics();

  gs_eparam_t *image = gs_effect_get_param_by_name(effect, ”image”);

  gs_effect_set_texture(image, context->texture);

  gs_draw_sprite(context->texture, 0, context->frame_processor.video_width,

                 context->frame_processor.video_height );

  obs_leave_graphics();

}

Loput liitän­näisen toimin­nal­li­suu­desta liittyvät lähes yksinomaan Intel Realsense SDK:n asetusten säätä­miseen, sekä kamerasta saapuvien kuvien käsit­telyn säikeis­tä­miseen, mutta näiden toiminnan avaaminen on varsi­naisen liitän­näisen tekemisen ulkopuo­lella. Lisätietoja näistä on saata­villa Realsense2 SDK:n koodie­si­mer­keissä.

Liitän­näisen asentaminen

Liitän­näisen asenta­minen vaatii liitän­näisen kirjas­to­tie­doston siirtä­misen OBS-ohjel­miston liitän­näisten hakemistoon realsense2-kirjas­to­tie­doston kanssa. Esimer­kiksi käyttä­mälläni koneella OBS-ohjelma on asennettu hakemistoon C:\Tools\obs-studio, jolloin realsense2.dll ja realsense-d400-plugin.dll kopioidaan hakemistoon C:\Tools\obs-studio\obs-plugins\64bit. Lisäksi liitän­näi­selle tehdään tyhjä lokali­soin­ti­tie­dosto en-US.ini hakemistoon C:\Tools\obs-studio\data\obs-plugins\realsense-d400\locale.

Liitän­näisen käyttöönotto

Mikäli kaikki liitän­näisen tiedostot on asennettu ja Realsense-kamera kytketty koneeseen, OBSissa on mahdol­lista lisätä kuvaläh­teeksi useam­pikin Realsense D400 Input (Kuva 1). Sen jälkeen kuvalähteen asetuk­sista puolestaan on valit­ta­vissa jokin kytke­tyistä kameroista käyttöön (Kuva 2).

OBS-ohjelman näkymä
Kuva 1. OBS-ohjelman näkymä, johon on liitetty neljä kameraa. Kuvat on käännetty 90 astetta vasta­päivään. Kuvaläh­teeksi valitun kameran kuva on koros­tettu punai­sella reunuksella. 
Kameran asetukset
Kuva 2. Valitun kameran asetukset. Tällä hetkellä säädet­tä­vissä on ylä- ja alarajat tallen­net­ta­ville syvyy­sar­voille, sekä syvyys­kuvan arvon suhde reaali­maa­ilmaan (yksi yksikkö vastaa 100 mikro­metriä, eli 0.1 millimetriä).

Liitän­näinen on julkaistu GPLv3-lisens­sillä Github-verkko­pal­veluun. Liitän­näistä hyödyn­netään jatkossa Basecamp-hankkeen etätek­no­lo­gia­ko­kei­luissa, kun inten­sii­vi­val­men­nuk­sista luodaan virtuaalihologrammeja.


Kirjoittaja:

Anssi Gröhn, tieto­jen­kä­sit­telyn lehtori, Basecamp-hankkeen asian­tuntija, Karelia-ammattikorkeakoulu