MRBT 2014 Projekt M7: Detekce textur Vedoucí: Aleš Jelínek Vypracoval: Dávid Pacura 136569 UAMT VUT FEKT
Zadanie Naprogramujte jednoduchou 3D scénu s několika otexturovanými tělesy, stačí např. jehlan a krychle. Scénou by mělo jít volně otáčet a pořídit její obraz (screenshot) z libovolné pozice. Ze znalosti tohoto obrazu a geometrie scény (poloha a rozměry těles + poloha pozorovatele) restaurujte textury na viditelných plochách těles. Soustřeďte se na restaurování textur a porovnejte je s původně použitými. Teoretický rozbor Nájdenie textúr na objektoch pri znalosti polohy v priestore je možné vyhľadaním rovín. Z troch bodov je možné spočítať rovnicu roviny. Po dosadení súradníc bodu do rovnice získame číslo, ktoré vyjadruje odchýlku od tejto roviny. V prípade bodu ležiaceho na tejto rovine je táto nulová. Aby bolo možné pracovať nie len s objektmi zloženými z rovín, ale aj s objektami, ktoré sú zakrivené, je nutné nastaviť určitú hranicu odchýlky bodov, ktoré sú ešte považované za súčasť roviny. Nevýhodou je nepresné rekonštruovanie textúry, nakoľko dochádza k zanedbaniu zakrivení. Táto metóda je teda vhodná pre scény obsahujúce objekty s malým zakrivením, s prevahou rovín. Ďalším problémom pri detekcii je perspektíva. Pred priestorovou rotáciou je nutné ju odstrániť. Toto je možné iba pri znalosti vertikálneho uhlu záberu kamery, takzvaného FieldOfView. Okrem tohto údaja je taktiež potrebné poznať šírku, výšku scény a minimálnu a maximálnu možnú hĺbku scény. Z týchto údajov je možné vypočítať inverznú maticu perspektívnej transformácie. Ako posledná vec je potrebné rotovať nájdené plochy tak, aby došlo k vynulovaniu Z súradnice a tým k rekonštrukcii pôvodnej 2D textúry, ktorá bola na danú plochu aplikovaná. Toto je znova možné pomocou výpočtu rovnice roviny pre body, u ktorých už bola odstránená perspektíva. Keďže počet bodov viditeľných pre danú plochu z pohľadu kamery je nutne menší alebo rovný počtu bodov plochy rotovanej kolmo k osy Z, je jasné, že došlo k strate informácií. Túto stratu je možné čiastočne kompenzovať pomocou interpolačných metód. Týmto však dochádza k rozmazaniu obrazu, preto je nutné obraz doostriť, napríklad pomocou dodatočného rozmazania gausovým filtrom a vytvorením ostrého obrázka použitím váženej sumy (substrakciou) na extrahovaný a rozmazaný obrázok. Kvalita rekonštrukcie pôvodnej textúry bude teda závisieť na tvare objektu, na ktorý je aplikovaná a na jeho natočení v priestore. Čím väčší bude rozdiel počtu bodov objektu pri pohľade z kamery a po výslednej rotácii, tým väčšia bude strata informácie. Použitá matematika Nájdenie rovín Detekcia rovín funguje na princípe výpočtu rovnice roviny pomocou troch bodov. Množina bodov v kartézskych súradniciach je získaná z 2D viditeľnej oblasti scény a hĺbky každého rovinného bodu v Z-bufferi. Následne sa pomocou pseudonáhodného generátora vyberá postupne jeden z týchto bodov. Následne sa vezmú dvaja jeho susedia, vzdialený 1 pixel pravý a spodný. Z týchto troch bodov sa vypočíta rovnica priamky. Na poradí týchto bodov nezáleží. Výpočet rovnice roviny: A = (p2.y - p1.y) * (p3.z - p1.z) - (p3.y - p1.y) * (p2.z - p1.z) B = (p2.z - p1.z) * (p3.x - p1.x) - (p3.z - p1.z) * (p2.x - p1.x) C = (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y) D = -(A * p1.x + B * p1.y + C * p1.z)
Rovnica roviny: A * X + B * Y + C * Z + D = 0 Príslušnosť bodu do roviny je možné zistiť dosadením jeho súradníc do uvedenej rovnice. V prípade, že ľavá strana je rôzna od nuly, toto číslo vyjadruje vzdialenosť daného bodu od požadovanej roviny. Toto umožňuje definovať hranicu nelinearity pre príslušnosť bodu k rovine. Výsledná rovina sa získava aplikovaním algoritmu semienkového (Flood-fill) vyplňovania štartujúceho v pôvodnom náhodne zvolenom bode. Algoritmus používa jednu frontu, do ktorej si odkladá nenavštívených susedov aktuálneho bodu (4 okolie ľavý, pravý, horný, dolný) v prípade, že sám patrí do roviny. Bod sa označí ako použitý, aby nedošlo k jeho opakovanému zaradeniu do fronty a presunie sa do množiny bodov danej roviny. Po vyprázdnení zásobníka sa všetky zostávajúce body označia ako nepoužité a začína sa odznova náhodným výberom bodu. Perspektíva Reálny svet je zobrazený v perspektíve. Táto sa preto používa aj v počítačovej grafike. V OpenGL je perspektíva definovaná transformačnou maticou v homogénnych súradniciach a má tvar: Kde: f a 0 0 0 0 f 0 0 0 0 zf + zn 2 zf zn zn zf zn zf 0 0 1 0 f = 1 tan ( FOV 2 ) FOV field of view vertikálny uhol záberu kamery a aspect ratio pomer šírky a výšky záberu kamery zn minimálna hodnota hĺbky scény zf maximálna hodnota hĺbky scény Homogénne súradnice sú v tvare X, Y, Z, W, kde X, Y, Z poznáme a za W sa dosadzuje číslo 1. Výsledné súradnice získame vydelením súradníc získaných po prenásobení transformačnou maticou hodnotou W: X = X W Y = Y W Z = Z W Pre získanie scény bez perspektívy je nutné transformovať všetky viditeľné body pomocou inverznej perspektívnej matice. Táto má tvar:
a f 0 0 0 0 1 f 0 0 0 0 1 0 0 0 zn zf zn + zf 2 zf zn 2 zf + zn Hodnoty Z súradnice však musia byť normalizované na rozsah 0 1. Výsledné body však už nie sú uniformné (nie sú celočíselné a vzdialené o hodnotu 1), ale majú hodnoty obsahujúce desatinné miesta. Na získanie výsledného obrazu je teda nutné použiť niektorú z interpolačných metód. Rotácia Rovinu, ktorá nie je perspektívne skreslená je možné priestorovo rotovať do polohy, kedy je kolmá na os Z. Týmto získavame pôvodnú textúru, ktorá bola na objekt aplikovaná. Na rotáciu sú použité štandardné rotačné matice: R x = R y = R z = 1 0 0 0 cos θ sin θ 0 sin θ cos θ cos θ 0 sin θ 0 1 0 sin θ 0 cos θ cos θ sin θ 0 sinθ cos θ 0 0 0 1 Implementácia Pre implementovanie projektu som zvolil.net framework v4.0 od firmy Microsoft, štandardne bežiaci na platforme Windows XP a novších. Beh pod prostredím Linux je možný s použitím frameworku MONO. Ako implementačný jazyk som použil C#. Scéna je modelovaná s použitím OpenGL pre.net Interop knižnice OpenTK. Na interpoláciu textúr pri rotácii je využitá knižnica OpenCV pre.net Interop knižnice Emgu.CV. Modelovaná scéna má rozlíšenie 800x600 pixelov a obsahuje nasledujúce objekty: Kocka 6 textúrovateľných strán Ihlan 4 textúrovateľné strany Guľa 6 textúr vo formáte.dds, texturované pomocou vertex shadera Scéna je pohyblivá: Zoom kolieskom myši Rotácia ľavým tlačidlom myši a pohybom Posuv pravým tlačidlom myši a pohybom Textúry u kocky a ihlanu je možné meniť výmenou súborov cx.png a cy.jpg u kocky a pz.jpg u ihlanu, kde X je v rozsahu 1-4, Y v rozsahu 5-6 a Z v rozsahu 1-4. Obrázky sú uložené spoločne pri hlavnom súbore aplikácie TextureExtractor.exe. Je nutné, aby ich rozmery bol mocninou čísla 2. Taktiež je vhodné, aby boli oba rozmery rovnaké. Toto však nie je nutné (dôjde k deformácii).
Samotný kód nebudem v tomto dokumente rozoberať, nakoľko tento je okomentovaný a vysvetlený priamo v Solution. Po spustení programu je možné ľubovoľne natočiť, posunúť a priblížiť namodelovanú scénu. Scéna je automaticky otextúrovaná. Samotná extrakcia textúr prebieha stlačením tlačidla Extract. Toto sa nachádza pod modelovanou scénou. Po jeho stlačení sa naplní vedľa umiestnený combobox zoznamom nájdených plôch. Výberom ktorejkoľvek položky sa táto stane aktuálne editovanou. V pictureboxe Extracted je možné vidieť náhľad plochy zo scény, ktorá sa aktuálne edituje. Aktuálne editovaná plocha je automaticky zbavená perspektívy, avšak jej priestorovú rotáciu je nutné vykonať manuálne, nakoľko sa mi nepodarilo implementovať funkčný výpočet potrebných rotačných uhlov. Viditeľnosť textúry je podmienená jej priestorovou rotáciou, nie je teda vždy viditeľná. Je preto nutné zmeniť rotačné uhly, textúra sa následne objaví. V prípade potreby je možné rekonštruovanú textúru ľubovoľne posúvať po osiach X a Y a prípadne zoomovať (štandardne je v minimálnej veľkosti). Takto rekonštruovanú textúru je možné exportovať vo formáte PNG v plnom rozlíšení modelovanej scény 800x600 pixelov. Taktiež je možné načítať si do programu pre porovnanie originálnu textúru, ktorá sa zobrazí nad rekonštruovanou. Táto je základne vo veľkosti vstupného obrázka, tento teda nie je celý viditeľný. Je však možný posun myšou pomocou kliknutia a ťahu. Program ďalej obsahuje možnosť voľby interpolačnej metódy: Lanczos 4 Bilinear Neares area Bicubic Nearest-neighbor Taktiež je voliteľná maximálna odchýlka bodu od roviny. Štandardná hodnota 0 vyjadruje odchýlku, ktorá je pre každú plochu určená parametrom D rovnice roviny.
Nastavenie scény Načítanie textúry na porovnanie Načítaná originálna textúra Nastavenie zoomu Rekonštruovaná textúra Export rekonštruovanej textúry Voľba interpolačnej metódy Voľba hranice Obrázok 1: Aplikácia s rekonštruovanou textúrou Voľba textúry Extrakcia textúr Náhľad textúry v scéne Nastavenie rotácie Nastavenie posuvu Aktuálne uhly natočenia
Experimenty Už z povahy problému je jasné, že rekonštrukcia textúry má význam iba do určitého uhlu natočenia strata informácií musí byť dostatočne malá. Kvalita rekonštrukcie však závisí taktiež na použitej interpolačnej metóde. Pre experimenty som zvolil Lanczos 4 metódu, ktorá dosahuje najlepšie výsledky pri použití Bilinear a Bicubic dochádza k jemnému rozmazaniu celého obrazu, u Nearestneighbor zasa k aliasingu a Nearest area mierne rozmazáva jemné štruktúry. Natočenie približne 20 stupňov Obrázok 2: detegovaná textúra pred rekonštrukciou Na obrázku 2 nie su na prvý pohľad viditeľné žiadne vady. Lepšie prezretie ukáže jemné rozmazanie v ľavej časti..
Obrázok3: detegovaná textúra po rekonštrukcii Obrázok 4: originálna textúra Na obrázkoch 3 a 4 je možné vidieť rekonštruovanú a pôvodnú textúru. Obrázky sa javia takmer identické, mierny rozdiel je viditeľný na nálepke VUT, kde v rekonštruovanom obrázku sú mierne hrubšie línie a rozmazané, avšak stále viditeľné písmo. 20 natočenie je teda možné pokladať za takmer plne rekonštruovateľné.
Natočenie približne 40 stupňov Obrázok 5: detegovaná textúra pred rekonštrukciou Na obrázku 5 je vidieť, že aj keď je natočenie relatívne malé, textúra je skreslená obrázok je v ľavej časti mierne rozmazaný, čo je možné vidieť na pneumatikách a na nálepke VUT - jemné línie, ktoré obsahuje, sú neostré. Dá sa teda predpokladať, že rekonštruovaná textúra bude skreslená ešte výraznejšie.
Obrázok 6: detegovaná textúra po rekonštrukcii Obrázok 7: originálna textúra Na obrázkoch 6 a 7 je možné vidieť rekonštruovanú a pôvodnú textúru. Podľa predpokladu dochádza k skresleniu ľavej polovice textúry, ktorá je relatívne neostrá. Je možné predpokladať, že ďalším doostrovaním by bolo možné dosiahnuť ešte lepšiu rekonštrukciu. 40 natočenie už teda obsahuje nedostatok informácií na rekonštrukciu pôvodnej textúry obsahujúcej jemné detaily. Avšak v prípade získavania hrubej textúry štruktúry povrchu (stena, doska, podlaha) je takýto uhol možné považovať za dostatočný.
Natočenie približne 60 stupňov Obrázok 8: detegovaná textúra pred rekonštrukciou Obrázok 8 je nie len skreslený, ale aj celkovo rozmazaný, kvalita rekonštrukcie nebude vyská.
Obrázok 9: detegovaná textúra po rekonštrukcii Obrázok 10: originálna textúra Na obrázkoch 10 a 11 je možné vidieť rekonštruovanú a pôvodnú textúru. Podľa predpokladu dochádza k celkovému skresleniu rekonštruovanej textúry je neostrá. Na hranách vidno prejavy aliasingu a nálepka VUT je nečitateľná. 60 natočenie už teda neobsahuje dostatok informácií na rekonštrukciu pôvodnej textúry obsahujúcej jemné detaily. Pre vizuálne zhodnotenie o aký objekt sa jedná, je však táto textúra postačujúca.
Natočenie približne 75 stupňov Obrázok 12: detegovaná textúra pred rekonštrukciou Obrázok 12: Objekt na textúre je pod takýmto uhlom ledva rozpoznateľný. Toto je možné očakávať aj u rekonštruovanej textúry.
Obrázok 13: detegovaná textúra po rekonštrukcii Objekt z rekonštruovanej textúry pod uhlo, 75 z obrázku 13 je dobre rozpoznateľný, avšak veľmi skreslený a rozmazaný. Rekonštrukcia pod takýmto uhlom je teda vhodná iba pre presnejšie určenie objektu.
Natočenie približne 45 stupňov v každom smere Obrázok 145: textúra pred rekonštrukciou Skreslenie textúry z obrázku 14 je už výrazné jednotlivé objekty sú ťažko rozpoznateľné, hlavne na vzdialenejšom konci. Rekonštrukcia pravdepodobne umožní aspoň rozpoznanie objektov
Obrázok 15: detegovaná textúra po rekonštrukcii Obrázok 16: originálna textúra Na obrázkoch 15 a 16 je možné vidieť rekonštruovanú a pôvodnú textúru. Strata informácií je výrazná, dochádza k veľkému rozmazaniu vzdialenejšieho konca obrázka a splývaniu detailov. Na rozdiel od nerotovaného obrázku sú však všetky objekty jasne rozpoznateľné. Rekonštrukcia z takýchto uhlov teda už nie je vhodná na získanie pôvodnej textúry, umožňuje však vizuálne rozpoznanie objektov na nej
Záver Rekonštrukcia textúr umožňuje aj pomocou priestorovej rotácie a interpolačných metód priblížiť sa pôvodnej textúre. Kvalita však závisí na veľkosti rotácie je priamo úmerná pomeru pixelov pôvodnej textúry a viditeľnému počtu bodov textúry na objekte pred rotáciou. Textúry, kde tento pomer dosahuje 0,75 a viac je možné považovať za veľmi dobre rekonštruovateľné. V závislosti od povahy textúry je možné získať rekonštruovaný obraz, ktorý je voľným okom neodlíšiteľný od pôvodného. Rozmazanie sa dá takmer úplne odstrániť. Textúry s pomerom 0,5 je možné rekonštruovať do stavu, v ktorom je väčšina objektov na nich rozpoznateľná. Rozmazanie už však nie je úplne odstrániteľné a rekonštruovaný obraz je tak vhodný iba na vizuálnu kontrolu. U textúr s pomerom 0,25 je možné po rekonštrukcii rozpoznať väčšie tvary, avšak rozmazanie už nie je odstrániteľné. Rekonštruovaný obraz je teda vhodný iba pre vizuálnu kontrolu. Pokračovaním tejto práce môže doplnenie automatickej priestorovej rotácie, ktorej podpora je v aplikácii už zabudovaná je potrebný iba výpočet správnych rotačných uhlov. Ďalej je možné zapracovať na odstránení rozmazania.