Nu är arbetet presenterat och den slutgiltiga versionen inskickad. Det var synd att jag inte hann testa klassificeringen av tecken inom arbetet, men tiden var även utan det ganska knapp. Med den extra arbetsinsatsen som hade krävts för att dels genomföra klassificeringen och dels beskriva den i rapporten skulle kvaliteten behövt sjunka rejält om jag skulle haft någon rimlig chans att utföra det i tid, så jag stannade vid hudsegmenteringen vilket kändes logiskt då det varit det jag fokuserat på överlägset mest under arbetet totalt.
Här [PDF] är en länk till själva presentationen (som eventuellt kan verka kryptisk utan medföljande kommentarer..). Jag använde Google Docs för att skapa presentationen, som också klarar av att exportera till Microsofts PowerPoint-format, men eftersom jag inte behövde några rörliga bilder klarade jag mig med PDF. Den slutgiltiga rapporten finns här [PDF].
Tack till min handledare Fredrik Georgsson och ni från (f.d.) Teligent som höll mig sällskap under sommaren!
2008-12-01
2008-11-14
2008-11-10
2008-10-31
Vecka 44
Jag skriver för fullt på rapporten i detta skedet, vilket gör att det inte finns så mycket att skriva om här. Dock har jag några nya bilder från rapporten. Den första demonstrerar konceptet av kopplade komponenter, vilket är ett bra exempel på något som är enkelt nog att beskriva för att ett barn skulle förstå det, men trots det blir ganska komplicerat att implementera från scratch.
Övriga bilder är utvecklingen av en snake, vilka jag skrivit om förut, som bara påverkas av continuity energy, med resultatet att punkterna placerar sig så att vinkeln mellan linjerna till dess grannar blir identisk. Första bilden visar den (slumpvisa) positionen som ormen ursprungligen placeras i, där de röda gradienterna visar grannskapen för de två vita punkterna (motsvarande energigrannskap beräknas för alla punkterna, men hade jag ritat ut alla hade det inte gått att se något alls):
De nya positionerna är de med lägst energivärde i grannskapet, vilket inte överraskande visas i nästa bild, där formen blivit betydligt mer cirkellik:
Den sista bilden visar vad som hänt efter sju uppdateringar, vilket demonstrerar anledningen till att en snake som bara använder kontuitetsenergi är ganska meningslös - den krymper snabbt mot en enda punkt:
När jag beskrev PCA i rapporten hittade jag två missar jag gjort när jag härledde uttrycken för egenvektorerna, vilket var det som orsakade de sporadiska felen som jag beskrev förra veckan. Komiskt nog var slutresultatet korrekt, med undantag för ett teckenfel som uppstod eftersom jag bara beräknade en kvot x/y för att senare beräkna x och y separat. Detta ger inte oväntat samma resultat som -x/-y, vilket jag inte hade tänkt på. Lösningen var ganska enkel och nu fungerar min PCA som den borde.
Nästa vecka är nummer 20. Jag ska göra allt jag kan för att avsluta ihop rapporten, med undantag för försöket att klassificera tecken vilket jag inte hunnit utföra ännu. Under veckan ska jag fatta beslutet om jag ska försöka hinna med det eller inte, men att avsluta rapporten får högre prioritet eftersom klassificeringen till största del är till för att göra presentationen mer intressant (det vore i och för sig också en trevlig avslutning av projektet..). Jag har en vecka till efter nästa vecka innan rapporten behöver lämnas in till kursansvarrig inför presentationstillfället den 28/11, så eventuellt kommer jag utnyttja delar av den också.
Övriga bilder är utvecklingen av en snake, vilka jag skrivit om förut, som bara påverkas av continuity energy, med resultatet att punkterna placerar sig så att vinkeln mellan linjerna till dess grannar blir identisk. Första bilden visar den (slumpvisa) positionen som ormen ursprungligen placeras i, där de röda gradienterna visar grannskapen för de två vita punkterna (motsvarande energigrannskap beräknas för alla punkterna, men hade jag ritat ut alla hade det inte gått att se något alls):
De nya positionerna är de med lägst energivärde i grannskapet, vilket inte överraskande visas i nästa bild, där formen blivit betydligt mer cirkellik:
Den sista bilden visar vad som hänt efter sju uppdateringar, vilket demonstrerar anledningen till att en snake som bara använder kontuitetsenergi är ganska meningslös - den krymper snabbt mot en enda punkt:
När jag beskrev PCA i rapporten hittade jag två missar jag gjort när jag härledde uttrycken för egenvektorerna, vilket var det som orsakade de sporadiska felen som jag beskrev förra veckan. Komiskt nog var slutresultatet korrekt, med undantag för ett teckenfel som uppstod eftersom jag bara beräknade en kvot x/y för att senare beräkna x och y separat. Detta ger inte oväntat samma resultat som -x/-y, vilket jag inte hade tänkt på. Lösningen var ganska enkel och nu fungerar min PCA som den borde.Nästa vecka är nummer 20. Jag ska göra allt jag kan för att avsluta ihop rapporten, med undantag för försöket att klassificera tecken vilket jag inte hunnit utföra ännu. Under veckan ska jag fatta beslutet om jag ska försöka hinna med det eller inte, men att avsluta rapporten får högre prioritet eftersom klassificeringen till största del är till för att göra presentationen mer intressant (det vore i och för sig också en trevlig avslutning av projektet..). Jag har en vecka till efter nästa vecka innan rapporten behöver lämnas in till kursansvarrig inför presentationstillfället den 28/11, så eventuellt kommer jag utnyttja delar av den också.
2008-10-24
Vecka 43
18 veckor har gått och 2 är kvar nu! Tiden går faktiskt snabbt ibland, som under de sista veckorna av ett större projekt.. utöver att beskriva några kvarvarande koncept teoretiskt i rapporten (Morfologi och snakes, för att vara exakt) har jag under veckan också testat hur pass bra hudklassificeringen givet färgmodellen egentligen är. Den här gången tränade jag först hudmodellen under bra ljusförhållanden, sen tog jag några statiska bilder med handgester och segmenterade manuellt (vilket var snabbare än det låter tack vare roipoly i Matlab) ut händerna:
Bakgrunden var sedan helt enkelt den inversa masken (efter en liten dilation för att slippa eventuella missade handpixlar):
Det enda som återstod var nu att faktiskt klassificera alla pixlar i bilden vid olika tröskelvärden för Mahalanobisavstånd som räknades som hud. Resultatet kan plottas i en ROC-kurva där andelen korrekta positiva klassificeringar (hudpixlar som identifieras mot hud) plottas mot andelen falska positiva (bakgrundspixlar som klassificeras som hud):
För alla klassificerare är det en avviktning mellan hur många falska positiva man är villig att leva med, men säkerheten är bättre ju närmare det övre vänstra hörnet linjen går. I detta fallet är den något vilseledande, eftersom jag nämnt tidigare räcker färg i regel inte till för någon säker klassificering. Jag upprepade samma försök med bilden som nedanstående mask segmenterades från:
Bakgrund:
Samt ROC-kurva, som visar aningen andra resultat den här gången:
Linjen lyckas till och med dyka under den streckade diagonalen som svarar mot ren chans vid ett tillfälle, vilket är ganska imponerande. Anledningen till de vitt spridda resultaten var att
formen på handen och därmed det registrerade färgvärdet och utseendet var helt annorlunda än den första bilden, som kraftigt liknade de bildrutor som färgmodellen tränats på.
Jag implementerade också Hotelling-transformen (aka PCA) under veckan, men det är fortfarande något som krånglar. Det jag har hittils är en metod som givet en binär mask bildar en positions- och avståndsoberoende representation, vilket förenklat beskrivit ger resultatet att föremålet roteras längst sin huvudaxel, trycks ihop så att den minsta rektangel som innesluter föremålet blir en kvadrat och skalas om till en bestämd storlek. Så långt är allt väl, men tanken är också att representationen ska vara rotationsinvariant, vilket inte är läget just nu (i vissa vinklar förvrids istället formen). Min gissning är att min egenvektorsberäkning har ett teckenfel eller liknande någonstans som bara uppstår ibland, men förhoppningsvis kan jag fixa det.
Nästa vecka är det inte oväntat en slutspurt som gäller, i form av att försöka få PCA att fungera korrekt, extrahera klassificeringsfeatures och med passande (simpel) metod försöka klassificera några bilder. I rapporten ska jag beskriva min implementation av snakes och PCA, samt strukturera om lite saker (som vanligt).
Bakgrunden var sedan helt enkelt den inversa masken (efter en liten dilation för att slippa eventuella missade handpixlar):
Det enda som återstod var nu att faktiskt klassificera alla pixlar i bilden vid olika tröskelvärden för Mahalanobisavstånd som räknades som hud. Resultatet kan plottas i en ROC-kurva där andelen korrekta positiva klassificeringar (hudpixlar som identifieras mot hud) plottas mot andelen falska positiva (bakgrundspixlar som klassificeras som hud):
För alla klassificerare är det en avviktning mellan hur många falska positiva man är villig att leva med, men säkerheten är bättre ju närmare det övre vänstra hörnet linjen går. I detta fallet är den något vilseledande, eftersom jag nämnt tidigare räcker färg i regel inte till för någon säker klassificering. Jag upprepade samma försök med bilden som nedanstående mask segmenterades från:
Bakgrund:
Samt ROC-kurva, som visar aningen andra resultat den här gången:
Linjen lyckas till och med dyka under den streckade diagonalen som svarar mot ren chans vid ett tillfälle, vilket är ganska imponerande. Anledningen till de vitt spridda resultaten var attformen på handen och därmed det registrerade färgvärdet och utseendet var helt annorlunda än den första bilden, som kraftigt liknade de bildrutor som färgmodellen tränats på.
Jag implementerade också Hotelling-transformen (aka PCA) under veckan, men det är fortfarande något som krånglar. Det jag har hittils är en metod som givet en binär mask bildar en positions- och avståndsoberoende representation, vilket förenklat beskrivit ger resultatet att föremålet roteras längst sin huvudaxel, trycks ihop så att den minsta rektangel som innesluter föremålet blir en kvadrat och skalas om till en bestämd storlek. Så långt är allt väl, men tanken är också att representationen ska vara rotationsinvariant, vilket inte är läget just nu (i vissa vinklar förvrids istället formen). Min gissning är att min egenvektorsberäkning har ett teckenfel eller liknande någonstans som bara uppstår ibland, men förhoppningsvis kan jag fixa det.
Nästa vecka är det inte oväntat en slutspurt som gäller, i form av att försöka få PCA att fungera korrekt, extrahera klassificeringsfeatures och med passande (simpel) metod försöka klassificera några bilder. I rapporten ska jag beskriva min implementation av snakes och PCA, samt strukturera om lite saker (som vanligt).
2008-10-17
Vecka 42
Under veckan har jag beskrivit morfologi i lite större detalj än tidigare i rapporten, mer specifikt färgmorfologi utifrån "pseudo-färg" och delvis vektorsortering. Jag har också tittat lite på features som area, konturlängd och cirkularitet som när de beräknas givet en segmenterad hand förhoppningsvis förmedlar en del information om vad som pågår. En del tid gick också åt för att undersöka PCA (principalkomponentanalys). Jag har beräkningen av egenvärden och -vektorer färdig nu, vilken var oväntat krånglig för de matriser som dyker upp för mig, men jag har inga resultat eller illustrativa bilder hittils.
Nästa vecka är det fortsatt rapportskrivande som gäller, samt att på implementationssidan transformering till att representera händer egenvektorerna som nya axlar och skala om området till standardstorlek. Jag ska också se om jag hinner spela in statisk träningsdata i form av ett antal bokstäver i teckenspråksalfabetet och faktiskt försöka klassificera tecken (!). Denna oväntade utveckling (som var oväntad eftersom jag lagt fokus för examensarbetet på segmenteringen av hud i realistiska ljusmiljöer, vilket visade sig vara svårt) är menad att demonstrera att segmenteringen faktiskt fungerar under vissa förhållanden (som jag kan beskriva och kvantifiera ganska bra) och när den gör det bör det gå att också utvinna information ur bilden.
Nästa vecka är det fortsatt rapportskrivande som gäller, samt att på implementationssidan transformering till att representera händer egenvektorerna som nya axlar och skala om området till standardstorlek. Jag ska också se om jag hinner spela in statisk träningsdata i form av ett antal bokstäver i teckenspråksalfabetet och faktiskt försöka klassificera tecken (!). Denna oväntade utveckling (som var oväntad eftersom jag lagt fokus för examensarbetet på segmenteringen av hud i realistiska ljusmiljöer, vilket visade sig vara svårt) är menad att demonstrera att segmenteringen faktiskt fungerar under vissa förhållanden (som jag kan beskriva och kvantifiera ganska bra) och när den gör det bör det gå att också utvinna information ur bilden.
2008-10-10
Vecka 41
Jag testade att använda mina funktioner för göra att med en tränad färgmodell göra en tröskling vid Mahalanobisavstånd 10 och plocka ut ut färgvärden från den största kopplade komponenten, vilket var (delar av) min hand. Genom en massiv dilation och invertering av masken betecknade jag allt annat i bilden som bakgrund (det fanns inga andra hudområden på bilden). Resultatet av att plotta färgvärdena i RGB-rymden syns nedan, med hudvärden i grönt och bakgrund som röda punkter.
Som det kanske syns är alla färgvärden (både bakgrund och hud) i bilden koncentrerade i en ganska liten del av den totala färgrymden. Nästa bild visar området inom Mahalanobisavstånd 10, alltså de pixlar som skulle klassificeras som hud. Pixlarnas färg är de faktiska RGB-värden som ingår i regionen.
Resultatet ser ganska lovande ut för de gröna färgvärdena (vid avstånd 10 får man ungefär 95%/6% andel sanna positiva och falska positiva klassificeringar), men på grund av metoden jag använde för att plocka fram hudvärdena i första hand är det självklart de med lågt Mahalanobisavstånd inom handen som användes. Även fast alla färgvärden som identifierades som hud faktiskt var det (sanna positiva) så fanns det många fler hudpixlar som inte inkluderades (falska negativa). Nästa steg var att testa vilka slags färgvärden en hand faktiskt innehåller under typiska ljudförhållanden. För att göra detta tog jag en bild med enkel bakgrund, vilket gjorde det relativt enkelt att automatiskt segmentera handen, vilket syns nedan.
I figuren nedan är alla värden markerade i färgrymden.
Det här ger en helt annan bild av vilka färgvärden en hand kan förväntas anta. Det sista uppenbara steget var att ta en bild av bakgrunden utan några hudområden och se hur de förhåller sig till hudvärdena.
Figuren nedan visar färgvärdena från bakgrunden ovan.
Det är intressant dels hur litet område som färgvärdena hamnar inom, men även hur mycket färgerna skiljer sig från vad man intuitivt skulle förväntat sig utifrån den faktiska bilden. Även om det finns blå, röda och vita föremål i bilden fångar denna kameran under dessa förhållanden
färger som alla är beiga med lite variationer i hur ljusa/mörka de är. Den enda uppenbara skillnaden mellan bakgrunden jämfört med hudvärdena är att den inte innehåller lika ljusa punkter, vilket beror på att handen är närmare kamerna och lampan som belyser scenen är just ovanför.
Denna undersökning har visat (ännu en gång) att det inte är tvärenkelt att segmentera utifrån enbart färg, i alla fall med denna kameran och möjligheten att kontrollera belysningen. Det är intressant att min metod med Mahalanobisavstånd och största kopplade komponenten ofta producerar så pass acceptabla resultat trots allt. Ironiskt nog är orsaken till den (begränsade) framgången till stor del att metoderna för att samla in huddata inte får med alla delar av handen.
Om hela handens färgvärden används för att beräkna Mahalanobisavståndets kovariansmatris och medelvektor placeras fördelningen nästan exakt i mitten av färgrymden och ett gigantiskt högt tröskelvärde behövs för att få med mer än en bråkdel av hudpixlarna. Detta gör självklart också att stora delar av bakgrunden felaktigt klassificeras som hud.
Nästa vecka är det som vanligt rapportskrivande som gäller till en början, jag behöver fortfarande dokumentera snakes mer ingående från ett teoretiskt perspektiv och även beskriva min implementation (även om det i dagsläget verkar tvivelaktigt att den kommer bidra något i slutändan) av dom. Delavsnittet om färgmorfologi gapar också tomt. På implementationssidan så är nuvarande planen att testa diverse features (principalkomponentanalys (PCA) står högt på listan) under antagandet att handsegmenteringen är tillräckligt fungerande för att producera något slags användbar data till klassificeringsalgoritmer. Om det faktiskt är fallet eller bara är omotiverad optimism är en öppen fråga hittils, men även om resultatet blir entydigt negativt bör jag ha en ganska bra bild av anledningen till misslyckandet, och isåfall gäller det att knyta ihop det jag har arbetat med hittils och avsluta allt jag påbörjat i rapporten.
Som det kanske syns är alla färgvärden (både bakgrund och hud) i bilden koncentrerade i en ganska liten del av den totala färgrymden. Nästa bild visar området inom Mahalanobisavstånd 10, alltså de pixlar som skulle klassificeras som hud. Pixlarnas färg är de faktiska RGB-värden som ingår i regionen.
Resultatet ser ganska lovande ut för de gröna färgvärdena (vid avstånd 10 får man ungefär 95%/6% andel sanna positiva och falska positiva klassificeringar), men på grund av metoden jag använde för att plocka fram hudvärdena i första hand är det självklart de med lågt Mahalanobisavstånd inom handen som användes. Även fast alla färgvärden som identifierades som hud faktiskt var det (sanna positiva) så fanns det många fler hudpixlar som inte inkluderades (falska negativa). Nästa steg var att testa vilka slags färgvärden en hand faktiskt innehåller under typiska ljudförhållanden. För att göra detta tog jag en bild med enkel bakgrund, vilket gjorde det relativt enkelt att automatiskt segmentera handen, vilket syns nedan.
I figuren nedan är alla värden markerade i färgrymden.
Det här ger en helt annan bild av vilka färgvärden en hand kan förväntas anta. Det sista uppenbara steget var att ta en bild av bakgrunden utan några hudområden och se hur de förhåller sig till hudvärdena.
Figuren nedan visar färgvärdena från bakgrunden ovan.
Det är intressant dels hur litet område som färgvärdena hamnar inom, men även hur mycket färgerna skiljer sig från vad man intuitivt skulle förväntat sig utifrån den faktiska bilden. Även om det finns blå, röda och vita föremål i bilden fångar denna kameran under dessa förhållandenfärger som alla är beiga med lite variationer i hur ljusa/mörka de är. Den enda uppenbara skillnaden mellan bakgrunden jämfört med hudvärdena är att den inte innehåller lika ljusa punkter, vilket beror på att handen är närmare kamerna och lampan som belyser scenen är just ovanför.
Denna undersökning har visat (ännu en gång) att det inte är tvärenkelt att segmentera utifrån enbart färg, i alla fall med denna kameran och möjligheten att kontrollera belysningen. Det är intressant att min metod med Mahalanobisavstånd och största kopplade komponenten ofta producerar så pass acceptabla resultat trots allt. Ironiskt nog är orsaken till den (begränsade) framgången till stor del att metoderna för att samla in huddata inte får med alla delar av handen.
Om hela handens färgvärden används för att beräkna Mahalanobisavståndets kovariansmatris och medelvektor placeras fördelningen nästan exakt i mitten av färgrymden och ett gigantiskt högt tröskelvärde behövs för att få med mer än en bråkdel av hudpixlarna. Detta gör självklart också att stora delar av bakgrunden felaktigt klassificeras som hud.
Nästa vecka är det som vanligt rapportskrivande som gäller till en början, jag behöver fortfarande dokumentera snakes mer ingående från ett teoretiskt perspektiv och även beskriva min implementation (även om det i dagsläget verkar tvivelaktigt att den kommer bidra något i slutändan) av dom. Delavsnittet om färgmorfologi gapar också tomt. På implementationssidan så är nuvarande planen att testa diverse features (principalkomponentanalys (PCA) står högt på listan) under antagandet att handsegmenteringen är tillräckligt fungerande för att producera något slags användbar data till klassificeringsalgoritmer. Om det faktiskt är fallet eller bara är omotiverad optimism är en öppen fråga hittils, men även om resultatet blir entydigt negativt bör jag ha en ganska bra bild av anledningen till misslyckandet, och isåfall gäller det att knyta ihop det jag har arbetat med hittils och avsluta allt jag påbörjat i rapporten.
2008-10-03
Vecka 40
Jag har under veckan skrivit början till en systembeskrivning i rapporten och fyllt ut beskrivningarna av binär och gråskale-morfologi, kopplade komponenter och snakes.
En ganska pinsam bugg med all min spatiella filtrering visade sig först när jag arbetade med väldigt små bilder (8x8 pixlar) till rapporten, men när jag upptäckte den fick jag orsak att skriva en bättre metod för att pad:a bilder innan filtrering som verkar funka bra. Det fick mig i sin tur att gå tillbaks och undersöka färgmodeller och binär morfologi. Till skillnad från på kontoret (där väggarna var för nära hudfärg) har det visat sig att under antagandet att handen är det största hudfärgade objektet går det ofta bra att segmentera enbart med hjälp av färg här hemma. Detta förutsätter en hyfsat välkalibrerad hudmodell (vilket kan utföras en gång och sparas till fil så länge ljusförhållandena inte ändras) och att belysningen på handen är ungefär densamma i det område man rör sig i. Bilden nedan är endast nerskalad.
Nästa bild visar Mahalanobiskartan (där låg intensitet är nära hudfärg).
Genom att tröskla bilden så att värden under 30 blir vita och övriga svarta och sedan göra en ordentlig dilation fick jag resultatet nedan. Några delar av bilden som inte hör till handen var tillräckligt nära i färg för att komma med.
Nu kommer (äntligen) min kopplade komponent-funktion till nytta. Efter en liten modifikation ger den nu också information om de funna komponenterna, vilken man kan använda för att endast behålla den komponenten som har störst area.
Resultatet blir dugligt i många fall, även om delar av formen går förlorad.
Nästa vecka kommer jag undersöka hur hud- och ickehud-pixlar är fördelade i färgrymden för att undersöka hur pass separerbara mängderna är (jag har mina gissningar: nästan inte alls), skriva om snakes och se vilka features man kan använda efter sin hudklassificering för att avgöra vad handen håller på med.
En ganska pinsam bugg med all min spatiella filtrering visade sig först när jag arbetade med väldigt små bilder (8x8 pixlar) till rapporten, men när jag upptäckte den fick jag orsak att skriva en bättre metod för att pad:a bilder innan filtrering som verkar funka bra. Det fick mig i sin tur att gå tillbaks och undersöka färgmodeller och binär morfologi. Till skillnad från på kontoret (där väggarna var för nära hudfärg) har det visat sig att under antagandet att handen är det största hudfärgade objektet går det ofta bra att segmentera enbart med hjälp av färg här hemma. Detta förutsätter en hyfsat välkalibrerad hudmodell (vilket kan utföras en gång och sparas till fil så länge ljusförhållandena inte ändras) och att belysningen på handen är ungefär densamma i det område man rör sig i. Bilden nedan är endast nerskalad.
Nästa bild visar Mahalanobiskartan (där låg intensitet är nära hudfärg).
Genom att tröskla bilden så att värden under 30 blir vita och övriga svarta och sedan göra en ordentlig dilation fick jag resultatet nedan. Några delar av bilden som inte hör till handen var tillräckligt nära i färg för att komma med.
Nu kommer (äntligen) min kopplade komponent-funktion till nytta. Efter en liten modifikation ger den nu också information om de funna komponenterna, vilken man kan använda för att endast behålla den komponenten som har störst area.
Resultatet blir dugligt i många fall, även om delar av formen går förlorad.Nästa vecka kommer jag undersöka hur hud- och ickehud-pixlar är fördelade i färgrymden för att undersöka hur pass separerbara mängderna är (jag har mina gissningar: nästan inte alls), skriva om snakes och se vilka features man kan använda efter sin hudklassificering för att avgöra vad handen håller på med.
2008-09-26
Vecka 39
I början av veckan skrev jag i rapporten om lite metoder inom bildanalys som tröskling, linjär (faltning) och ickelinjära (morfologi) metoder samt snakes. Det finns fortfarande kvar en del detaljer som ska fyllas i tills mitten av nästa vecka då jag ska skicka in en ny version av rapporten till min handledare. Mot slutet av veckan började jag också på en beskrivning av den mjukvara som jag hittils har ur en funktionell synpunkt.
På implementeringssidan ordnade jag kod för att spara en "körning" (alla frames som renderas från programmet startas till att det avslutas) som ett videoklipp i godtyckligt format. Detta är ganska nödvändigt att både kunna läsa från och skriva till videofilmer så fort man börjar vilja göra saker som kan ta flera sekunder per bildruta, eftersom tålamodet lätt tar slut och man har svårt att följa med vad som händer när man inte kan se processen snabbare än vad datorn hinner med att rendera. Jag har också tittat på om det går att använda förväntad position på regionen (inte bara area) för att begränsa region growing-processen och det ser lovande ut.
Eftersom de kvarvarande på företaget kommer byta kontor kommande vecka har jag tagit hem mina saker och kommer resterande tid arbeta hemifrån eller från universitetet. Jag fick låna hem nätverkskameran som jag använder och mina program fungerar nu på min egen dator, så enda potentiella nackdelen med att jobba hemifrån skulle vara om min disciplin inte räcker till.
Nästa vecka kommer jag fylla ut de delar av rapporten som jag börjat på i veckan (främst snakes och morfologi). Jag ska också försöka hålla målet i sikte att med någorlunda precision kunna spåra en hand, oavsett vilka förenklande antaganden eller metoder jag behöver använda. Det är 6 veckor kvar av de ursprungliga 20 nu. Eventuellt har jag täckt tillräckligt mycket mark (nästan uteslutande inom hudsegmentering och implementering av allmänna metoder) med mitt arbete redan nu , men jag skulle väldigt gärna hinna undersöka kvarstående hinder för att klassificera enkla tecken åtminstone översiktligt. Det skulle också göra mina resultat mycket lättare att strukturera och presentera.
På implementeringssidan ordnade jag kod för att spara en "körning" (alla frames som renderas från programmet startas till att det avslutas) som ett videoklipp i godtyckligt format. Detta är ganska nödvändigt att både kunna läsa från och skriva till videofilmer så fort man börjar vilja göra saker som kan ta flera sekunder per bildruta, eftersom tålamodet lätt tar slut och man har svårt att följa med vad som händer när man inte kan se processen snabbare än vad datorn hinner med att rendera. Jag har också tittat på om det går att använda förväntad position på regionen (inte bara area) för att begränsa region growing-processen och det ser lovande ut.
Eftersom de kvarvarande på företaget kommer byta kontor kommande vecka har jag tagit hem mina saker och kommer resterande tid arbeta hemifrån eller från universitetet. Jag fick låna hem nätverkskameran som jag använder och mina program fungerar nu på min egen dator, så enda potentiella nackdelen med att jobba hemifrån skulle vara om min disciplin inte räcker till.
Nästa vecka kommer jag fylla ut de delar av rapporten som jag börjat på i veckan (främst snakes och morfologi). Jag ska också försöka hålla målet i sikte att med någorlunda precision kunna spåra en hand, oavsett vilka förenklande antaganden eller metoder jag behöver använda. Det är 6 veckor kvar av de ursprungliga 20 nu. Eventuellt har jag täckt tillräckligt mycket mark (nästan uteslutande inom hudsegmentering och implementering av allmänna metoder) med mitt arbete redan nu , men jag skulle väldigt gärna hinna undersöka kvarstående hinder för att klassificera enkla tecken åtminstone översiktligt. Det skulle också göra mina resultat mycket lättare att strukturera och presentera.
2008-09-19
Vecka 38
Jag har under veckan förbättrat metoderna för att samla in huddata genom region growing. När bara en uppsättning datapunkter användes blev resultatet ofta väldigt ostabilt eftersom kameran bara fått se handen ur en vinkel. På bilden nedan har jag visat upp handflatan för kameran som samlade in några tusen färgvärden och byggde en hudmodell.
Mahalanobiskartan för modellen visas nedan (mörka områden är nära hud här).
Området på undersidan av handen är skuggbelagt och eftersom hudvärden endast togs från framsidan av handen under direkt belysning ges dom låg hudtillhörighet (ljus färg på bilden). När jag istället lät funktionerna kontinuerligt plocka ut färgvärden som matchade den förväntade arean inom någon procent blev resultatet en snabbt ökande datamängd som sällan plockade ut falska hudvärden. Genom att spara huddata till fil och tillåta programmet att läsa in och utöka den kan man bygga på en databas av hudvärden för olika förhållanden (och i längden olika användare). Bilden nedan visar att alla delar av händerna ges hög hudtillhörighet i en modell byggd på en större mängd huddata (drygt 100 000 vektorer som var och en svarar mot en hudpunkt).
Eftersom flera saker i bakgrunden kan ha samma färg som hudområden löser såklart detta inte hela problemet, men det går nu att automatiskt och snabbt ge programmet mycket stora datamängder utan särskilt begränsande antaganden och att i förväg träna hudmodellen så den finns redo för kommande körningar. Beräkningen av kovariansmatrisen, dess invers och medelvektorn är beroende på datamängdens storlek men behöver bara göras en gång, varefter tiden som krävs för att beräkna Mahalanobisavståndet för en pixel är konstant.
Jag har under veckan också inarbetat rörelse som ett energimått för snakes. Metoden jag använt är MHI (Motion History Images), vilket ger en gråskalebild som den nedan där de rörelse upptäcks blir vita, medan pixlar som haft rörelse i föregående bildrutor "tonar bort".
De tre ledtrådarna som mina snakes just nu söker efter i bilden är respons från färgmodellen, konturer och rörelse. Värdena beräknas normalt i ett litet grannskap kring varje punkt och skalas om till ett [0, 1]-intervall innan de viktas ihop. Eftersom en snake är en energiminimerande spline är det låga värden (mörka områden) som bedöms som hud. Bilden nedan visar Mahalanobiskartan för en bild.
Nästa bild är kontur (via pseudofärg-morfologi som jag nämnt tidigare).
Det var lite problem med sättet jag avgjorde om det fanns rörelse eller inte i en bild, men just nu lagrar jag ett antal tidigare bildrutor och jämför nuvarande bildruta mot dom. Fördelen är att förändringar i kamerans position eller kroppshållning "tonar bort" när rörelsen avstannar, men det finns också nackdelar. Inuti ett föremål som rör sig kommer en given punkt inte uppfattas som att den har förändrats mellan två bildrutor, vilket ofta ger stora "stationära" områden inuti rörliga föremål (som händer), som på bilden nedan.
När dessa viktas ihop blir resultatet som på bilden nedan, vilket alltså visar hur en snake skulle uppfatta bilden ifall grannskapsområdet var hela bilden.
Det finns fortfarande stora hinder till att spåra hudområden i föränderliga ljusmiljöer, eftersom dessa tre mått inte räcker till för att hitta hud och bara hud. Bilden nedan visar energilandskapet när jag rör handen över en bakgrund som tilldelas i princip samma mått på hudgrad som min hand. Detta gör att rörelse inte kan upptäckas där och konturerna är mycket svaga eller obefintliga.
Poängen är alltså att de ledtrådar mitt program använder sig av just nu för att försöka följa händerna (färg, kontur och rörelse) inte kommer vara tillräckliga i en svår och varierande miljö. Det är här som det börjar bli aktuellt att tänka på förenklande antaganden, som att det inte finns några hudfärgade föremål som rör sig utöver händerna, eller till och med att det inte finns hudfärgade föremål utöver händerna alls i bilden. Med det senare antagandet skulle det räcka att använda metoderna för att bygga en hudmodell med region growing och sedan använda Mahalanobiskartan direkt för att klassificera hudområden. Det börjar också bli tid att undersöka lite olika features som kan användas för att givet segmenterade händer avgöra vad de sysselsätter sig med. Nästa vecka ska jag skriva på kapitel av rapporten som börjat halka efter mer och mer och senare under veckan undersöka hur jag enklast kan förenkla inspelningsmiljön.
Mahalanobiskartan för modellen visas nedan (mörka områden är nära hud här).
Området på undersidan av handen är skuggbelagt och eftersom hudvärden endast togs från framsidan av handen under direkt belysning ges dom låg hudtillhörighet (ljus färg på bilden). När jag istället lät funktionerna kontinuerligt plocka ut färgvärden som matchade den förväntade arean inom någon procent blev resultatet en snabbt ökande datamängd som sällan plockade ut falska hudvärden. Genom att spara huddata till fil och tillåta programmet att läsa in och utöka den kan man bygga på en databas av hudvärden för olika förhållanden (och i längden olika användare). Bilden nedan visar att alla delar av händerna ges hög hudtillhörighet i en modell byggd på en större mängd huddata (drygt 100 000 vektorer som var och en svarar mot en hudpunkt).
Eftersom flera saker i bakgrunden kan ha samma färg som hudområden löser såklart detta inte hela problemet, men det går nu att automatiskt och snabbt ge programmet mycket stora datamängder utan särskilt begränsande antaganden och att i förväg träna hudmodellen så den finns redo för kommande körningar. Beräkningen av kovariansmatrisen, dess invers och medelvektorn är beroende på datamängdens storlek men behöver bara göras en gång, varefter tiden som krävs för att beräkna Mahalanobisavståndet för en pixel är konstant.Jag har under veckan också inarbetat rörelse som ett energimått för snakes. Metoden jag använt är MHI (Motion History Images), vilket ger en gråskalebild som den nedan där de rörelse upptäcks blir vita, medan pixlar som haft rörelse i föregående bildrutor "tonar bort".
De tre ledtrådarna som mina snakes just nu söker efter i bilden är respons från färgmodellen, konturer och rörelse. Värdena beräknas normalt i ett litet grannskap kring varje punkt och skalas om till ett [0, 1]-intervall innan de viktas ihop. Eftersom en snake är en energiminimerande spline är det låga värden (mörka områden) som bedöms som hud. Bilden nedan visar Mahalanobiskartan för en bild.
Nästa bild är kontur (via pseudofärg-morfologi som jag nämnt tidigare).
Det var lite problem med sättet jag avgjorde om det fanns rörelse eller inte i en bild, men just nu lagrar jag ett antal tidigare bildrutor och jämför nuvarande bildruta mot dom. Fördelen är att förändringar i kamerans position eller kroppshållning "tonar bort" när rörelsen avstannar, men det finns också nackdelar. Inuti ett föremål som rör sig kommer en given punkt inte uppfattas som att den har förändrats mellan två bildrutor, vilket ofta ger stora "stationära" områden inuti rörliga föremål (som händer), som på bilden nedan.
När dessa viktas ihop blir resultatet som på bilden nedan, vilket alltså visar hur en snake skulle uppfatta bilden ifall grannskapsområdet var hela bilden.
Det finns fortfarande stora hinder till att spåra hudområden i föränderliga ljusmiljöer, eftersom dessa tre mått inte räcker till för att hitta hud och bara hud. Bilden nedan visar energilandskapet när jag rör handen över en bakgrund som tilldelas i princip samma mått på hudgrad som min hand. Detta gör att rörelse inte kan upptäckas där och konturerna är mycket svaga eller obefintliga.
Poängen är alltså att de ledtrådar mitt program använder sig av just nu för att försöka följa händerna (färg, kontur och rörelse) inte kommer vara tillräckliga i en svår och varierande miljö. Det är här som det börjar bli aktuellt att tänka på förenklande antaganden, som att det inte finns några hudfärgade föremål som rör sig utöver händerna, eller till och med att det inte finns hudfärgade föremål utöver händerna alls i bilden. Med det senare antagandet skulle det räcka att använda metoderna för att bygga en hudmodell med region growing och sedan använda Mahalanobiskartan direkt för att klassificera hudområden. Det börjar också bli tid att undersöka lite olika features som kan användas för att givet segmenterade händer avgöra vad de sysselsätter sig med. Nästa vecka ska jag skriva på kapitel av rapporten som börjat halka efter mer och mer och senare under veckan undersöka hur jag enklast kan förenkla inspelningsmiljön.
2008-09-12
Vecka 37
I veckan har jag utökat min region growing-metod så den nu ritar ut en markering där handen antas befinna sig vid kalibrering och även en ellips som svarar mot den förväntade arean. Själva processen sker iterativt med längre och längre accepterade avstånd mellan färgvärden så länge arean på det markerade området är närmare ellipsens area än föregående steg. Detta resulterar i ett antal färgvektorer för de pixlar som tros tillhöra hudområden. Statistiken över hudfärg kan sedan användas i flera olika färgmodeller. Om färgvärdenas medelvektor och kovariansmatris beräknas kan Mahalanobisavståndet beräknas, vilket är likt Euklidiskt avstånd men också tar hänsyn till att de tre färgkanalerna inte är oberoende av varandra.
När en pixel som ligger på kanten till den växande regionen undersöks används just nu bara pixelns egna färgvärde och grannens. En förbättring skulle kunna vara att vikta den tillåtna avvikelsen i färg för att en pixel ska inkluderas med avståndet från ellipsens mittpunkt eller till närmsta pixel på dess kant. Just nu är sådana förbättringar inte särskilt aktuella, eftersom resultatet är en ganska sofistikerad färgmodell, vilket tydligt visar på bristen med färginformation. Bilden nedan visar en inverterad "Mahalanobis-karta", vilket bara är en bild där Mahalanobisavståndet till varje punkt (givet tidigare huddata från region growing-metoden) beräknats och inverterats, så mörka värden svarar mot högt avstånd från hudfärg och ljusa områden är nära hudfärg.
Det är inte svårt att se problemen med bilden, belysningen gör att stora delar av dörren och väggen till stora delar överlappar hudens färgvärden. Detta visar att oavsett hur sofistikerad färgmodell som används så behövs även annan information. Det är där snakes kommer tillbaks in i bilden, eftersom all information som kan beräknas för en viss pixel givet dess grannskap kan matas in som ett nytt energimått i modellen. På bilden nedan söker sig punkterna mot områden som har lågt Mahalanobisavstånd (igen baserat på tidigare skapad hudmodell) och starka kanter (givet av gradientoperation med pseudofärg-morfologi). De försöker också hålla jämna avstånd mellan varandra och bilda mjuka kurvor, vilket är standard.
Ormen kan inte utifrån denna informationen förlitligt fånga och spåra handen. Det finns gott om kanter i bilden utöver handen, och även hudfärgade föremål När jag rörde handen (långsamt) vänsterut i bilden hakade ett antal punkter istället fast i dörrkarmen eftersom den kanten var skarpare och färgen var nära nog.
Den information som behövs är rörelse, t.ex. genom motion history images, vilket är något som jag ska försöka få att fungera nästa vecka. Om handens konturer bara kan hittas en gång kan positionen från föregående bildruta användas för att uppskatta dess förväntade position i nästa bildruta. På grund av detta kan det vara lönsamt att undersöka om det finns smartare sätt att placera ut snakepunkterna initialt (just nu sätter jag dom bara på kanten av samma ellips som i region growing-metoden). Jag kommer troligtvis ägna tid åt att skriva på rapporten också, det finns gott om relativt enkla metoder som jag har använt men inte beskrivit ännu.
När en pixel som ligger på kanten till den växande regionen undersöks används just nu bara pixelns egna färgvärde och grannens. En förbättring skulle kunna vara att vikta den tillåtna avvikelsen i färg för att en pixel ska inkluderas med avståndet från ellipsens mittpunkt eller till närmsta pixel på dess kant. Just nu är sådana förbättringar inte särskilt aktuella, eftersom resultatet är en ganska sofistikerad färgmodell, vilket tydligt visar på bristen med färginformation. Bilden nedan visar en inverterad "Mahalanobis-karta", vilket bara är en bild där Mahalanobisavståndet till varje punkt (givet tidigare huddata från region growing-metoden) beräknats och inverterats, så mörka värden svarar mot högt avstånd från hudfärg och ljusa områden är nära hudfärg.
Det är inte svårt att se problemen med bilden, belysningen gör att stora delar av dörren och väggen till stora delar överlappar hudens färgvärden. Detta visar att oavsett hur sofistikerad färgmodell som används så behövs även annan information. Det är där snakes kommer tillbaks in i bilden, eftersom all information som kan beräknas för en viss pixel givet dess grannskap kan matas in som ett nytt energimått i modellen. På bilden nedan söker sig punkterna mot områden som har lågt Mahalanobisavstånd (igen baserat på tidigare skapad hudmodell) och starka kanter (givet av gradientoperation med pseudofärg-morfologi). De försöker också hålla jämna avstånd mellan varandra och bilda mjuka kurvor, vilket är standard.
Ormen kan inte utifrån denna informationen förlitligt fånga och spåra handen. Det finns gott om kanter i bilden utöver handen, och även hudfärgade föremål När jag rörde handen (långsamt) vänsterut i bilden hakade ett antal punkter istället fast i dörrkarmen eftersom den kanten var skarpare och färgen var nära nog.
Den information som behövs är rörelse, t.ex. genom motion history images, vilket är något som jag ska försöka få att fungera nästa vecka. Om handens konturer bara kan hittas en gång kan positionen från föregående bildruta användas för att uppskatta dess förväntade position i nästa bildruta. På grund av detta kan det vara lönsamt att undersöka om det finns smartare sätt att placera ut snakepunkterna initialt (just nu sätter jag dom bara på kanten av samma ellips som i region growing-metoden). Jag kommer troligtvis ägna tid åt att skriva på rapporten också, det finns gott om relativt enkla metoder som jag har använt men inte beskrivit ännu.
2008-09-05
Vecka 36
Mer än 50% av den planerade tiden för exjobbet har förflutit nu och jag försöker sålla mellan de metoder jag vill undersöka för att välja ut dom som jag förväntar mig kommer ge mest nytta. I syfte att producera en bra kantdetektor som fungerar i låg upplösning och drar nytta av färginformation skrev jag i början av veckan funktioner för gråskalemorfologi. Till skillnad från de tidigare som bara arbetat med formen på binära objekt (svarta eller vita men inget mellanläge) kan de utökade funktionerna behandla bilder i gråskala. Genom att använda samma operator på de tre färgkanalerna i en RGB-bild kan de också användas för en slags "pseudofärg-morfologi", där resultatet är en färgbild. Resultatet är drastiskt när strukturelementet som använts är någorlunda stort eller upplösningen är låg och även smått skrämmande när testbilderna innehåller en person (som mig). På bilden nedan har jag eroderats med en cirkelformat element, vilket gör att ljusa områden "krymper" medan mörka "växer" (eftersom varje pixel tilldelas det lägsta färgvärdet inom elementet).
Nästa bild är en dilation med samma element, vilket omvänt gör att ljusa områden "växer" medan mörka "krymper".
För att visa att mitt vanliga utseende inte är fullt lika skrämmande har nästa bild inte manipulerats alls.
Slutligen kan erosioner och dilationer användas som utgångspunkt för många andra operationer, som på bilden nedan där jag gjort en "öppning", vilket helt enkelt är en erosion följd av en dilation.
Resultatet blir att (ljusa) objekt under strukturelementets storlek raderas från bilden. Det krävs ingen större fantasi för att lista ut att det också går att göra en "stängning" genom en dilation följd av en erosion. Bilden som produceras syns nedan. Om man selektivt tillämpade denna teknik skulle t.ex. ansikten ganska enkelt kunna suddas ut för att förhindra identifiering.
Dessa kan också byggas på vidare, till exempel genom att beräkna tophat som är skillnaden mellan en bild och dess "öppning" och tar bort bakgrunden (originalet med små och ljusa föremål bortplockade genom öppningen) från bilden.
Från början sökte mina gråskalefunktioner efter de lägsta (vid erosion) eller högsta (vid dilation) färgvärdena individuellt i varje kanal, vilket gjorde att resultatet för en viss pixel kunde bli en färgvektor som inte fanns i bilden. Nästa utökning var att söka efter den "lägsta" eller "högsta" vektorn (av tre färgvärden) för varje pixel, vilket kan beräknas på många olika sätt. Jag valde Euklidiskt avstånd (norm) för varje vektor. Detta gav en version av "färgmorfologi", som dock förstärker brus, eftersom slumpvisa förändringar i färgvärden kan orsaka rejält avvikande vektorer, som alltid kommer väljas ut i operationerna. Det har visat sig att färgmorfologi är ett rejält stort område med många olika idéer, särskilt inom kantdetektering, vilket också var mitt syfte med att undersöka metoderna. I nuläget verkar det dock för mig som om att tidsinvesteringen för att undersöka "riktig" färgmorfologi och implementera metoderna är vettigare att lägga på andra saker. Mina "pseudofärg"-metoder fungerar tillräckligt bra för att söka reda på kanter i bilden (som nedan), sen kan jag använda andra tekniker för att använda information baserad på färg, rörelse (och förhoppningsvis textur, mer om det senare) och kombinera resultatet till något som är robust. Så är min tankegång just nu i alla fall.
Kantdetekteringen kan byggas som en morfologisk grundoperation i samma funktion som erosion (minsta värdet) och dilation (högsta värdet) genom att söka rätt på det maximala avståndet mellan två värden, där värden kan vara skalärer som på bilderna här eller vektorer som i de något långsammare och kraftigt brus-höjande färgoperationerna jag skrivit. Med morfologiska kantoperatorer som ger ganska acceptabelt resultat ägnade jag lite tid i slutet av veckan åt att undersöka region growing, vilket är processen att plocka ut en/några pixlar som seed, som sedan kontrollerar enligt något kriteria om deras grannar borde ingå i regionen tills den slutat växa. De kriterier jag använt hittils är likhet med seed-pixlarnas färg och likhet med grannen som ingår i regionens färg. Region growing är ganska enkelt (kan dock ta tid på större bilder) men ger ganska lovande resultat. Nedan är ett exempel när hela handen och inget annat plockats ut genom att jämföra grannarnas färg.
Och på bilden nedan har jämförelsen med seed-pixlarnas färg misslyckats totalt eftersom regionen inte kan växa längre bort utan att passera över områden med "fel" färg (även om exakt samma färgvärden finns lite längre bort från mitten).
Syftet med metoden är för att användaren i kalibreringsfasen ska kunna hålla upp handen framför kameran, som plockar ut färgvärden och bygger en modell för huden. Det optimala vore sedan att under körning spåra handen och periodvis uppdatera färgmodellen så att systemet inte tappar bort handen ens om ljusförhållandena ändras (inom rimliga gränser).
Nästa vecka ska jag implementera några färgmodeller som jag tidigare tittat på för att producera ett mått på hur sannolikt det är att en viss pixel tillhör handen, som Mahalanobisavstånd och en approach där systemet lär sig vilka regler (som exempelvis att R-värdet för en pixel ska vara mellan 50 och 100) som ger högst grad korrekt klassificering av hudpixlar. Måttet på hudsannolikhet för ett färgvärde ska i sin tur in som en av flera energimått som ormen (aktiva konturen) söker sig mot, tillsammans med kantmått och förväntad position på handen (utifrån tidigare känd position och riktningen på handens rörelse). Jag ska också se om det går att använda en kantdetektering för att beräkna ett enkelt texturmått genom antalet pixlar som ingår i en kant i ett litet område eller liknande, eftersom händer verkar innehålla många "kanter".
Nästa bild är en dilation med samma element, vilket omvänt gör att ljusa områden "växer" medan mörka "krymper".
För att visa att mitt vanliga utseende inte är fullt lika skrämmande har nästa bild inte manipulerats alls.
Slutligen kan erosioner och dilationer användas som utgångspunkt för många andra operationer, som på bilden nedan där jag gjort en "öppning", vilket helt enkelt är en erosion följd av en dilation.
Resultatet blir att (ljusa) objekt under strukturelementets storlek raderas från bilden. Det krävs ingen större fantasi för att lista ut att det också går att göra en "stängning" genom en dilation följd av en erosion. Bilden som produceras syns nedan. Om man selektivt tillämpade denna teknik skulle t.ex. ansikten ganska enkelt kunna suddas ut för att förhindra identifiering.
Dessa kan också byggas på vidare, till exempel genom att beräkna tophat som är skillnaden mellan en bild och dess "öppning" och tar bort bakgrunden (originalet med små och ljusa föremål bortplockade genom öppningen) från bilden.Från början sökte mina gråskalefunktioner efter de lägsta (vid erosion) eller högsta (vid dilation) färgvärdena individuellt i varje kanal, vilket gjorde att resultatet för en viss pixel kunde bli en färgvektor som inte fanns i bilden. Nästa utökning var att söka efter den "lägsta" eller "högsta" vektorn (av tre färgvärden) för varje pixel, vilket kan beräknas på många olika sätt. Jag valde Euklidiskt avstånd (norm) för varje vektor. Detta gav en version av "färgmorfologi", som dock förstärker brus, eftersom slumpvisa förändringar i färgvärden kan orsaka rejält avvikande vektorer, som alltid kommer väljas ut i operationerna. Det har visat sig att färgmorfologi är ett rejält stort område med många olika idéer, särskilt inom kantdetektering, vilket också var mitt syfte med att undersöka metoderna. I nuläget verkar det dock för mig som om att tidsinvesteringen för att undersöka "riktig" färgmorfologi och implementera metoderna är vettigare att lägga på andra saker. Mina "pseudofärg"-metoder fungerar tillräckligt bra för att söka reda på kanter i bilden (som nedan), sen kan jag använda andra tekniker för att använda information baserad på färg, rörelse (och förhoppningsvis textur, mer om det senare) och kombinera resultatet till något som är robust. Så är min tankegång just nu i alla fall.
Kantdetekteringen kan byggas som en morfologisk grundoperation i samma funktion som erosion (minsta värdet) och dilation (högsta värdet) genom att söka rätt på det maximala avståndet mellan två värden, där värden kan vara skalärer som på bilderna här eller vektorer som i de något långsammare och kraftigt brus-höjande färgoperationerna jag skrivit. Med morfologiska kantoperatorer som ger ganska acceptabelt resultat ägnade jag lite tid i slutet av veckan åt att undersöka region growing, vilket är processen att plocka ut en/några pixlar som seed, som sedan kontrollerar enligt något kriteria om deras grannar borde ingå i regionen tills den slutat växa. De kriterier jag använt hittils är likhet med seed-pixlarnas färg och likhet med grannen som ingår i regionens färg. Region growing är ganska enkelt (kan dock ta tid på större bilder) men ger ganska lovande resultat. Nedan är ett exempel när hela handen och inget annat plockats ut genom att jämföra grannarnas färg.
Och på bilden nedan har jämförelsen med seed-pixlarnas färg misslyckats totalt eftersom regionen inte kan växa längre bort utan att passera över områden med "fel" färg (även om exakt samma färgvärden finns lite längre bort från mitten).
Syftet med metoden är för att användaren i kalibreringsfasen ska kunna hålla upp handen framför kameran, som plockar ut färgvärden och bygger en modell för huden. Det optimala vore sedan att under körning spåra handen och periodvis uppdatera färgmodellen så att systemet inte tappar bort handen ens om ljusförhållandena ändras (inom rimliga gränser).Nästa vecka ska jag implementera några färgmodeller som jag tidigare tittat på för att producera ett mått på hur sannolikt det är att en viss pixel tillhör handen, som Mahalanobisavstånd och en approach där systemet lär sig vilka regler (som exempelvis att R-värdet för en pixel ska vara mellan 50 och 100) som ger högst grad korrekt klassificering av hudpixlar. Måttet på hudsannolikhet för ett färgvärde ska i sin tur in som en av flera energimått som ormen (aktiva konturen) söker sig mot, tillsammans med kantmått och förväntad position på handen (utifrån tidigare känd position och riktningen på handens rörelse). Jag ska också se om det går att använda en kantdetektering för att beräkna ett enkelt texturmått genom antalet pixlar som ingår i en kant i ett litet område eller liknande, eftersom händer verkar innehålla många "kanter".
2008-08-29
Vecka 35
I veckan har jag till största del programmerat. Jag har äntligen en funktion som räknar kopplade komponenter och tilldelar de färger automatiskt och den fungerar ganska bra, så bilderna nedan är en liten demo. Den första bilden har ett schackmönster där varje ruta (nätt och jämnt) sitter ihop med de andra, vilket betyder att bilden innehåller en enda kopplad komponent och får en grå färg.
Nästa bild är identisk, förutom att en erosion nu har gjort att rutorna nu inte sitter ihop. De är alltså olika kopplade komponenter och får olika färger (men de börjar bli så många att man har svårt att särskilja vissa färger).
Slutligen en riktig bild, där jag med binär thresholding har behållit alla föremål med vissa ljusvärden och sedan "öppnat bilden" (opening) för att bli av med några tusen pixlar som orsakats av brus (som annars skulle räknats som "kopplade komponenter" och tilldelats unika färger).
Arbetet med kopplade komponenter tog oväntat lång tid, men resultatet är väldigt praktiskt i många sammanhang. Exempelvis antar några författare att den största kopplade komponenten i bilden som är hudfärgad är användarens hand/arm, vilket verkar fungera bra.
Den nuvarande tanken för mitt projekt är att mjukvaran först genomgår en kalibreringsfas där användaren håller upp handen framför kameran. Snakes (aktiva konturer) är nuvarande det starkaste hoppet för att kunna följa handens form, men som bilden nedan visar skulle en väldigt enkel lösning vara att indikera ett område där alla pixlar antas vara hud och be användaren att hålla handen innanför.
Oavsett hur färgvärdena plockas ut så används den informationen sen för att uppskatta vilka färgvärden som antas tillhöra hudområden och vilka som inte gör det (färgmodellen tränas/kalibreras). Med hjälp av färginformationen och rörelse i bilden och/eller formen/texturen på objekt spåras sedan handen mellan varje bildruta. Detta har fördelen att området av bilden som behöver genomsökas blir mindre eftersom handen rimligtvis inte bör röra sig alltför långt mellan två bildrutor som kommer med cirka 0.03 sekunders mellanrum. Detta förutsätter dock att programmet hinner med att göra beräkningarna i realtid, eller att det är acceptabelt att köra långsammare (vilket det bör vara om ett existerande videoklipp används).
Det viktigaste som behövs just nu är robust kantdetektering, eftersom det som jag beskrivit vore bättre att inte behöva förlita sig på färginformation för att hitta handen, utan istället semi-automatiskt hitta handen och extrahera den informationen under kalibreringen.
Bilden ovan visar en snake med 25 punkter som knappt syns och förvirrat försöker inhägna inget i allmänhet, men tre av punkterna har ett "energilandskap" utritat kring sig. Varje punkt använder flera olika mått för att bestämma sin nya position men tanken är alltid att minimera energin, där måttet på "energi" är saker som att försöka hålla jämna avstånd till sina grannar, behålla en fin, rund form, söka sig mot ljusa föremål och kanter. Av de fyra måtten jag nyss nämnde visar de färgade områdena de första tre (röd - "ballongenergi", grön - "kontinuititetsenergi", blå - "intensitetsenergi"). De mörkare områdena inom de färgade grannskapen för punkterna visar vars energin är lägst, vilket är vars punkten vill röra sig. Det sista måttet på energi är att söka sig mot kanter, vilket är det viktigaste och något som jag inte har fungerande i alla olika situationer än (närmare bestämt i nerskalade/subsamplade bilder, vilket jag tänkt använda med snakes för att låta dom hierarkiskt söka sig till bättre anpassningar).
Jag har också utökat min faltningsfunktion i veckan för att bland annat hantera kanteffekter bättre genom att reflektera delar av bilden och skapa en större utökad version under operationen. Detta ledde oväntat nog till ett ganska roligt tidsfördriv, eftersom det inte är något som hindrar att man reflekterar 100% av bilden, live.
Min LCD-skärm är större än din (och mer självrefererande).
Det här är en del av ett fönster.
Nu är det vecka 35, vilket betyder att nästa vecka är den tionde och halva tiden för exjobbet är över nu. Det känns som om jag fått mycket gjort, men jag uppskattar att jag inte varit framsynt nog att inse hur mycket arbete vissa saker skulle kräva i förväg. Om jag hade vetat det i förväg är det inte lika säkert att jag kommit igång. Högst på dagsordningen nästa vecka står att ordna kantdetektering som fungerar bra vid låg upplösning, jag har några redan implementerade metoder som kan fungera, annars finns Canny. Utöver det vill jag få gråskalemorfologi att fungera, halvt av samma anledning (kantdetektering) och titta på om varians/standardfördelningen i bilden ger några ledtrådar till vilka områden som innehåller hud. Rapporten börjar hamna bakom det jag faktiskt gjort också, så förr eller senare borde jag gå över till att skriva mer och programmera mindre, men just nu vill jag få mer resultat.
Nästa bild är identisk, förutom att en erosion nu har gjort att rutorna nu inte sitter ihop. De är alltså olika kopplade komponenter och får olika färger (men de börjar bli så många att man har svårt att särskilja vissa färger).
Slutligen en riktig bild, där jag med binär thresholding har behållit alla föremål med vissa ljusvärden och sedan "öppnat bilden" (opening) för att bli av med några tusen pixlar som orsakats av brus (som annars skulle räknats som "kopplade komponenter" och tilldelats unika färger).
Arbetet med kopplade komponenter tog oväntat lång tid, men resultatet är väldigt praktiskt i många sammanhang. Exempelvis antar några författare att den största kopplade komponenten i bilden som är hudfärgad är användarens hand/arm, vilket verkar fungera bra.Den nuvarande tanken för mitt projekt är att mjukvaran först genomgår en kalibreringsfas där användaren håller upp handen framför kameran. Snakes (aktiva konturer) är nuvarande det starkaste hoppet för att kunna följa handens form, men som bilden nedan visar skulle en väldigt enkel lösning vara att indikera ett område där alla pixlar antas vara hud och be användaren att hålla handen innanför.
Det viktigaste som behövs just nu är robust kantdetektering, eftersom det som jag beskrivit vore bättre att inte behöva förlita sig på färginformation för att hitta handen, utan istället semi-automatiskt hitta handen och extrahera den informationen under kalibreringen.
Bilden ovan visar en snake med 25 punkter som knappt syns och förvirrat försöker inhägna inget i allmänhet, men tre av punkterna har ett "energilandskap" utritat kring sig. Varje punkt använder flera olika mått för att bestämma sin nya position men tanken är alltid att minimera energin, där måttet på "energi" är saker som att försöka hålla jämna avstånd till sina grannar, behålla en fin, rund form, söka sig mot ljusa föremål och kanter. Av de fyra måtten jag nyss nämnde visar de färgade områdena de första tre (röd - "ballongenergi", grön - "kontinuititetsenergi", blå - "intensitetsenergi"). De mörkare områdena inom de färgade grannskapen för punkterna visar vars energin är lägst, vilket är vars punkten vill röra sig. Det sista måttet på energi är att söka sig mot kanter, vilket är det viktigaste och något som jag inte har fungerande i alla olika situationer än (närmare bestämt i nerskalade/subsamplade bilder, vilket jag tänkt använda med snakes för att låta dom hierarkiskt söka sig till bättre anpassningar).Jag har också utökat min faltningsfunktion i veckan för att bland annat hantera kanteffekter bättre genom att reflektera delar av bilden och skapa en större utökad version under operationen. Detta ledde oväntat nog till ett ganska roligt tidsfördriv, eftersom det inte är något som hindrar att man reflekterar 100% av bilden, live.
Min LCD-skärm är större än din (och mer självrefererande).
Det här är en del av ett fönster.
Nu är det vecka 35, vilket betyder att nästa vecka är den tionde och halva tiden för exjobbet är över nu. Det känns som om jag fått mycket gjort, men jag uppskattar att jag inte varit framsynt nog att inse hur mycket arbete vissa saker skulle kräva i förväg. Om jag hade vetat det i förväg är det inte lika säkert att jag kommit igång. Högst på dagsordningen nästa vecka står att ordna kantdetektering som fungerar bra vid låg upplösning, jag har några redan implementerade metoder som kan fungera, annars finns Canny. Utöver det vill jag få gråskalemorfologi att fungera, halvt av samma anledning (kantdetektering) och titta på om varians/standardfördelningen i bilden ger några ledtrådar till vilka områden som innehåller hud. Rapporten börjar hamna bakom det jag faktiskt gjort också, så förr eller senare borde jag gå över till att skriva mer och programmera mindre, men just nu vill jag få mer resultat.
Prenumerera på:
Inlägg (Atom)

