dinsdag 17 februari 2009

Roosterbepaling

Ondertussen is er (alweer) wat tijd verstreken, maar ik heb zeker niet stilgezeten, integendeel, ik heb van mijn beperkte aantal examens kunnen profiteren om heel wat aan mijn thesis te werken. Een van mijn belangrijkste progressies is het afwerken van de code om het rooster in een textuur te bepalen. Ik had reeds werkende code hiervoor, maar deze werkte maar op een beperkt aantal texturen. De code die ik nu heb is zeer robuust en werkt op een zeer brede waaier van texturen. Hieronder volgt een beschrijving van de werkwijze die ik hanteer. De belangrijkste aanpassingen zijn gebaseerd op de ondervinding dat een goede preprocessing van de textuur zeer belangrijk is.

De eerste stap, een preprocessing stap, is gebaseerd op het feit dat de lokale intensiteit van een textuur niet overal even groot is. Bij een zo goed als perfecte textuur is dit geen probleem, maar bij een foto van een near-regular texture kan dit wel voor problemen zorgen. Dit kan bv. veroorzaakt zijn door een flash die niet volledig uniform is of door zonlicht. Een oplossing hiervoor is om de intensiteitswaarden van een textuur te delen door de intensiteitswaarden van een circular average filter toegepast op de oorspronkelijke textuur, gevolgd door een normalisatie. Dit wordt hieronder gedemonstreerd.

Textuur: vóór

Circular average filter toegepast op de textuur

Textuur: na deling en normalisatie

Vervolgens worden er enkele kleine aanpassingen gedaan, zoals een constrastverhoging, een inversie van de intensiteitswaarden indien de gemiddelde intensiteitswaarde hoger is dan 0.5 (dit geeft meer uitgesproken pieken bij de autocorrelatie) en nogmaals een circular average filter (ditmaal met een zeer kleine straal) om hoogfrequente ruis te elimineren. Het resultaat is hieronder weergegeven.

Textuur na contrastverhoging, inversie en smoothing

In de volgende preprocessingstap gaan we op zoek naar een gepaste threshold zodat we de textuur kunnen omzetten naar een zwart-wit textuur. Het is namelijk gebleken dat de pieken in de autocorrelatiefunctie hierdoor meer uitgesproken zijn. Een mogelijke thresholdwaarde kan men berekenen door de brightness aan te passen bij een maximaal contrast en de intensiteit te zoeken waarbij relatief het minste aantal pixels veranderen. Dit wordt gedemonstreerd in onderstaande figuur.

Animatie die aangeeft waar een mogelijk optimale threshold ligt

Hierna wordt, zoals in een vorige post reeds vermeld, de autocorrelatie berekend en worden hiervan de pieken gezocht in een 8x8 window. In tegenstelling tot de vorige versie, waarbij de afstand tot de dichtstbijzijnde grotere piek als maat voor een lokale piek werd gebruikt, gebruiken we nu simpelweg de correlatiewaarde als maat wat betere resultaten geeft. We nemen initieel de 7 punten in de autocorrelatiefiguur met de hoogste waarde (1 punt is het middelpunt van de autocorrelatiefiguur, de andere 6 punten liggen ongeveer rond dit middelpunt). Voor elk van deze punten (behalve het middelpunt) wordt gecontroleerd of er in het verlengde van dit punt t.o.v. het middelpunt geen andere punten liggen met een hogere SSDn (sum of squared differences, normalized: een betere maat dan de correlatiemaat, maar rekenintensiever), want dit wijst erop dat de textuur een bijna-regulariteit vertoont, maar er dus geen is.

Autocorrelatiefiguur met het middelpunt in het rood en de 6 punten met hoogste correlatiewaarde in het geel

Textuur waarbij het algoritme oorspronkelijk een verkeerd rooster berekende

Autocorrelatie en de 7 punten met hoogste correlatiewaarde (de twee middelste gele punten zijn fout)

Autocorrelatie met gecorrigeerde punten

Vervolgens worden op deze 7 punten de GHT (general hough transform) toegepast. Indien dit geen resultaat geeft, wordt er iteratief telkens een extra punt genomen tot de GHT wel een resultaat geeft. Zo zijn er voor de eerste textuur 10 punten nodig.

De autocorrelatiefiguur met de 10 punten met hoogste correlatiewaarde die nodig zijn om 2 vectoren te vinden met de GHT

De textuur met het gevonden rooster

Dit algoritme slaagt erin het rooster te vinden van zowat alle testtexturen (ongeveer 200). Een nodige voorwaarde om het rooster te vinden is dat de textuur niet transparant mag zijn, bv. een hek vertoont verschillende gaten waardoor men de achtergrond kan zien. Bij deze texturen slaagt mijn algoritme er meestal nog wel in het rooster te vinden, maar niet altijd. Enkele voorbeelden.

Textuur van een hek waarbij het rooster correct bepaald wordt

Textuur van een hek waarbij het rooster niet correct bepaald wordt

Andere nodige voorwaarden zijn het feit dat de textuur een relatief groot deel van de afbeelding moet bedekken (minstens ongeveer 70%), de textuur niet te onregelmatig mag zijn en er minstens vier tegels aanwezig moeten zijn.

De rekentijd nodig voor het berekenen van het rooster is ongeveer 15 seconden voor een 500x500 afbeelding en na een optimalisatie van de genormaliseerde kruiscorrelatiemethode (normxcorr2) nog 9 seconden.

Geen opmerkingen: