maandag 23 maart 2009

Eerste resultaten textuursynthese

Nu het roosterbepalingsalgoritme relatief robuust was en ik een primitief wallpapergroepclassificatiealgoritme had, werd het tijd om te beginnen aan de textuursynthese. Met de informatie die ik uit de eerste twee fases kon halen, was ik in staat bestaande synthesealgoritmes te verbeteren en/of efficiënter te maken.

Het eerste textuursynthesealgoritme is een pixel-based synthesealgoritme van Wei & Levoy. Dit is een zeer eenvoudig, maar ingenieus algoritme dat een nieuwe textuur zal synthetiseren volgens een vooropgestelde grootte, pixel per pixel. Het concept wordt vrij duidelijk uitgelegd aan de hand van de volgende figuur.

Figuur 1: pixel based texture synthesis

Figuur (a) toont de inputtextuur. Daarop zijn verschillende neighbourhoods afgebeeld met een vooraf bepaalde grootte (in dit geval een 5x5 window). Op figuur (b) staat de outputtextuur. Deze wordt geïnitialiseerd zodat er random pixels staan op de randen rechts en onderaan (in feite zorgt men ervoor dat de histogram sterk lijkt op de histogram van de inputtextuur). Voor elke pixel die men wil synthetiseren, gaat men de neighbourhood van de outputtextuur vergelijken met elke mogelijk neighbourhood van de inputtextuur en neemt men diegene die er het sterkst op gelijk (bv. via de SSD). De bijhorende pixel kopieert men dan naar de outputtextuur. Figuur (c) toont de outputtextuur als ongeveer de helft van de pixels reeds gesynthetiseerd is. Figuur (d) toont de volledig gesynthetiseerde textuur.

De resultaten van een dergelijk algoritme zijn in een aantal gevallen aanvaardbaar, maar in de meeste gevallen absoluut niet. Het algoritme scoort vooral goed bij irreguliere texturen. Vanaf het moment er enige regelmaat aanwezig is, faalt het algoritme deze regelmaat te reproduceren in zijn gesynthetiseerde texturen. Enkele resultaten zijn hier te vinden. Het is dus mijn bedoeling dit algoritme zodanig aan te passen dat deze regelmaat wel degelijk terug te vinden is in de outputtextuur.

Een eerste aanpassing aan het algoritme, is een aanpassing die o.a. terug te vinden is in de doctoraatsthesis Sample-Based Texture Synthesis door M. Sabha. Daarin wordt vermeld dat het random initialiseren van de pixels in de outputtextuur geen goed idee is in het geval de inputtextuur een zekere regelmaat vertoont. De nieuwe gesynthetiseerde pixels zullen meestal heel lokaal de inputtextuur benaderen, maar de globale regelmaat niet weergeven. Een grotere neighbourhood nemen helpt in sommige gevallen, maar ook niet altijd. Een beter idee is dan het nemen van een stuk van de inputtextuur (waarvan de dimensies die van de tegelgrootte benaderen, of een veelvoud ervan zijn) en dit stuk te plakken in de linkerbovenhoek van de outputtextuur. De nieuwe gesynthetiseerde pixels zullen nu in de meeste gevallen zowel de lokale structuur van de inputtextuur benaderen, maar ook de globale structuur. Een belangrijke vereiste is wel dat de neighbourhoodgrootte zo moet gekozen zijn dat ze ongeveer de dimensies van de tegelgrootte benadert. Hoe kleiner de dimensies, hoe kleiner de kans dat de globale structuur te zien zal zijn in de outputtextuur.

Figuur 2: textuursynthese met een random geïnitialiseerde output en een waarvan een stuk van de input gekopieerd werd

Een volgende stap is het bepalen van de neighbourhoodgrootte. Het is heel logisch deze even groot te nemen als die van de tegelgrootte. In de meeste gevallen geeft dit correcte resultaten. In sommige gevallen echter niet. Het is namelijk zo dat bv. een 5x5 window in feite slechts ongeveer 3x5 groot is en dus niet de volledige structuur van een tegel omvat. De neighbourhoodgrootte verdubbelen of toch zeker de hoogte verdubbelen biedt een oplossing.

Een laatste aanpassing is om de efficiëntie van het algoritme te verbeteren en in kleine mate ook de kwaliteit van de outputtextuur te verhogen. Als men, zoals in het huidige geval, weet waar men t.o.v. een bepaalde referentiepositie in de inputtextuur pixels aan het synthetiseren is in de outputtextuur, en men daarenboven ook weet wat de tegelgrootte is, kan men de zoekruimte waarbinnen men op zoek gaat naar een gelijkaardige neighbourhood verkleinen. Deze methode wordt verduidelijkt op fig. 3 en 4. Rond elke pixel die in aanmerking komt in de inputtextuur wordt een window gebruikt, in dit geval een 9x9 window, zodat kleine roosterafwijkingen kunnen opgevangen worden.

Figuur 3: de allereerste pixel die moet gesynthetiseerd worden

Figuur 4: de gele vierkanten duiden de pixels aan die in aanmerking komen om op de plaats van de nieuwe pixel te komen

Een aanpassing die zeker ook nog van pas komt, maar die ik nog niet geïmplementeerd heb, is om niet enkel op de roosterpunten (en directe omgeving daarvan) te gaan zoeken naar overeenkomstige pixels, maar ook de symmetrieën van de wallpapergroepen in rekening breng. Dit is in principe niet zo'n grote aanpassing, maar het zal de resultaten slechts weinig beïnvloeden.

Enkele resultaten van het algoritme in huidige toestand zijn hieronder weergegeven.

Figuur 5: inputtextuur (192x192)

Figuur 6: outputtextuur (100x100)

Figuur 7: inputtextuur (247x250)

Figuur 8: outputtextuur (100x100)

Figuur 9: inputtextuur (355x267)

Figuur 10: outputtextuur (140x120)

Zoals reeds te zien op deze figuren, is het duidelijk dat de resultaten voor reguliere texturen zo goed als perfect zijn. Voor near-regular textures zijn de resultaten nogal wisselvallig. Fig.8 toont goede resultaten voor de synthese van fig.7. Fig.6 toont de iets minder geslaagde synthese van fig.5. Hoe minder regulier de texturen, hoe minder de kwaliteit van het resultaat. Het blijkt dat deze methode voor een groot deel texturen wel acceptabele resultaten geeft, maar voor het andere deel soms eerder ruis produceert dan iets anders. De conclusie is dat deze methode te kort schiet als men een zo algemeen mogelijke methode wenst. Ook qua tijd is deze methode niet aan te raden. Ik heb welliswaar geen optimalisaties doorgevoerd (buiten een klein stuk van de code dat ik in C geïmplementeerd heb), maar bv. voor fig.8 mocht ik rond de 15 minuten wachten.

Nu ik reeds geëxperimenteerd heb met de patch based methode van Kwatra, is het duidelijk dat deze methode meer perspectieven biedt. De lokale en globale structuur wordt daarbij eenvoudig in de output gebracht en de snelheid zal veel hoger liggen dan die van de pixel based methode.

Geen opmerkingen: