FACULTEIT INDUSTRIELE INGENIEURSWETENSCHAPPEN TECHNOLOGIECAMPUS DE NAYER
Ontwikkeling van een algoritme om eigen handen te detecteren in eye-tracker beelden
Stijn VINCK
Promotor:
ing. S. De Beugher
Masterproef ingediend tot het behalen van de graad van master of Science in de ¨ wetenschappen: Elektronica-ICT industriele afstudeerrichting ICT
Academiejaar 2014 - 2015
c Copyright KU Leuven
Zonder voorafgaande schriftelijke toestemming van zowel de promotor(en) als de auteur(s) is over¨ nemen, kopieren, gebruiken of realiseren van deze uitgave of gedeelten ervan verboden. Voor aanvragen i.v.m. het overnemen en/of gebruik en/of realisatie van gedeelten uit deze publicatie, kan u zich richten tot KU Leuven Technologiecampus De Nayer, Jan De Nayerlaan 5, B-2860 SintKatelijne-Waver, +32 15 31 69 44 of via e-mail
[email protected]. Voorafgaande schriftelijke toestemming van de promotor(en) is eveneens vereist voor het aanwenden van de in deze masterproef beschreven (originele) methoden, producten, schakelingen en programma’s voor industrieel of commercieel nut en voor de inzending van deze publicatie ter deelname aan wetenschappelijke prijzen of wedstrijden.
FACULTEIT INDUSTRIELE INGENIEURSWETENSCHAPPEN TECHNOLOGIECAMPUS DE NAYER
Ontwikkeling van een algoritme om eigen handen te detecteren in eye-tracker beelden
Stijn VINCK
Promotor:
ing. S. De Beugher
Masterproef ingediend tot het behalen van de graad van master of Science in de ¨ wetenschappen: Elektronica-ICT industriele afstudeerrichting ICT
Academiejaar 2014 - 2015
c Copyright KU Leuven
Zonder voorafgaande schriftelijke toestemming van zowel de promotor(en) als de auteur(s) is over¨ nemen, kopieren, gebruiken of realiseren van deze uitgave of gedeelten ervan verboden. Voor aanvragen i.v.m. het overnemen en/of gebruik en/of realisatie van gedeelten uit deze publicatie, kan u zich richten tot KU Leuven Technologiecampus De Nayer, Jan De Nayerlaan 5, B-2860 SintKatelijne-Waver, +32 15 31 69 44 of via e-mail
[email protected]. Voorafgaande schriftelijke toestemming van de promotor(en) is eveneens vereist voor het aanwenden van de in deze masterproef beschreven (originele) methoden, producten, schakelingen en programma’s voor industrieel of commercieel nut en voor de inzending van deze publicatie ter deelname aan wetenschappelijke prijzen of wedstrijden.
Dankwoord
¨ ingenieurswetenschapDeze masterproef kwam tot stand als besluit van mijn opleiding industriele pen aan de KU Leuven. Graag zou ik enkele mensen willen bedanken. Allereerst zou ik iedereen willen bedanken die deel uitmaakten van mijn opleiding op campus De Nayer. Hiermee heb ik het over de professoren, labobegeleiders en natuurlijk ook mijn medestudenten. Ik heb hier de kans gekregen om een goede theoretische basis op te bouwen en om problemen kritisch op te lossen. Graag zou ik ook mijn promotor Stijn De Beugher willen bedanken. Hij stond steeds klaar om mijn vragen te beantwoorden, testbeelden te maken met de eye-tracker, tekst na te lezen en tips te geven bij het vormen van mijn masterproef. Tenslotte wil ik mijn ouders bedanken voor de kansen die ze mij gegeven hebben om deze studie af te maken en voor het nalezen van mijn tekst.
ix
Abstract
Door het opkomend succes van egocentrische camera’s, zoals de Google Glass, is het interessant om deze beelden hiervan verder te onderzoeken. In deze masterthesis ontwikkelen we een algoritme om onze eigen handen te kunnen detecteren met behulp van beelden afkomstig van de eye-tracker. Dit zou men onder andere kunnen gebruiken binnen de shoppingcontext om te detecteren welke producten de consument vastgrijpt. Uit vorige onderzoeken bleek dat we onze handdetectie kunnen doen aan de hand van twee onderdelen. Vooreerst gaan we een huidsegmentatie doen in drie kleurruimten , namelijk in het RGB-, HSV- en YCbCr-domein. Als resultaat bekomen we een binaire afbeelding. Deze gebruiken we vervolgens in combinatie met onze gaze data om handen te detecteren. We gebruiken de gaze data van een aantal vorige frames om te zoeken naar handen. We zoeken niet enkel op het gazepunt zelf, maar gaan in een gebied hierrond zoeken om onze slaagkans te vergroten. Onze eigen handen bevinden zich zelden boven een bepaalde hoogte in het frame, dus kunnen we een onderscheid maken tussen onze eigen handen en handen van een andere persoon. We bekomen soms foute detecties omdat tijdens de huidsegmentatie objecten met dezelfde kleur als de huidskleur mee worden gesegmenteerd. In meer dan 70% van de gevallen dat er een hand gedetecteerd wordt, kunnen we zeggen dat dit ons eigen hand is. Er blijven echter veel frames over waarop er geen detectie plaatsvindt, dit komt doordat het gazepunt niet altijd in de buurt van onze eigen handen ligt. Na het uitvoeren van dit onderzoek kunnen we concluderen dat ons algoritme voldoende werkt wanneer er een hand in de frame wordt gedetecteerd. Maar we moeten ook rekening houden met het groot aantal frames waar geen hand gedetecteerd wordt, bijvoorbeeld wanneer het gazepunt zich tussen onze beide handen bevindt. Verder onderzoek zal moeten uitzoeken of het mogelijk is om beide handen apart te detecteren en zo de precisie van het algoritme te vergroten.
xi
Abstract
Due to the upcoming success of egocentric camera’s like “Google Glass”, it is a challenge to investigate in the research of applications based on the resulting tracker images. This master thesis elaborates an algorithm to detect a person’s proper hand using the images delivered by an eyetracker. A possible usage of the algorithm is explained in the following example: to truly understand a shopper, you need to see the world as the shopper sees it, therefore this application in combination with an eye-tracker could be used inside a shopping behavior research tool to detect which product a consumer tries to pick from the shelf with his hand. Recent studies have shown that it is possible to detect a person’s hand by means of two different processes. The first process does a skin segmentation on the image in the three different color spaces: the RGB, HSV and YCbCr domain. This results in a binary image. The second process combines the binary image and the gaze data to detect the hand. The gaze data of previous images is used to detect where a possible hand is positioned. The algorithm does not only use the gaze point itself, but also investigates the area around the gaze point to increase the success rate. It also takes into consideration that the own hand position is mostly placed in the lower part of the image. When it detects a hand in the upper part of the image the hand is more likely the hand of another person. When the algorithm detects a hand, then in 70% of all cases this is a correct detection, which is a satisfactory result. Nevertheless the majority of false hand detections are due to faulty skin segmentation: objects with almost the same skin color are detected as a hand. Sometimes the algorithm also fails to detect a hand, although there is actually a hand in the image. This is because the gaze point does not always lies near the hand, i.e. the person probably was not looking at his hand. After elaborating the necessary research and testing the algorithm it can be stated that the algorithm works properly in most cases. But further research and development should be done to eliminate faulty or incorrect detections, e.g. when the gaze point lies between the two hands. Finally, adding an extension to the algorithm allowing it to detect both hands should increasing the overall detection accuracy.
xiii
Short Summary
This thesis explains the development of an algorithm that detects a person his hand with the use of images received from an eye-tracker. The detection consists of two parts. The first part does a skin segmentation resulting in a binary image and the second part does a hand detection using the gaze data and the binary image. The source code is developed in C++ using the OpenCV library for the image manipulations.
Background EAVISE, which stands for Embedded Artificially intelligent VISion Engineering, is a multidisciplinary research group located at Campus De Nayer in Sint-Katelijne-Waver focusing on applications of advanced computer vision and artificial intelligence. The research goal of EAVISE is to apply stateof-the-art computer vision techniques as a solution for industry-specific vision problems. With the advent of wearable camera’s, such as “Google Glass”, there has been an increasing interest in egocentric computer vision. An important part of computer vision is the egocentric gaze. The gaze date is used in combination with a skin segmentation to detect a person his hands in egocentric frames.
Algorithm The input data is mainly delivered in the form of a movie, the graphical function “ffmpeg” is used to break the movie into individual frames. The image processing routines operate only on a n individual image frame, forcing the algorithm to execute on a frame by frame basis. The algorithm consists of two parts.
Skinsegmentation The first part of the algorithm handles the skin segmentation. The algorithm segments skin pixels into 3 color spaces. These 3 color spaces represent the RGB, HSV and YCbCr color space. In the RGB-color space the algorithm uses the red, green and blue channel to segment skin pixels from non-skin pixels. In the HSV-color space it uses only the hue channel for the detection of skin pixels. It should be noted that lots of skin detection algorithms are solely based on this hue channel detection. For excellent skin segmentation the hue channel detection is extremely important. Finally, it only uses the Cb- and the Cr-channels in the YCbCr color space for skin pixel detection. Combining the segmentation result of each pixel in the 3 color spaces creates a binary black and white image. Each possible skin pixel is represented as a white pixel, as shown in figure 1. On this binary image a median blur filter is applied, this leads to a smoother binary image and the filter also removes the remaining black holes in the binary skin image. xv
xvi
Figuur 1: Skinsegmentation in the 3 color spaces
By creating a tunable median blur filter it is now possible to tune the filter between either bad skin segmentation or excessive filter computation, allowing the algorithm to do a fast skin detection or not.
Handdetection In the second part of the algorithm the binary image that is obtained after skin segmentation, is used in combination with the gaze data received from the eye-tracker to detect a hand. The Gaze data contains very much information. The most important data for the algorithm are the main gaze data elements containing the values of the pixels where there exist an eye-fixation and their frame numbers. This data is then stored in a vector. It has been noticed that if a person would like to grab an object with his own hands, the person will first have an eye-fixation on the object. This can be found in the gaze data a few frames before the person actually grabs the object. In the hand detection function the algorithm uses the binary images created after the skin segmentation of previous gaze data frames to detect on or more skin pixels. If the gaze data contains a number of times a skin pixel, as shown in figure 2, it’s likely that the algorithm has detected a hand.
Figuur 2: Gaze data with skin pixels
xvii
Results The result of the algorithm is satisfying. If the algorithm detects the existence of a hand then in approximately 70% of all cases it is really a hand. The remaining 30% are so called “false” detections, mostly due to false skin segmentation as a result of the existence of equivalent colors on the surroundings as shown in figure 2.4. The algorithm also detects a “non-existing” hand in the between of 2 existing hands as shown in figure 4. If there are two hands in a frame, the current algorithm only detects one hand. Another weakness of the algorithm is that it not always segments all the skin pixels, because segmentation results can differ by influence of the light on the skin. This results in a lot of missing hand detections in various frames that obviously contain a hand. Nevertheless, if the algorithm detects a person his hand, it is very likely that it is correct.
Figuur 3: False detection
Figuur 4: Detection between 2 hands
Though the algorithm has some shortcomings, it could easily be modified to achieve better results and detect with a higher accuracy a hand in more frames. The following image shows the final result.
Figuur 5: Detection of a hand
Inhoudsopgave
1 Situering en doelstelling
1
1.1 Situering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.2 Doelstelling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
2 Literatuurstudie
3
2.1 Algoritme om handen te detecteren . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.1.1 Pixelgebaseerde huidsegmentatie . . . . . . . . . . . . . . . . . . . . . . .
3
2.1.2 Handdetectie door middel van objectdetectie
8
. . . . . . . . . . . . . . . . .
2.1.3 Detectie op bewegende beelden . . . . . . . . . . . . . . . . . . . . . . . . 13 2.2 Beelden van de eye-tracker
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3 Conclusie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3 Specificaties + Uitwerking
17
3.1 Huidsegmentatie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.1.1 RGB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.1.2 HSV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.1.3 YCbCr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3.1.4 Samenvoegen van de kleurruimten . . . . . . . . . . . . . . . . . . . . . . . 20 3.1.5 Optimalisatie van de code . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.2 Gaze data
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.2.1 Gaze formaat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.2.2 Verwerken van de gaze data . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.2.3 Eigen handen detecteren . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4 Resultaten
29
4.1 Huidsegmentatie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 4.1.1 RGB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 4.1.2 HSV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.1.3 YCbCr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4.1.4 Samenvoegen van kleurruimten . . . . . . . . . . . . . . . . . . . . . . . . 31 4.2 Handdetectie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 5 Besluit
37 xix
xx
INHOUDSOPGAVE
5.1 Toekomstig werk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 A Programmacode
41
B Callgraph van kcachegrind
53
Lijst van figuren
1
Skinsegmentation in the 3 color spaces . . . . . . . . . . . . . . . . . . . . . . . . xvi
2
Gaze data with skin pixels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi
3
False detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
4
Detection between 2 hands
5
Detection of a hand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
1.1 Logo van EAVISE
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
2.1 Meest voorkomende kleurwaarden op afbeeldingen volgens Jones and Rehg (2002)
4
2.2 Huid model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.3 Niet-huid model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.4 Verschil tussen huidskleur en bureau (Li and Kitani (2013)) . . . . . . . . . . . . . .
4
2.5 Algoritme voor huidsegmentatie via RGB-H-CbCr model volgens Dawod et al. (2010)
5
2.6 Genormaliseerde hue waarden voor huid-pixels (Dawod et al. (2010)) . . . . . . . .
6
2.7 Dilatatie van een binaire afbeelding . . . . . . . . . . . . . . . . . . . . . . . . . .
7
2.8 Lokale extrema in een bepaalde schaal (Lowe (1999)) . . . . . . . . . . . . . . . .
8
2.9 SIFT descriptor (Lowe (1999)) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
2.10 Box-types gebruikt door SURF (Bay et al. (2006)) . . . . . . . . . . . . . . . . . . .
9
¨ van de orientatie ¨ 2.11 De histogrammen van de gradient voor 4 richtingen (links) , 8 richtingen (midden) of 16 richtingen (rechts) (Suard et al. (2006)) . . . . . . . . . . . . . 10 2.12 Voorbeeld van een C-HOG descriptor . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.13 Cirkel van 16 pixels voor hoekdetectie . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.14 Voorbeeld van een hand in voorgrond . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.15 Voorbeeld van een mobiele eye-tracker . . . . . . . . . . . . . . . . . . . . . . . . 14 2.16 Gazepunt op eigen handen (Li et al. (2013)) . . . . . . . . . . . . . . . . . . . . . . 15 3.1 Vorm 1 van open hand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.2 Vorm 2 van open hand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.3 Origineel frame in het RGB-domein . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.4 Frame in het HSV-domein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.5 Frame in het YCbCr-domein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.6 Frame in RGB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.7 Huidpixels in het RGB-domein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 xxi
xxii
LIJST VAN FIGUREN
3.8 Frame in HSV
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.9 Huid-pixels in HSV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.10 Frame in YCbCr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3.11 Huid-pixels in YCbCr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3.12 Huidsegmentatie door samenvoeging van RGB, HSV en YCbCr kleurruimte . . . . . 20 3.13 Blur met graad 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.14 Blur met graad 25
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.15 Origineel frame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.16 Huidsegmentatie rondom het gazepunt . . . . . . . . . . . . . . . . . . . . . . . . 23 3.17 Schema van de code door kcachegrind . . . . . . . . . . . . . . . . . . . . . . . . 24 3.18 Gazepunt op beker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.19 Hand gaat naar beker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.20 Vierkant van 30pixels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.21 Vierkant van 80pixels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.22 Hand blijft onderaan in beeld . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.23 Hand blijft onderaan in beeld . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.24 Detectie van eigen hand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 3.25 Detectie van iemand anders hand . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 4.1 Origineel frame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.2 Huidpixels in het RGB-domein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.3 Origineel frame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.4 Huidpixels in het RGB-domein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.5 Frame in het HSV-domein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.6 Huid-pixels in het HSV-domein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.7 Frame in het HSV-domein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.8 Huid-pixels in het HSV-domein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.9 Frame in het YCbCr-domein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4.10 Huid-pixels in het YCbCr-domein . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4.11 Origineel frame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4.12 Samenvoeging van 3 kleurruimten . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4.13 Huidsegmentatie met een blurfilter . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 4.14 Juiste detectie van een hand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.15 Valse detectie van een hand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.16 Handdetectie tussen 2 handen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 B.1 Main en huiddetectie functie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 B.2 Main en handdetectie functie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Lijst van tabellen
3.1 Tijdverschillen met verschillende resoluties . . . . . . . . . . . . . . . . . . . . . . 22 3.2 Tijdverschillen met verschillende frames per seconde . . . . . . . . . . . . . . . . . 22 4.1 Aantal frames met mogelijke handdetectie
. . . . . . . . . . . . . . . . . . . . . . 32
4.2 Precisie en recall waarden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.3 Aantal gedetecteerde handen met variabele grootte vierkant en aantal huid-pixels . . 34
xxiii
Lijst van acroniemen
Acroniemen RGB HSV YC B C R POI
Red, Green, Blue Hue, Saturation, Value Y=luminantie, Cb,Cr= kleurcomponenten Point-Of-Interest
xxv
1
Situering en doelstelling
1.1
Situering
Figuur 1.1: Logo van EAVISE
EAVISE (Embedded Artificially intelligent VISion Engineering) is een onderzoeksgroep op de campus De Nayer in Sint-Katelijne-Waver en zoek onder andere uit om met behulp van de eye-tracker onze eigen handen te kunnen detecteren. Deze masterproef schrijven we als eindwerk voor mijn ¨ wetenschappen elektronica ICT aan de KU Leuven campus De Nayer en hanopleiding industriele delt over het computer vision onderdeel van de onderzoeksgroep EAVISE.
1
2
1.2
1 Situering en doelstelling
Doelstelling
Door het opkomend gebruik van draagbare camera’s, zoals Google Glass, is de interesse in egocentrische beeldverwerking gegroeid. In deze masterproef is ons doel het ontwikkelen van een algoritme om eigen handen te kunnen detecteren met behulp van beelden die afkomstig zijn van de eye-tracker. Dit algoritme zou kan gebruikt worden bij de ontwikkeling van een marketingstrategie. Binnen de shoppingcontext zou men kunnen detecteren welke producten de klant bekijkt en nadien dan ook vastgrijpt. Men zou dit ook in het vakgebied van de taalkunde en communicatie kunnen gebruiken om te zien wat we met onze handen doen in een conversatie met andere mensen.
2
Literatuurstudie
Onze literatuurstudie bestaat uit twee delen. Sectie 2.1 handelt over het algoritme dat we gaan ontwikkelen om onze eigen handen te kunnen detecteren via beelden. Dit algoritme hebben we gebaseerd op de paper van Li and Kitani (2013). Dit algoritme wordt opgesplitst in drie delen, namelijk de pixel-gebaseerde huidsegmentatie, de handdetectie door middel van objectdetectie en de detectie op bewegende beelden. Deze laatste onderzoeken we omdat de eye-tracker een egocentrische camera is en op het hoofd wordt geplaatst. Hierdoor is het moeilijk om een verschil te detecteren tussen wat er op de voorgrond gebeurt en wat op de achtergrond. In sectie 2.2 bespreken we de beelden die afkomstig zijn van de eye-tracker en welke informatie we hieruit kunnen halen.
2.1 2.1.1
Algoritme om handen te detecteren Pixelgebaseerde huidsegmentatie
Er zijn verschillende manieren om onze huid te kunnen detecteren, maar de meest gebruikte is die op basis van de kleur van onze huid zelf. We werken pixelgebaseerd en hierdoor kan men elke pixel gaan onderverdelen in een huid-pixel of een niet-huid-pixel zonder invloed te hebben van de pixels ernaast. Een eerste methode die we bekeken hebben met betrekking tot pixelgebaseerde huidsegmentatie is de methode van Jones and Rehg (2002). Hun dataset bestond uit afbeeldingen afkomstig van het internet. Van deze afbeeldingen hebben ze een globaal kleurmodel gemaakt om te zien welke kleuren het meeste voor komen. Hierdoor kwam men tot de conclusie dat de meeste kleuren zich op de grijze lijn, de lijn die zwart en wit verbindt in het RGB-domein, bevinden. Zie figuur 2.1. Wit en zwart zijn de meest gebruikte kleuren en er is eerder een lichte helling richting rood dan richting blauw. Nadien hebben ze een model toegevoegd dat huid en niet-huid afbeeldingen onderscheidt van elkaar. Ze hebben al de afbeeldingen die huid bevatten manueel gelabeld en in een huid histogram 3
4
2 Literatuurstudie
Figuur 2.1: Meest voorkomende kleurwaarden op afbeeldingen volgens Jones and Rehg (2002)
gestoken. De andere afbeeldingen die geen huid bevatten werden ook gelabeld en in een niet-huid histogram onderverdeeld. Uit deze histogrammen kan men dan de kans berekenen of we al dan niet met een huid-pixel te maken hebben.
Figuur 2.2: Huid model
Figuur 2.3: Niet-huid model
Op de histogrammen, zie figuur 2.2 en 2.3, kunnen we duidelijk zien dat de niet-huid afbeeldingen zich vooral bevinden langs de grijze lijn en dat de huid afbeeldingen zich eerder richting rood bevinden boven de grijze lijn. Deze hellingen naar het rood zijn de zogenoemde huid-pixels. Zie figuur 2.2. Deze methode houdt zich dus enkel bezig in de RGB-kleurruimte waardoor er ook foute huid-pixels gedetecteerd kunnen worden. Bijvoorbeeld een bureau die ongeveer dezelfde kleur heeft als blanke huid zou men kunnen detecteren als huid. Zie figuur 2.4.
Figuur 2.4: Verschil tussen huidskleur en bureau (Li and Kitani (2013))
2 Literatuurstudie
5
Een andere methode die we bestudeerd hebben om de huid te detecteren is via het RGB-H-CbCr model van Dawod et al. (2010). Zij bekijken de beelden in drie verschillende kleurruimtes. Zij beginnen in het RGB-domein. Later worden ze omgezet naar het HSV-domein en ook naar YUVdomein (of YCbCr-domein). In elke kleurruimte zijn er waarden gedetecteerd die beslissen of een pixel huid of niet-huid is. In hun resultaat segmenteren ze de huid pixels nadat ze de drie kleurruimten samenvoegden. Op deze segmentatie voeren ze nog morfologische operaties uit zodat ze een duidelijker eindresultaat verkrijgen. Deze methode is ontwikkeld voor gezichtsdetectie, daarom gebruiken ze ook region labeling om gezichtskenmerken te onderscheiden. Aangezien we in ons onderzoek enkel onze eigen handen zullen detecteren, moeten we region labeling niet toepassen. Zie figuur 2.5.
Figuur 2.5: Algoritme voor huidsegmentatie via RGB-H-CbCr model volgens Dawod et al. (2010)
De eerste kleurruimte die ze gebruikten voor hun beelden is het RGB-domein. Hierin hebben we drie vlakken die voorstellen hoeveel rood (R), groen (G) of blauw (B) er in een pixel van een afbeelding zit. Elke pixel is een combinatie van deze 3 vlakken en heeft telkens een waarde van 0 ´ van de RGB kanalen. In het RGB-domein hanteerden ze de waarden van Kovac tot 255 in e´ en et al. (2003), die ze als resultaat bekwamen in hun onderzoek naar detectie van huidskleur. Zij ´ ontwikkelden twee regels die moesten gelden voor de detectie van de huidskleur. Namelijk e´ en voor de huid onder invloed van daglicht en een andere voor als de huid onder invloed is van licht van een flash of fel licht. De twee regels zijn als volgt: Regel 1: onder invloed van daglicht
(R > 95) AND (G > 40) AND (B > 20) AND (max[R, G, B] − min[R, G, B] > 15) AND (|R − G| ≤ 15) AND (R > G) AND (R > B)
(2.1)
Regel 2: onder invloed van fel licht
(R > 220) AND (G > 210) AND (B > 170) AND (|R − G| ≤ 15) AND (R > B) AND (G > B)
(2.2)
Logischerwijs kunnen deze regels nooit op hetzelfde moment voor komen en gaan ze deze regels als een logische OR gebruiken. Kovac et al. (2003) gebruikten dus in het RGB-gebied regel 2.1 of regel 2.2.
6
2 Literatuurstudie
De tweede kleurruimte waarin ze werkten is het HSV-gebied, dat bestaat uit 3 vlakken. Het eerste vlak is de hue (of tint), dit is wat we eigenlijk de kleur noemen. Het tweede vlak is de saturatie, dit geeft de felheid van een kleur aan. Het laatste vlak is de value (of intensiteit), deze geeft de lichtheid van de kleur aan. In het HSV-gebied is enkel het H-vlak belangrijk voor de huidsegmentatie. Men kan niet-huid-pixels makkelijk onderscheiden van huid-pixels want deze liggen namelijk in het gebied tussen 25 en 230 op een histogram van de hue waarde van de pixel. Dit kan men zien in het histogram van figuur 2.6.
Figuur 2.6: Genormaliseerde hue waarden voor huid-pixels (Dawod et al. (2010))
Dawod et al. (2010) gebruikten volgende twee regels om huid te detecteren in het HSV-domein:
H < 25
(2.3)
H > 230
(2.4)
De regels 2.3 en 2.4 kunnen dus niet samen gebruikt worden. Men zou ook de pixelgebaseerde huidsegmentatie kunnen uitvoeren door enkel in de HSV-kleurruimte te werken, zoals in het werk van Oliveira and Conci (2009). Maar zij ondervonden dat dit niet goed werkt voor alle huidskleuren. Dit zou wel goed werken voor mensen met een lichte huidskleur. Het laatste gebied waarin Dawod et al. (2010) in beslisten of een pixel een huid-pixel is of niet, is de YUV- (of YCbCr-) kleurruimte. De drie vlakken van het YCbCr-domein zijn eigenlijk makkelijk op te delen in twee grote delen. Y staat voor de component die de helderheid weergeeft en Cb en Cr zijn de kleurcomponenten die ze gebruikten in hun algoritme voor huidsegmentatie. Men kan op basis de Cb- en Cr-waarden een huidregio insluiten door het gebruik van volgende vijf regels:
Cr ≤ 1.5862xCb + 20
(2.5)
Cr ≥ 0.3448xCb + 76.2069
(2.6)
Cr ≥ −4.5652xCb + 234, 5652
(2.7)
Cr ≤ −1.15xCb + 301.75
(2.8)
C ≤ −2.2857xCb + 432.85
(2.9)
2 Literatuurstudie
7
De regels 2.5 tot 2.9 moeten allemaal op hetzelfde moment waar zijn, men zou dus een logische AND tussen al deze regels moeten gebruiken om een huid-pixel te kunnen detecteren in de YCbCR-kleurruimte. Uiteindelijk worden de regels van de RGB-, HSV- en YCbCr-kleurruimte samengebracht zodat de huid gedetecteerd kan worden op de beelden. Dus als er in de drie kleurruimtes een huid-pixel gedetecteerd wordt, dan zal het algoritme dit aanduiden.
Als ze de huid-pixels uit de beelden hebben verkregen, passen ze hier morfologische operaties op toe. Dit doen ze zodat de huid-pixels een aaneensluitende regio vormen. De morfologische operatie dilatatie is een mogelijkheid om een beter resultaat te verkrijgen. Dilatatie zorgt voor het opvullen van kleine gaten in een binaire afbeelding, zie figuur 2.7. Maar als deze operatie niet voldoende is, moet men hele vlakken opvullen. Dawod et al. (2010) gebruikten enkel deze simpele dilatatie tijdens hun onderzoek, maar er bestaan ook nog andere morfologische operaties. Erosie bijvoorbeeld is het tegenovergestelde van dilatatie, hierbij worden de ge¨ısoleerde gaten vergroot. Combinaties van deze operaties worden ook gemaakt, namelijk opening en closing. Opening is een erosie gevolgd door een dilatatie, hierdoor worden de nadelige effecten van erosie verminderd. Closing is het omgekeerde proces van opening om de nadelige effecten van dilatatie te verminderen.
Figuur 2.7: Dilatatie van een binaire afbeelding
Als de morfologische operaties uitgevoerd zijn, zouden ze de huid-pixels van de niet-huid-pixels moeten kunnen onderscheiden.
8
2.1.2
2 Literatuurstudie
Handdetectie door middel van objectdetectie
Een hand kan verschillende vormen aannemen. Een hand kan gesloten of open zijn, het kan ook twee vingers opsteken of enkel een duim of ... . Al deze vormen moeten gedetecteerd worden als er door middel van huidsegmentatie nog niet voldoende gesegmenteerd is. Er kan bepaald worden of er een links of rechts hand in het beeld aanwezig is zoals in het onderzoek van Fathi et al. (2011). Zij gebruikten hiervoor objectdetectie. Er zijn verschillende manieren die gebruikt kunnen worden voor objectdetectie. We bespreken hieronder de meest gebruikte handdetectietechnieken zoals SIFT, SURF, HOG en FAST. Deze methoden werden ook in de paper van Li and Kitani (2013) besproken. SIFT Scale Invariant Feature Transform (SIFT) ge¨ıntroduceerd door Lowe (1999, 2004) is een algoritme voor objectdetectie. Maar SIFT is ook een proces om verschillende afbeeldingen van bijvoorbeeld een toren te kunnen samenvoegen voor een grote panorama. Lowe (2004) zijn methode verandert een afbeelding in een verzameling van functievectoren of keypoints, die invariant zijn bij translaties, rotaties en herschalingen. We kunnen het SIFT-algoritme meestal onderverdelen in vier stappen. In de eerste stap worden lokale extrema gezocht met behulp van een Difference of Gaussian (DoG) op de verschillende schalen van de afbeelding. Men gaat een pixel vergelijken met zijn 8 naburige pixels en ook de 9 pixels in de volgende en vorige schaal, zoals men op figuur 2.8 kan zien. Als deze pixel een lokaal extremum is dan is het een mogelijke keypoint.
Figuur 2.8: Lokale extrema in een bepaalde schaal (Lowe (1999))
In de tweede stap worden volgens Lowe (2004) op al deze mogelijke keypoints een threshold toegepast zodat er enkel nog de nuttige keypoints overblijven en de andere worden geweigerd. Er wordt op twee gebieden een threshold toegepast, namelijk op die van het contrast en ook op die van de randen. Bij de threshold voor contrast wordt er een enkel lokale extrema boven de 0,03 bijgehouden en bij de randthreshold al de waarden onder de 10. Nu blijven alleen nog de echte keypoints over. ¨ In de volgende stap gaat men de orientatie toekennen aan elk keypoint zodat er niets verandert bij rotatie van de afbeelding. Dit doet men op basis van de magnitude en de hoek van de vectoren in de pixels.
2 Literatuurstudie
9
Figuur 2.9: SIFT descriptor (Lowe (1999))
In de laatste stap neemt Lowe (2004) rond het keypoint een 16x16 gebied van pixels en herverdeelt dit in een gebied van 4x4 subblokken. In elk subblok zijn er 8 verschillende richtingen naar waar de vector zich kan richten. Deze laatste stap is goed te zien op figuur 2.9. SIFT zou een goede methode zijn om samen met de pixelgebaseerde huidsegmentatie, zoals beschreven in de vorige sectie, te gebruiken voor handdetectie. Samen zouden ze een groter onderscheid maken dan huidsegmentatie alleen, zoals ook Wang and Wang (2008); Fathi et al. (2011); Li and Kitani (2013) concludeerden.
SURF Speeded Up Robust Features (SURF) maakt gebruik van box-types zoals in figuur 2.10. Bay et al. (2006) heeft deze methode bestudeerd. Deze manier van objectdetectie is gebaseerd op SIFT, maar er moeten minder berekeningen uitgevoerd worden en hierdoor werkt het sneller. Deze methode is beter bestand tegen transformaties van objecten en ze geeft sneller resultaten van de berekeningen door benaderingen en optimalisaties.
Figuur 2.10: Box-types gebruikt door SURF (Bay et al. (2006))
De methode is sneller dan SIFT, maar ze zal hierdoor ook wel minder keypoints geven. Een kleiner aantal keypoints levert niet noodzakelijk een slechter resultaat. Omwille van het kleine aantal kunnen er sneller gelijkaardige keypoints op andere afbeeldingen opgespoord worden. Bij handde-
10
2 Literatuurstudie
tectie is het positief dat het aantal keypoints niet te groot is, hierdoor kan er makkelijker en sneller een hand gedetecteerd worden, Bay et al. (2008). HOG Histogram of Oriented Gradients (HOG) is een andere methode voor objectdetectie. Dalal and Triggs (2005) hebben onderzoek gedaan naar deze methode. Het doel van deze methode is het beschrijven van een afbeelding door een groep van lokale histogrammen. Deze histogrammen, ¨ van de orientatie ¨ voorbeeld op figuur 2.11, bevatten de gradient in lokale delen van de afbeelding. ¨ van een beeld is de eerste afgeleide van een beeld. Als men in een beeld overgaat De gradient ¨ weergeven. Dus van een donkere pixel naar een lichtere pixel dan zal deze overgang de gradient ¨ hoe feller de overgang, hoe groter de gradient.
¨ van de orientatie ¨ Figuur 2.11: De histogrammen van de gradient voor 4 richtingen (links) , 8 richtingen (midden) of 16 richtingen (rechts) (Suard et al. (2006))
We kunnen volgens Suard et al. (2006) en Bertozzi et al. (2007) dit HOG-algoritme opdelen in ¨ berekenen voor de afbeelding. Dit doen we door 3 stappen. In de eerste stap gaan we de gradient met een masker over elke pixel in horizontale en verticale richting van de afbeelding te gaan
[−1, 0, 1] and [−1, 0, 1]T
(2.10)
Dit masker zou de beste resultaten geven in detectie van afbeeldingen met mensen Suard et al. (2006); Bertozzi et al. (2007). ¨ Een volgende stap is het maken van een histogram van de orientatie voor elke cel. De cellen kunnen rechthoekig of cirkelvormig zijn en de histogrammen kunnen zich tussen 0 en 180 graden ¨ of deze signed of unsigned is. bevinden of tussen 0 en 360 graden. Dit hangt af van de gradient ¨ beter zou zijn voor de Dalal and Triggs (2005) hebben ondervonden dat een unsigned gradient detectie van mensen. In een laatste stap gaan we de histogrammen moeten normaliseren. Dit komt door de verschillende soorten belichting en andere veranderlijken. Deze normalisatie van de cellen gebeurt lokaal terwijl er ook rekening wordt gehouden met de waarden van de naburige cellen. Deze normalisatie gebeurt dus op een blok van cellen. Er zijn twee soorten blokken: de RHOG blokken (rechthoekig) en de C-HOG blokken (cirkelvormig). Figuur 2.12 toont een voorbeeld van een C-HOG descriptor. In het Dalal and Triggs (2005) onderzoek voor detectie van mensen werd er vooral met R-HOG blokken gewerkt van 3x3 met 6x6 pixel cellen. De R-HOG blokken gelijken sterk op de methode (Scale Invariant Feature Transfrom (SIFT), maar de R-HOG blokken worden berekend op een vaste
2 Literatuurstudie
11
Figuur 2.12: Voorbeeld van een C-HOG descriptor
¨ schaal zonder de orientatie mee te geven. Ze worden samen gebruikt om ruimtelijke info te geven. ¨ SIFT wordt gebruikt op verschillende schalen en hun orientatie wordt wel meegegeven en hun descriptors worden apart gebruikt. HOG is een goede methode om mensen te kunnen detecteren maar voor handdetectie is het geen betere methode dan SIFT of SURF. (Li and Kitani (2013)) FAST Features from accelerated segment test (FAST) is een methode om randen te detecteren en werd onderzocht door Mair et al. (2010). FAST kan gebruikt worden om keypoints uit een afbeelding te halen. Het is een methode die sneller (verwijzing naar de naam FAST) werkt dan SIFT. Het is een goede detector voor real-time video verwerking. FAST gebruikt een cirkel van 16 pixels, zoals op figuur 2.13, om te detecteren of de middelste pixel p een rand is. Zo’n cirkel noemt men een Bresenham cirkel en heeft een straal van 3 pixels. P wordt als een rand gedetecteerd als er een bepaald aantal pixels (N) in de figuur een grotere of kleinere intensiteit hebben als pixel p. N krijgt meestal de waarde 12.
Figuur 2.13: Cirkel van 16 pixels voor hoekdetectie
Hierdoor is het een detector die op hoge snelheid kan werken want het moet enkel maar de intensiteit van de afbeelding in rekening brengen. We kunnen deze detector zijn snelheid nog verhogen door niet al de pixels op de cirkel te moeten onderzoeken maar enkel bijvoorbeeld p te vergelijken met pixel 1, 5, 9 en 13 op de cirkel.
12
2 Literatuurstudie
Uit al deze verschillende methodes van objectdetectie zouden we de best mogelijke methode moeten selecteren. We zouden deze methodes kunnen vergelijken op het gebied van aantal keypoints dat we verkrijgen, de snelheid van de berekeningen,... . Maar in ons onderzoek naar handdetectie is in eerste instantie de vorm van het hand het belangrijkste onderdeel om te detecteren. De vorm van het hand wil dus zeggen dat we de randen moeten kunnen detecteren.
2 Literatuurstudie
2.1.3
13
Detectie op bewegende beelden
Bij het gebruik van een eye-tracker worden er egocentrische beelden verkregen. De eye-tracker wordt op het hoofd geplaatst waardoor deze beelden meestal in beweging zijn. Om hier een detectie van de handen op te kunnen uitvoeren, moet er dus uit deze beelden de voorgrond (onze handen) en de achtergrond (de rest) bepaald kunnen worden. Hiervoor bestaan verschillende methoden. Methode 1 Methode 1 is gebaseerd op de regels van Li and Kitani (2013) en wordt de voorgrond op basis van de huidskleur gesegmenteerd. Deze segmentatie werd al in sectie 2.1.1 besproken. Al de pixels die in een reeks van bijvoorbeeld 15 frames gedetecteerd worden als huid-pixel, zullen dus beschouwd worden als de voorgrond. Als een pixel een grote verandering van waarde krijgt dan zal deze ook als voorgrond beschouwd worden. Al de andere pixels in de frames worden dan als achtergrond bekeken. Zie figuur 2.14.
Figuur 2.14: Voorbeeld van een hand in voorgrond
Methode 2 Een andere manier om voorgrond en achtergrond te onderscheiden van elkaar is gebaseerd op enkele afspraken zoals bij Ren and Gu (2010); Fathi et al. (2011): ¨ 1. We veronderstellen dat de achtergrond statisch is in de coordinaten van de wereld. 2. Alles wat beweegt ten opzichte van de statische achtergrond noemen we voorgrond. 3. Achtergrondvoorwerpen zijn meestal verder weg van de camera dan voorgrondvoorwerpen 4. We nemen aan dat we een grote panorama zouden kunnen maken van al de achtergrondbeelden aan elkaar geplakt.
14
2 Literatuurstudie
De methode voor de onderscheiding tussen voor- en achtergrond gaat als volgt: ze maken eerst een beginnende schatting van wat er achtergrond gaat zijn, dit kunnen ze doen door bijvoorbeeld onderscheid te maken op de huidskleur. Ze maken ook tijdelijke lokale panorama’s van hun schattingen van de achtergronden. Daarna registreren ze elk beeld in zijn eigen lokale achtergrondpanorama. De regio’s die ze niet selecteren in hun achtergrond, zijn dus de voorgrond. In ons onderzoek zouden dit dus onze eigen handen zijn.
2.2
Beelden van de eye-tracker
Een eye-tracker is een toestel dat de oogpositie en de oogbeweging meet. Met deze gegevens kunnen we het punt naar waar men kijkt (Point of Interest, POI) terugvinden. Er bestaan twee soorten eye-trackers, namelijk de remote eye-tracker en de mobiele eye-tracker. Bij een remote eye-tracker wordt een camera naast een montitor geplaatst. Hierdoor heeft de eye-tracker geen contact met de gebruiker en is er geen sprake van fysieke storingen. Een mobiele eye-tracker bestaat uit een brilmontuur met twee camera’s, zie figuur 2.15. Een eerste camera registreert naar waar de gebruiker kijkt. De tweede camera is in combinatie met een IR LED die gericht is op het oog zelf. Deze geeft ons de informatie over de positie van de pupil en naar waar men dus effectief ¨ kijkt. Daarnaast wordt de informatie zoals de coordinaten naar waar het oog kijkt, de tijd, de pupilgrootte, het framenummer naar een apart bestand geschreven. Deze gegevens noemt men de gaze data.
Figuur 2.15: Voorbeeld van een mobiele eye-tracker
Aan de hand van deze gaze data wordt er bepaald naar waar we kijken en kan er voorspeld worden waar onze eigen handen gaan liggen op de beelden. In het onderzoek van Li et al. (2013) gaat men de plaats naar waar de persoon kijkt, het gazepunt, proberen te voorspellen op beelden. Gaze data bevat informatie van de oog-data, zoals de richting naar waar men kijkt. Als de ogen van links naar rechts kijken, dan zal het gazepunt een grote verschuiving maken. Hand-oog en ¨ hand-hoofd coordinatie is belangrijk in ons onderzoek. Volgens Pelz et al. (2001) zouden we naar een object eerst kijken en gemiddeld 600ms daarna zou er een handbeweging gemaakt worden naar dit object. We kunnen vanuit onze gaze data voorspellen waar uiteindelijk onze eigen handen zich gaan bevinden. Uit het onderzoek van Li et al. (2013) is gebleken dat we meestal naar een omgeving van onze eigen handen kijken.
2 Literatuurstudie
15
´ hand in beeld is, dan gaat het gazepunt meestal op het uiteinde van de vingers Als er slechts e´ en liggen. Als er meerdere handen in beeld zijn, dan gaat het gazepunt tussen beide handen liggen. Dit is te zien op figuur 2.16.
Figuur 2.16: Gazepunt op eigen handen (Li et al. (2013))
Er kan dus voorspeld worden waar onze handen zijn op basis van deze kennis. Als er een gazepunt op onze frame geregistreerd wordt, zal er rond deze plaats en een paar frames later (600ms) al dan niet een huid-pixel gedetecteerd worden. In het onderzoek van Li et al. (2013) ondervinden ze dat het gebied rondom het gazepunt 80 pixels groot is. Dit is afhankelijk van de setting die gebruikt wordt. Als er zich in dit gebied huid-pixels voordoen dan kunnen we ervan uitgaan dat er mogelijk een hand gedetecteerd wordt.
2.3
Conclusie
¨ Op basis van onze literatuurstudie zullen we de beste en meest efficiente manier bepalen om onze eigen handen te kunnen detecteren in egocentrische beelden. Bij het gebruiken van pixelgebaseerde huidsegmentatie is het duidelijk dat de hue een belangrijke parameter is om huid te kunnen detecteren maar deze is echter niet voldoende. We zouden dus best een combinatie in verschillenden kleurruimten maken zoals het RGB-H-CrCb model van Dawod et al. (2010). Een methode om de handen te detecteren als object is ingewikkeld omdat een hand verschillende vormen kan aannemen. Onze huidsegmentatie in combinatie met de gaze data kunnen we gebruiken om op onze bewegende beelden een onderscheid te maken tussen voorgrond (onze eigen handen) en achtergrond.
3
Specificaties + Uitwerking
In dit hoofdstuk bespreken we hoe we ons algoritme uitwerken. We maken ons algoritme met behulp van de open source bibliotheek van OpenCV. We starten met het ontwikkelen van de code voor de huidsegmentatie.
3.1
Huidsegmentatie
De huidsegmentatie is het belangrijkste onderdeel in ons onderzoek naar handdetectie in egocentrische beelden. We segmenteren enkel op de huidskleur en gaan geen objectdetectie gebruiken. We maken geen gebruik van objectdetectie omdat de vorm van het hand zelf te complex is. En zoals we in de literatuurstudie reeds besproken hebben kan een hand verschillende vormen aannemen. Figuren 3.1 en 3.2 tonen bijvoorbeeld twee mogelijke vormen van een open hand.
Figuur 3.1: Vorm 1 van open hand
Figuur 3.2: Vorm 2 van open hand
17
18
3 Specificaties + Uitwerking
Voor onze segmentatie op basis van de huidskleur baseren we ons op het RGB-H-CbCr model van Dawod et al. (2010). Hiervoor moeten we eerst frames uit videobeelden halen. Nadien zetten we deze frames om van de RGB-kleurruimte naar HSV- kleurruimte en YCbCr-kleurruimte. Dit is te zien op figuren 3.3, 3.4 en 3.5.
Figuur 3.3: Origineel frame in het RGB-domein
Figuur 3.4: Frame in het HSV-domein
Figuur 3.5: Frame in het YCbCr-domein
Wanneer we deze frames hebben omgezet naar de juiste kleurruimten, kunnen we naar de huidpixels zoeken met de regels van het RGB-H-CbCr model van Dawod et al. (2010).
3.1.1
RGB
Het originele frame is reeds in de RGB-kleurruimte opgenomen zodus dienen we hier geen omzetting te verrichten. We gebruiken de regel van Kovac et al. (2003) voor de waarden onder invloed van daglicht. Na deze regel toe te passen op de originele frames, krijgen we een binaire afbeelding als resultaat. Op een binaire afbeelding zijn een mogelijke huid-pixel wit afgebeeld en de niet-huidpixels zwart. Dit is te zien op volgende figuren 3.6 en 3.7 . Zoals te zien in deze figuren verkrijg je een goed resultaat met een witte achtergrond. Als de huidsegmentatie enkel in het RGB-domein plaatsvindt, verkrijgen we nooit een goed resultaat. Want de waarden veranderen heel makkelijk onder invloed van licht, zoals zonlicht of licht van TLlamp. We moeten dus ook andere kleurruimten in combinatie met de RGB-kleurruimte gebruiken zoals Dawod et al. (2010) ook deden tijdens hun onderzoek.
3 Specificaties + Uitwerking
Figuur 3.6: Frame in RGB
3.1.2
19
Figuur 3.7: Huidpixels in het RGB-domein
HSV
Dawod et al. (2010) werkten enkel op de hue waarde in de HSV-kleurruimte. Oliveira and Conci (2009) ondervonden dat we voor aziatische en kaukasische huidskleuren ook de saturatie waarden kunnen gebruiken om een beter resultaat te bekomen. Omdat we met kaukasische huidskleuren werken in onze segmentatie van huid-pixels, gebruiken we dus ook de saturatie. We werken met de waarden voor de hue van 0 tot 50 en voor de saturatie van 0,23 tot 0,68 in een gebied van 0 tot 100 procent.
0 ≤ H ≤ 50
(3.1)
0, 23 ≤ S ≤ 0, 68
(3.2)
We moeten echter opletten met deze waarden in OpenCV. In OpenCV gaan de hue waarden van 0 tot slechts 180, terwijl dit normaal van 0 tot 360 graden zou gaan. Ook de saturatie en intensiteit (value) worden uitgedrukt van 0 tot 255 in plaats van 0 tot 100 procent. Deze waarden geven dus een gebied van 58 tot 173 voor de saturatie.
Figuur 3.8: Frame in HSV
Figuur 3.9: Huid-pixels in HSV
Het bekomen resultaat is al vrij duidelijk maar er wordt nog steeds veel gedetecteerd wat geen huid-pixel is. Zie figuur 3.9.
20
3.1.3
3 Specificaties + Uitwerking
YCbCr
De laatste kleurruimte, die we gebruiken in onze huidsegmentatie, is die van YCbCr. We houden ons terug aan de regels van het RGB-H-CbCr model van Dawod et al. (2010) om huid te detecteren. Na deze regels toe te passen, krijgen we terug een binair resultaat waar de huid-pixels wit gekleurd zijn en waar de niet-huidpixels zwart zijn zoals te zien is op figuur 3.11.
Figuur 3.10: Frame in YCbCr
Figuur 3.11: Huid-pixels in YCbCr
Als we dit resultaat dan bekijken, worden er nog veel delen die geen huid zijn aangeduid als huidpixels. Dit zijn meestal delen van meubilair die ongeveer dezelfde kleur hebben als onze huidskleur.
3.1.4
Samenvoegen van de kleurruimten
Om tot de best mogelijke huiddetectie te komen, worden de drie kleurruimten waarin we de huidpixels hebben gesegmenteerd, samengevoegd. We werken met een RGB-HS-CbCr model, we gebruiken dus een kanaal extra ten opzichte van Dawod et al. (2010) Deze segmentatie resulteert in een duidelijk beeld. Zie figuur 3.12
Figuur 3.12: Huidsegmentatie door samenvoeging van RGB, HSV en YCbCr kleurruimte
Op deze figuur is goed te zien dat er zich links een hand bevindt. We kunnen dit beeld nog duidelijker maken door er median blur filter erop toe te passen. Deze filter vervangt elke pixel met de mediaan van zijn naburige pixels. Zie figuren 3.13 en 3.14. We kunnen de grootte van het gebied van zijn naburige pixels instellen. Het gebied dat we gaan vervagen met de filter mag niet te groot gekozen worden want anders wordt ons resultaat niet meer duidelijk, zoals op figuur 3.14.
3 Specificaties + Uitwerking
Figuur 3.13: Blur met graad 5
21
Figuur 3.14: Blur met graad 25
Na experimentatie met verschillende afmetingen van naburige pixels, bekomen we het beste resultaat met een grootte van 5 pixels, zoals op figuur 3.13. Als we dit vergelijken met de figuur 3.12, kunnen we vaststellen dat sommige kleine zwarte gaten op de handen weggefilterd zijn. Nu werkt onze huidsegmentatie al vrij specifiek, maar er zijn nog steeds delen niet-huid die toch als huid-pixels worden aanzien. Dit probleem proberen we op te lossen door toevoeging van onze gaze data. Omdat we pixelgebaseerd werken, zullen onze berekeningen lang duren. We zullen dus onze code moeten optimaliseren om ons algoritme sneller te laten verlopen.
22
3.1.5
3 Specificaties + Uitwerking
Optimalisatie van de code
Onze code voor de huidsegmentatie bevat veel berekeningen vooral in het RGB- en YCbCr-kleurdomein. Zeker omdat onze frames een resolutie hebben van 1280x720 pixels en er 20 frames per seconde zijn. Er gaat veel rekenkracht en dus ook tijd verloren om te berekenen of elke pixel een huid-pixel of een niet-huid pixel is. Om dit te onderzoeken of te profilen, hebben we gebruik gemaakt van het programmma callgrind met behulp van valgrind en om deze gegevens te visualiseren kcachegrind. Valgrind is een programma dat onderzoekt hoe snel een applicatie loopt en waar zich de punten bevinden waar er veel rekenkracht verloren gaat. Als we deze punten vinden, dan kunnen we deze aanpassen en onze applicatie op die manier sneller laten werken. Als we onze resultaten daarna bekijken met kcachegrind, zoals op fig 3.17, dan kunnen we zien hoeveel procent van de uitvoe´ ringstijd gebruikt wordt om deze functie uit te voeren. Het geeft ook de tijd weer om slechts e´ en keer door de functie te lopen en het aantal keer dat deze uitvoering plaats heeft gevonden. Op de figuur 3.17, kunnen we zien dat de main functie 1 maal wordt opgeroepen en de functie huiddetectie 409 keer. Dit komt omdat er 409 frames zijn en voor elk frame wordt deze functie opgeroepen. We merken ook op dat de functie huiddetectie() 84,04% van de uitvoeringstijd bevat en een functie inRange() toch wel 6,57%. We kunnen deze inRange() functie wel vervangen door 2 geneste for-lussen, die pixel per pixel de berekeningen doet en dit zou de functie versnellen. We kunnen deze functies allemaal veranderen met kleine aanpassingen maar in het resultaat gaat de tijd nooit met veel seconden verminderd worden. Daarnaast hebben we nog twee mogelijkheden onderzocht om onze tijd te verminderen.
Film 1 (40s) Film 2 (16s)
1280x720 232,42s 109,08s
640x360 81,08s 33,20s
Tabel 3.1: Tijdverschillen met verschillende resoluties
Een eerste mogelijkheid is dat we onze resolutie kunnen verkleinen van 1280x720 pixels naar 640x360 pixels. Dit wilt zeggen dat onze frames 4x kleiner worden. Dit wil ook zeggen dat er dus 4x minder pixels zijn om onze berekeningen op te doen. Het verschil in tijd wordt weergegeven in tabel 3.1 .
Film 1 (40s) Film 2 (16s)
20fps 232,42s 109,08s
10fps 144,95 63,44s
5fps 86,66s 39,6s
Tabel 3.2: Tijdverschillen met verschillende frames per seconde
Een tweede mogelijkheid zou zijn dat we het aantal frames per seconde zouden verminderen. We zouden dan nog slechts op 10 frames per seconde werken in plaats van 20 frames per seconde. Dus moet de functie huiddetectie() aantal keer minder opgeroepen worden. Het verschil in tijd wordt weergegeven in tabel 3.2. We kunnen ook beide methodes combineren, maar onze voorkeur gaat uit naar het verkleinen van de resolutie. Hierdoor gaat er veel minder data verloren dan bij de tweede methode waarbij het aantal frames per seconde vermindert wordt.
3 Specificaties + Uitwerking
23
We kunnen onze huidsegmentatie ook toepassen op niet heel het frame, maar enkel op een deel van het frame waar het gazepunt zich bevindt. Hierdoor gaat onze functie van de huidsegmentatie sneller verlopen, omdat men minder pixels moet bekijken. Een gevolg hiervan is dat we natuurlijk veel informatie van ons frame verliezen. Doordat het gazepunt niet altijd in de buurt van onze handen staat, verliezen we delen van het frame waar onze huid wel op aanwezig is.
Figuur 3.15: Origineel frame
Op de figuur 3.15 bevindt het gazepunt zich linksonderaan op het toetsenbord en ons hand zich op de muis rechtsonderaan op het frame. Als we enkel huidsegmentatie toepassen rond het gazepunt, zoals in het rode vierkant op figuur 3.16. In dit vierkant wordt ons hand niet gesegmenteerd of we moeten ons gebied rond het gazepunt zo groot maken. Dit zou dan niet meer sneller zijn dan onze huidsegmentatie op het hele frame.
Figuur 3.16: Huidsegmentatie rondom het gazepunt
Als we zeker zijn dat er in de buurt rond het gazepunt een hand ligt, dan zou dit een verbetering zijn in ons algoritme. Maar omdat het gazepunt ook regelmatig op plaatsen ligt waar geen handen zijn, geeft dit geen meerwaarde in ons algoritme.
24
3 Specificaties + Uitwerking
Figuur 3.17: Schema van de code door kcachegrind
3 Specificaties + Uitwerking
3.2 3.2.1
25
Gaze data Gaze formaat
De gaze data is de data die ons informatie geeft over het tijdstip van het frame, de positie naar waar men aan het kijken is, de pupilgrootte,... . Er zijn twee soorten van infolijnen in het bestand. Elk frame heeft een informatielijn van de eerste soort. Het ziet eruit als volgt:
777 0.00 MovieFrame 1 159
(3.3)
Deze informatielijn bevat maar twee belangrijke velden voor ons algoritme. Namelijk de 777 betekent dat er een nieuwe frame is gevonden en het laatste veld in de lijn geeft het framenummer weer (in het voorbeeld 3.3 is dit frame nummer 159). Een tweede soort informatielijn kan per frame meerdere keren voor komen. Deze lijn met informatie komt slechts na een lijn informatie van de eerste soort. Dus pas als er nieuw frame gevonden is, kan deze lijn voor komen.
777 0.00 MovieFrame 1 765 10 0.0 0.0 0.680366527777 0.604133555308 19915.7333979 10 0.0 0.0 0.671567464281 0.594628403905 19915.7698272
(3.4)
De tweede soort van informatie begint met de code 10. Dit wil zeggen dat er gaze data is gevonden. Het 4e en 5e veld zijn ook belangrijk voor ons algoritme want ze geven namelijk de x- en ¨ y-coordinaten van het gazepunt aan. Men moet dit nog wel vermenigvuldigen met het aantal pixels van de breedte en de hoogte van het frame. Figuur 3.4 is een voorbeeld van meerdere gaze data in een bepaald frame (zoals hier in frame 765). Als we meerdere gazepunt hebben dan gaan we hier het gemiddelde gazepunt van berekenen en daarna gebruiken we dit gemiddelde gazepunt in onze detectie naar onze eigen handen.
3.2.2
Verwerken van de gaze data
Aan de hand van onze gaze data gaan we proberen om onze eigen handen te detecteren. Zoals we gezien hebben in het onderzoek van Li et al. (2013), gaan we eerst naar een object kijken voor dat we met onze eigen handen hier naartoe gaan. Onderstaande figuren 3.18 en 3.19 illustreren dit duidelijk. We zien dat de gazepunt, het gele bolletje, eerst op het bekertje gericht staat en een aantal frames later gaan we met ons hand hier naartoe om dit bekertje te grijpen.
Figuur 3.18: Gazepunt op beker
Figuur 3.19: Hand gaat naar beker
26
3 Specificaties + Uitwerking
Door middel van onze huidsegmentatie en de gaze data gaan we dus onze eigen handen proberen te detecteren. Als er op een frame een gazepunt op een object staat, controleren we enkele frames later of er hier huid-pixels voorkomen. Dit doen we omdat blijkt uit het onderzoek van Li et al. (2013) dat er minstens 600ms, dit zijn dus 15 frames bij een film van 25 frames per seconde, tussen een fixatie van het oog op een object en de beweging van het hand naar het object is. Wanneer er huidpixels aanwezig zijn in onze frame zou dit betekenen dat we mogelijk ons eigen hand gedetecteerd hebben. Hieronder beschrijven we onze handdetectie in pseudo-code. Zie algoritme 1.
Algorithm 1 Handdetectie 1: 2: 3: 4: 5: 6: 7: 8:
procedure HANDDETECTIE(skin, rgb f rame, Gazepoints, f ramenr)
Vector hand points if Gazepoints.size() > aantalgaze then for aantalgaze do Steek pixels van vierkant rond gazepunt in skinpoints sort(skinpoints) if skinpoints[aantalskin] == 255 then hand points ← Gazepoints[ f ramenr − aantalgaze]
12:
end if end for else if skin.at(Gazepoints[ f ramenr]) == 255 then
13:
hand points ← Gazepoints[ f ramenr]
9: 10: 11:
14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
end if end if for hand points do
Gemiddelde middel punt van al de hand points berekenen if hand points > aantalhuid punten then hand f lag op 1 zetten end if end for if hand f lag = 1 en middel punt != 0 then
teken cirkel op middel punt hier is een hand gedetecteerd end if
maak hand points leeg end procedure
In ons algoritme zijn er enkele waarden die we kunnen wijzigen om een beter resultaat te verkrijgen. De eerste waarde is die van het aantal gazepunten. Hiermee geven we aan hoeveel vorige gazepunten dat we gaan gebruiken om onze handen te kunnen detecteren. De tweede waarde die we kunnen wijzigen in ons algoritme is het aantal huidpunten. Dit is het aantal keer dat men huid gedetecteerd heeft op basis van de vorige gazepunten. We bekijken elk vorig gazepunt op ons huidig frame, als dit gazepunt een huidpixel is dan wordt dit gazepunt in de vector handpoints gestoken. Als er genoeg punten, “handpoints”, in onze vector zitten dan gaat de vlag, “handflag”, op 1 gezet worden. Als deze aanstaat en het middelpunt van de gazepunten niet gelijk is aan (0,0), wil dit zeggen dat we mogelijk een hand gedetecteerd hebben. De derde waarde is die van het
3 Specificaties + Uitwerking
27
vierkant rondom het gazepunt. We moeten dit groot genoeg kiezen om voldoende pixels te kunnen onderzoeken. We mogen dit ook niet te groot kiezen want is er maar een klein deel van het vierkant een huidpixel. Omdat het gazepunt niet altijd in het midden van het hand ligt maar meestal op het uiteinde, mogen we ons vierkant ook niet te klein kiezen. Zie figuren 3.20 en 3.21.
Figuur 3.20: Vierkant van 30pixels
Figuur 3.21: Vierkant van 80pixels
Een laatste waarde die we kunnen veranderen, is die van het percentage huid-pixels binnen ons vierkant. Als we een groot aantal huid-pixels verwachten, zullen we niet veel handen detecteren. We zullen in deze situatie enkel een hand detecteren als het gazepunt in het midden van het hand ligt. Als we een kleiner aantal huid-pixels verwachten, zullen we meerdere handen detecteren, maar zullen er zich ook meer foute detecties voordoen.
3.2.3
Eigen handen detecteren
In ons algoritme moeten we niet enkel handen detecteren, maar ook een onderscheid kunnen maken tussen onze eigen handen en handen van een eventuele andere persoon. In egocentrische beelden ondervinden we dat onze eigen handen langs onder in beeld komen en gemiddeld nooit boven een bepaalde lijn in de frames komen. Na te experimenteren met onze frames, merken we dat onze eigen handen zelden boven de rode lijn op het frame komen. Dit is te zien op figuren 3.22 en 3.23.
Figuur 3.22: Hand blijft onderaan in beeld
Figuur 3.23: Hand blijft onderaan in beeld
28
3 Specificaties + Uitwerking
´ derde van de totale hoogte van het frame bevindt. We merken dat deze lijn zich op ongeveer e´ en Onze eigen handen blijven in ongeveer 99 procent van onze frames onder deze lijn. In ons algoritme moeten we daarom een lijn aanpassen, zodat we een verschil kunnen waarnemen tussen onze eigen handen en handen van een andere persoon.
1: 2:
if hand f lag = 1 en middel punt != 0 en middel punt ≤ rodeli jn then
teken groene cirkel op middel punt hier is een eigen hand gedetecteerd
end if 4: if hand f lag = 1 en middel punt != 0 en middel punt > rodeli jn then 3: 5: 6:
teken lichtblauwe cirkel op middel punt hier is een hand gedetecteerd end if
We tonen de detectie van onze eigen handen met een groene cirkel aan (figuur 3.24) en iemand anders handen met een lichtblauwe cirkel (figuur 3.25).
Figuur 3.24: Detectie van eigen hand
Figuur 3.25: Detectie van iemand anders hand
4
Resultaten
In het vorige hoofdstuk werd uitgebreid besproken hoe we onze eigen handen gaan detecteren aan de hand van huidsegmentatie en gaze data. In dit hoofdstuk gaan we de uiteindelijke resultaten bespreken. We hebben ons algoritme opgedeeld in twee delen. We beginnen met een huidsegmenatatie in drie verschillende kleurruimten en nadien gebruiken deze huidsegmentatie in combinatie met de gaze data om een handdetectie uit te voeren op onze frames.
4.1
Huidsegmentatie
In de huidsegmentatie gaan we de huid-pixels onderscheiden van de andere pixels. We doen dit in drie kleurruimten, het RGB-, HSV- en YCbCr-domein zoals in het model van Dawod et al. (2010). Huidskleur is moeilijk te segmenteren omdat er zoveel verschillende huidtinten zijn. De huidskleur van een persoon kan ook verschillen in de zomer of in de winter. De belichting op huid is een andere belangrijke factor die de huidsegmentatie moeilijk maakt.
4.1.1
RGB
In het RGB-domein ondervonden we dat we een goed resultaat verkregen als er geen andere objecten zich in het beeld bevonden met dezelfde kleur als onze huidskleur. De ideale situatie om huid te segmenteren van andere kleuren is op een witte achtergrond zoals in figuren 4.1 en 4.2. Als er in de achtergrond objecten zijn, die ongeveer dezelfde kleur hebben als huidskleur, worden deze ook als huid gesegmenteerd. Dit is te zien op figuren 4.3 en 4.4. Hierop is te merken dat de kleur van het bureau en de zijkant van het doosje links ook gedetecteerd worden. Dit is logisch want de kleur is bijna dezelfde als die van de arm zelf. 29
30
4.1.2
4 Resultaten
Figuur 4.1: Origineel frame
Figuur 4.2: Huidpixels in het RGB-domein
Figuur 4.3: Origineel frame
Figuur 4.4: Huidpixels in het RGB-domein
HSV
In het gebied van HSV hebben we de regels ook toegepast die we besproken hebben in ons vorig hoofdstuk. Op het eerste zicht is het resultaat goed, ook al zijn er veel onderzoeken, zoals Zarit et al. (1999),Oliveira and Conci (2009) en Dawod et al. (2010), die enkel de HSV-kleurruimte gebruiken om huid te segmenteren. Dit is te zien op de figuren 4.5 en 4.6.
Figuur 4.5: Frame in het HSV-domein
Figuur 4.6: Huid-pixels in het HSV-domein
Figuur 4.7: Frame in het HSV-domein
Figuur 4.8: Huid-pixels in het HSV-domein
4 Resultaten
4.1.3
31
YCbCr
Als laatste kleurruimte gaan we ons resultaat bekijken in de kleurruimte YCbCr. Op ons resultaat is te zien dat de arm gedetecteerd wordt, maar er worden ook nog andere delen gedetecteerd die geen huid zijn, dit is te zien op de figuren 4.9 en 4.10.
Figuur 4.9: Frame in het YCbCr-domein
4.1.4
Figuur 4.10: Huid-pixels in het YCbCr-domein
Samenvoegen van kleurruimten
Als we dan deze 3 kleurruimten samenvoegen met de logische AND-functie tussen RGB, HSV en YCbCr dan krijgen we het resultaat zoals op figuur 4.12
Figuur 4.11: Origineel frame
Figuur 4.12: Samenvoeging van 3 kleurruimten
Op deze binaire afbeelding passen we een median blur filter op toe zodat we een beter resultaat verkrijgen. Er zijn nog een paar delen op het frame die gedetecteerd worden als een huid-pixel ook al zijn ze helemaal geen huid. We gaan deze bekomen huidsegmentatie gebruiken om in combinatie met de gaze data onze eigen handen te kunnen detecteren.
Figuur 4.13: Huidsegmentatie met een blurfilter
32
4.2
4 Resultaten
Handdetectie
Om onze handen te detecteren maken we gebruik van onze huidsegmentatie, zoals eerder beschreven, in combinatie met de gazedata die we verkijgen van de eye-trackerbeelden. In ons frame onderzoeken we in een vierkant rond het gazepunt of er zich hierin voldoende huidpixels voordoen om een mogelijk hand te detecteren, dit noemen we dan onze huidgazepoints. We gebruiken niet enkel het gazepunt dat bij dit frame hoort, maar gaan tot 20 gazepunten terug kijken. Als er voldoende huidgazepoints zijn en ze bevinden zich niet boven een bepaalde hoogte in het frame, dan kunnen we er van uitgaan dat we een eigen hand gedetecteerd hebben. De hoogte ´ derde van de totale hoogte van het wordt bepaald door de rode lijn in ons frame en ligt op e´ en frame. We hebben ons algoritme getest op een eerste test sequentie die bestaat uit 971 frames. We hebben getest hoeveel keer een hand gedetecteerd zou worden als we het aantal huidgazepoints zouden veranderen. Natuurlijk zijn er niet op elke frame handen of een gazepunt te zien dus gebruiken we deze niet om onze data te berekenen. Het aantal frames waar er geen handen te detecteren zijn, is gelijk aan 193 frames. Dus bevatten er 778 frames onze eigen handen. Er zijn ook 255 frames waarop er geen gazepunt staat maar waar er wel handen op aanwezig zijn. Dus blijven er 523 nuttige frames over.
Aantal huidgazepunten Testbeeld 1 971 frames 778 frames (enkel handen) 523 frames (handen+gaze)
1 399 41,1% 51,3% 76,3%
2 342 35,2% 43,9% 65,4%
3 256 26,4% 33,9% 48,9%
5 179 18,4% 23,0% 34,2%
10 72 7,4% 9,25% 13,7%
Tabel 4.1: Aantal frames met mogelijke handdetectie
Uit deze resultaten van tabel 4.1 merken we dat onze handdetectie goed werkt. Het aantal punten die huid-pixels moeten zijn, is belangrijk in ons algoritme. Op minder dan de helft van de frames waar een hand op aanwezig is, wordt dit hand ook gedetecteerd. Hier zijn uiteraard nog frames bij die gedetecteerd zijn als een mogelijk hand maar dit helemaal niet zijn, zoals te zien op de figuren 4.14 en 4.15.
Figuur 4.14: Juiste detectie van een hand
Figuur 4.15: Valse detectie van een hand
4 Resultaten
33
Om de nauwkeurigheid van ons algoritme na te gaan en zullen we onze detecties onderverdelen in: True positives (TP): dit zijn het aantal frames met juist gedetecteerde handen op. False positives (FP): dit zijn het aantal frames waarop het algoritme denkt een hand gevonden te hebben, maar dit geen hand is. False negatives (FN): dit zijn het aantal frames met niet gedetecteerde handen. Met deze detecties gaan we de precisie en de recall van ons algoritme kunnen berekenen. De precisie kunnen we berekenen door het aantal juist gedetecteerde frames te nemen ten opzichte van het totaal aantal detecties, dit zijn dus alle positieven. De recall staat voor het aantal juist gedetecteerde frames ten opzichte van al de frames waar er een hand gedetecteerd zou moeten zijn. Hoe we dit berekenen is te zien in de formules 4.1 en 4.2.
Precisie =
Recall =
TP T P + FN
(4.1)
TP T P + FN
(4.2)
Nu kunnen we deze waarden uitrekenen voor ons algoritme en geven dit weer per aantal huidgazepunten dat we gebruikt hebben zoals in tabel 4.2.
Aantal huidgazepunten TP FP FN Precisie Recall
1 245 154 379 61,4% 39,3%
2 216 126 436 63,2% 33,1%
3 182 74 522 71,1% 25,8%
5 135 44 599 75,4% 18,3%
10 61 11 706 84,7% 7,9%
Tabel 4.2: Precisie en recall waarden
Als het aantal huidgazepunten stijgt, dan stijgt onze precisie ook mee, maar de recall daalt. Dus volgens ons onderzoek wordt het beste resultaat bekomen door met 3 huidgazepunten te werken. Hierbij hebben we een precisie van 71% en een recall van bijna 26% in testbeeld 1. Dit wil dus zeggen dat er op ongeveer op 1 van de 4 frames waar een hand op aanwezig is, ook een hand gedetecteerd wordt. Op de 3 andere frames wordt er dan geen hand gedetecteerd. We merken een verschil als we de grootte van het vierkant rondom het gazepunt veranderen en ook het aantal huid-pixels die er nodig zijn in dit vierkant om een hand te detecteren. Als het vierkant grootte nul heeft, dan wil dit zeggen dat we naar het gazepunt zelf kijken.
34
4 Resultaten
Grootte van het vierkant Testbeeld 1 Testbeeld 2 Testbeeld 3 Testbeeld 4 Testbeeld 5
aantal huidpixels 1/3 1/5 1/3 1/5 1/3 1/5 1/3 1/5 1/3 1/5
0 160 160 213 213 12 12 187 187 487 487
30 189 235 241 302 16 21 201 232 604 728
80 134 250 98 252 4 24 185 276 594 893
Tabel 4.3: Aantal gedetecteerde handen met variabele grootte vierkant en aantal huid-pixels
In tabel 4.3 geven we het aantal handen die gedetecteerd zijn in onze testbeelden. Deze zijn gedetecteerd in het vierkant rondom het gazepunt. We krijgen meer detecties als we het vierkant groter maken. De hoeveelheid van huid-pixels, die aanwezig moeten zijn in het vierkant om handen te detecteren, mag best niet te groot zijn in een groot vierkant. Zoals te zien is in tabel 4.3, werken we best met een vierkant van 80 pixels groot en waarvan 1/5 van de pixels in dit vierkant huid-pixels zijn. Als we in een vierkant van 80 pixels groot en waarvan 1/3 van de pixels huid-pixels zijn, dan bekomen we een veel slechter resultaat. Dit is zelfs slechter dan wanneer we enkel naar het gazepunt kijken. De grootte van het vierkant hangt natuurlijk van de setting af. De resolutie van de beelden van de eye-tracker zijn belangrijk. Wij werken in ons onderzoek met een resolutie van 640x360. Als de resolutie zou stijgen, dan zou de grootte van het vierkant ook moeten stijgen om toch hetzelfde resultaat te verkrijgen. We zouden deze waarden nog kunnen optimaliseren. Als er zich beide handen in het frame bevinden, dan ligt het gemiddelde gazepunt tussen deze twee handen in en wordt er dus geen echt hand gedetecteerd. Dit is te zien op figuur 4.16
Figuur 4.16: Handdetectie tussen 2 handen
4 Resultaten
35
We kunnen stellen dat in het algemeen onze handdetectie goed werkt. Er worden uiteraard soms foute detecties gemaakt, dit kan veroorzaakt zijn door de huidsegmentatie, zoals delen van het bureau of karton die mee gesegmenteerd worden. Maar de gazepunten kunnen dit ook veroorzaken. Doordat we het gemiddelde berekenen van de punten die in de vector met de handpoints zitten, ¨ kunnen deze coordinaten ver uit elkaar liggen, zoals met beide handen. Dit omdat een deel van de handpoints het linkse hand detecteert en een ander deel van de punten het rechtse hand. Hierdoor komt ons gemiddelde gazepunt tussen beide handen te liggen. Een andere reden voor de foute detecties is omdat er geen gazepunten gevonden zijn voor sommige frames en er dus hier geen handen gedetecteerd kunnen worden.
5
Besluit
Het doel van deze masterproef was om een algoritme te ontwikkelen dat onze eigen handen zou detecteren in beelden die afkomstig zijn van de eye-tracker. Dit zou nuttig kunnen zijn in de shoppingcontext of in het vakgebied van de taalkunde en communicatie. In onze literatuurstudie hebben we ons algoritme opgesplitst in drie delen, namelijk de huidsegmentatie, objectdetectie en het gebruik van de gazedata in onze beelden. We hebben verschillende technieken bestudeerd en zijn tot de conclusie gekomen dat we ons algoritme enkel met de gazedata en de huidsegmentatie zullen ontwikkelen. Objectdetectie is te moeilijk omdat een hand verschillende vormen kan aannemen. In onze huidsegmentatie zijn we de huidskleur gaan bestuderen in drie kleurruimten, het RGB- , HSV- en YCbCr-kleurdomein. Door deze drie kleurruimten te combineren hebben we zo goed mogelijk huid proberen te segmenteren. Daarna hebben we onze gazedata gebruikt om samen met het resultaat van onze huidsegmentatie op zoek te gaan naar onze eigen handen. Om te verzekeren dat we onze eigen handen detecteren, niet die van anderen, hebben we een lijn geplaatst op onze frames. Dit deden we omdat we ondervonden dat onze eigen handen enkel in het onderste gedeelte van een frame voor kwamen. Daarnaast hebben we niet enkel het gazepunt gebruikt om onze handen te detecteren, maar zijn in een gebied rondom het gazepunt gaan zoeken naar huid-pixels om onze slaagkans te vergroten. Uit onze resultaten kunnen we besluiten dat als er een mogelijk hand gedetecteerd wordt door ons algoritme, dit in 70% van de gevallen een eigen hand zal zijn. Dit is op zich een goed resultaat, maar er blijven nog veel frames over waar er geen detectie is. Een mogelijke verklaring is omdat we een x-aantal frames terugkijken met onze gazepunten en het gazepunt zich niet altijd op onze handen bevindt. Daarnaast komen er ook nog foute detecties voor in ons onderzoek. Deze kunnen meestal verklaard worden doordat de huidsegmentatie objecten met dezelfde kleur als onze huidskleur mee segmenteerd.
37
38
5.1
5 Besluit
Toekomstig werk
´ hand detecteren, maar als er zich beide handen in beeld bevinden gaat het Ons algoritme kan e´ en ´ hand detecteren. Het lijkt ons mogelijk om deze handen apart te in het beste geval slechts e´ en kunnen detecteren door onze vector met verschiillende gazepunten op te splitsen. Als we deze opsplitsen, kunnen we dus ook het verschil detecteren tussen een links en een rechts hand. Hierdoor zal onze precisie van het detecteren groter worden. In de toekomst zouden ze dit algoritme nog verder kunnen uitwerken om in bijvoorbeeld in de marketingwereld te bepalen wat een persoon vastneemt en naar wat men op het product dan juist bekijkt, bijvoorbeeld houdbaarheidsdatum,... .
Bibliografie
Bay, H., Ess, A., Tuytelaars, T., and Van Gool, L. (2008). Speeded-up robust features (surf). Computer vision and image understanding, 110(3):346–359. Bay, H., Tuytelaars, T., and Van Gool, L. (2006). Surf: Speeded up robust features. In Computer Vision–ECCV 2006, pages 404–417. Springer. Bertozzi, M., Broggi, A., Del Rose, M., Felisa, M., Rakotomamonjy, A., and Suard, F. (2007). A pedestrian detector using histograms of oriented gradients and a support vector machine classifier. In Intelligent Transportation Systems Conference, 2007. ITSC 2007. IEEE, pages 143–148. IEEE. Dalal, N. and Triggs, B. (2005). Histograms of oriented gradients for human detection. In Computer Vision and Pattern Recognition, 2005. CVPR 2005. IEEE Computer Society Conference on, volume 1, pages 886–893. IEEE. Dawod, A. Y., Abdullah, J., and Alam, M. J. (2010). A new method for hand segmentation using free-form skin color model. In Advanced computer theory and engineering (ICACTE), 2010 3rd international conference on, volume 2, pages V2–562. IEEE. Fathi, A., Ren, X., and Rehg, J. M. (2011). Learning to recognize objects in egocentric activities. In Computer Vision and Pattern Recognition (CVPR), 2011 IEEE Conference On, pages 3281– 3288. IEEE. Jones, M. J. and Rehg, J. M. (2002). Statistical color models with application to skin detection. International Journal of Computer Vision, 46(1):81–96. Kovac, J., Peer, P., and Solina, F. (2003). Human skin color clustering for face detection, volume 2. IEEE. Li, C. and Kitani, K. M. (2013). Pixel-level hand detection in ego-centric videos. In Computer Vision and Pattern Recognition (CVPR), 2013 IEEE Conference on, pages 3570–3577. IEEE. Li, Y., Fathi, A., and Rehg, J. M. (2013). Learning to predict gaze in egocentric video. In Computer Vision (ICCV), 2013 IEEE International Conference on, pages 3216–3223. IEEE. Lowe, D. G. (1999). Object recognition from local scale-invariant features. In Computer vision, 1999. The proceedings of the seventh IEEE international conference on, volume 2, pages 1150– 1157. Ieee. Lowe, D. G. (2004). Distinctive image features from scale-invariant keypoints. International journal of computer vision, 60(2):91–110. 39
40
BIBLIOGRAFIE
Mair, E., Hager, G. D., Burschka, D., Suppa, M., and Hirzinger, G. (2010). Adaptive and generic corner detection based on the accelerated segment test. In Computer Vision–ECCV 2010, pages 183–196. Springer. Oliveira, V. and Conci, A. (2009). Skin detection using hsv color space. In H. Pedrini, & J. Marques de Carvalho, Workshops of Sibgrapi, pages 1–2. Pelz, J., Hayhoe, M., and Loeber, R. (2001). The coordination of eye, head, and hand movements in a natural task. Experimental Brain Research, 139(3):266–277. Ren, X. and Gu, C. (2010). Figure-ground segmentation improves handled object recognition in egocentric video. In Computer Vision and Pattern Recognition (CVPR), 2010 IEEE Conference on, pages 3137–3144. IEEE. Suard, F., Rakotomamonjy, A., Bensrhair, A., and Broggi, A. (2006). Pedestrian detection using infrared images and histograms of oriented gradients. In Intelligent Vehicles Symposium, 2006 IEEE, pages 206–212. IEEE. Wang, C.-C. and Wang, K.-C. (2008). Hand posture recognition using adaboost with sift for human robot interaction. In Recent progress in robotics: viable robotic service to human, pages 317– 329. Springer. Zarit, B. D., Super, B. J., and Quek, F. K. (1999). Comparison of five color models in skin pixel classification. In Recognition, Analysis, and Tracking of Faces and Gestures in Real-Time Systems, 1999. Proceedings. International Workshop on, pages 58–63. IEEE.
A
Programmacode
Headerfile hand.hpp
/* * Stijn Vinck - handdetectie * * Masterproef Campus De Nayer E-ICT */ #include #include #include #include #include #include #include #include #include #include #include
"opencv2/ml/ml.hpp" <stdio.h>
#define InputFolder "/home/stijn/test/testbeelden/2015_08_19/001/jpg/" #define WKS "/home/stijn/test/testbeelden/2015_08_19/001/Gaze.wks" #define Filetype ".jpg" using namespace std; using namespace cv;
void handdetectie(Mat& skin, Mat& rgb_frame, Vector Gazepoints, int framenr, int& slider); Mat huiddetectie(Mat& capture, Point P1);
41
42
A Programmacode
Huiddetecie huid.hpp
/* * Huiddetectie op basis van de RGB-H-CbCr waarden + Gaze * */ #include "hand.hpp" #define MIN3(r,g,b) ((r)<(g)?((r)<(b)?(r):(b)):((g)<(b)?(g):(b))) #define MAX3(r,g,b) ((r)>(g)?((r)>(b)?(r):(b)):((g)>(b)?(g):(b))) #define WIN 100 Mat huiddetectie(Mat& rgb_frame, Point P1) { int m=0, n=0, o=0,p=0,q=0,r=0,s=0,t=0; int blue,green,red, max=0,min=0; float cb, cr; char filename[200], filename1[200], filename2[200], filename3[200], filename4[200],filename5[200],filename6[200],filename7[200]; //string window_name = "video original | q or esc to quit"; //namedWindow(window_name, WINDOW_AUTOSIZE); //resizable window = CV_WINDOW_KEEPRATIO; //namedWindow("skin", WINDOW_AUTOSIZE); //namedWindow("seg", WINDOW_AUTOSIZE); /*namedWindow("HSV", WINDOW_AUTOSIZE); //namedWindow("YCrCb", WINDOW_AUTOSIZE); //namedWindow("HSV_skin", WINDOW_AUTOSIZE); //namedWindow("RGB_skin", WINDOW_AUTOSIZE); //namedWindow("YUV_skin", WINDOW_AUTOSIZE);*/ Mat Mat Mat Mat Mat Mat Mat Mat Mat
rgb_skin; rgb1; rgb2(rgb_frame.rows,rgb_frame.cols,CV_8U); rgb3(rgb_frame.rows,rgb_frame.cols,CV_8U); rgb4(rgb_frame.rows,rgb_frame.cols,CV_8U); hsv_frame; hsv_skin; //HSV yuv_frame; yuv_skin(rgb_frame.rows,rgb_frame.cols,CV_8U); //YUV Mat skin(rgb_frame.rows,rgb_frame.cols,CV_8U); Mat skin1(rgb_frame.rows,rgb_frame.cols,CV_8U); Mat seg;
//RGB
//plaatsen van de beelden /*cvMoveWindow( "HSV", rgb_frame.cols, 0 ); cvMoveWindow( "YCrCb", 2*rgb_frame.cols, 0 ); cvMoveWindow("RGB_skin", 0, rgb_frame.rows); cvMoveWindow("HSV_skin", rgb_frame.cols, rgb_frame.rows); cvMoveWindow("YUV_skin", 2*rgb_frame.cols, rgb_frame.rows);*/ //RGB
A Programmacode
//gewoon daglicht inRange(rgb_frame, Scalar(20,40,95), Scalar(255,255,255), rgb1); //Scalar(B,G,R) rgb2=rgb1; rgb4=rgb1; for(int x=0;x(y,x)[0]; green= rgb_frame.at(y,x)[1]; red= rgb_frame.at(y,x)[2]; min=MIN3(blue,green,red); max=MAX3(blue,green,red); if(max-min>15){ rgb2.at(y,x)=255; } else{ rgb2.at(y,x)=0; } if((red-green)>15 && red>green && red>blue){ rgb4.at(y,x)=255; } else{ rgb4.at(y,x)=0; } } } bitwise_and(rgb1,rgb2,rgb3); bitwise_and(rgb3,rgb4,rgb_skin); //HSV cvtColor(rgb_frame,hsv_frame,CV_BGR2HSV); //afbeelding omzetten van RGB naar HSV
//HSV werk in OpenCV met H: 0-180, S:0-255, V:0-255 inRange(hsv_frame,Scalar(3,58,0),Scalar(25,173,255),hsv_skin);
//YUV of YCrCb cvtColor(rgb_frame,yuv_frame,CV_BGR2YCrCb); //afbeelding omzetten van RGB naar YCrCb for(int x=0;x(y,x)[1]; cb= yuv_frame.at(y,x)[2]; if(cr<=(1.5862*cb) && cr>=(0.3448*cb+76.2069) && cr>=(-4.5652*cb+234.5652) && cr<=(-1.15*cb+301.75) && cr<=(-2.2857*cb+432.85)){ yuv_skin.at(y,x)=255; }
43
44
A Programmacode
else{ yuv_skin.at(y,x)=0; } } } //samenvoegen van de 3 kleurruimten bitwise_and(rgb_skin,hsv_skin,skin1); bitwise_and(skin1,yuv_skin,skin); //Smoother maken van de skindetectie medianBlur(skin,skin,5); if(P1.x!=0 && P1.y!=0){ circle(rgb_frame,P1,5,Scalar(255,0,255),5,8,0); } waitKey(1); char key = (char)waitKey(2); //delay N millis, usually long enough to display and capture input
switch (key) { case ’q’: case ’Q’: case 27: //escape key //return 0; case ’ ’: //Save an image // handig om in verslag van masterproef te zetten sprintf(filename,"origineel%.2d.jpg",m++); imwrite(filename,rgb_frame); sprintf(filename1,"HSV%.2d.jpg",n++); imwrite(filename1,hsv_frame); sprintf(filename2,"YCrCb%.2d.jpg",o++); imwrite(filename2,yuv_frame); sprintf(filename3,"HSVskin%.2d.jpg",p++); imwrite(filename3,hsv_skin); sprintf(filename6,"RGBskin%.2d.jpg",s++); imwrite(filename6,rgb_skin); sprintf(filename7,"YUVskin%.2d.jpg",t++); imwrite(filename7,yuv_skin); sprintf(filename4,"skin%.2d.jpg",q++); imwrite(filename4,skin); sprintf(filename5,"seg%.2d.jpg",r++); imwrite(filename5,seg); cout << "Afbeeldingen opgeslagen " << endl; break; default: break; } return skin; }
A Programmacode
45
Handdetectie functie in main.cpp
/* * Detectie van de handen dmv de huidsegmentatie (skin) * en de gaze data in Gazepoints * */ void handdetectie(Mat& skin, Mat& rgb_frame, Vector Gazepoints, int framenr, int &slider){ char filename[200], filename1[200];
int hand=0; //flag om te detecteren of er een mogelijk hand is gedetecteerd Point middelpunt(0,0); vector handpoints; vector skinpoints;
if(Gazepoints.size()>=(unsigned) AANTAL){ //unsigned want size kan nooit kleiner zijn dan 0 // //Gazepoint van 20 frames ervoor zien of er op die plaatsen skin te vinden is // for(int i=0;i<=AANTAL;i++){ //beginnen bij frame 20 en aftellen naar frame 19, 18, 17,.. skinpoints.clear(); if(Gazepoints[framenr-i].x!=0 && Gazepoints[framenr-i].y!=0){ Point hoek1(Gazepoints[framenr-i].x-slider,Gazepoints[framenr-i].y-slider); Point hoek2(Gazepoints[framenr-i].x+slider,Gazepoints[framenr-i].y+slider); rectangle(rgb_frame,hoek1,hoek2,Scalar(255,0,0),1,8,0); for(int k=hoek1.x;k<=hoek2.x;k++){ for(int l=hoek1.y;l<=hoek2.y;l++){ //al de pixels in een vector steken skinpoints.push_back(skin.at(l,k)); } } sort(skinpoints.begin(),skinpoints.end()); //sorteren van de skinpoints //cout << (int) skinpoints[(skinpoints.size()/2)+1] << endl; if(skinpoints[(4*skinpoints.size()/5)]==255){ // 1/5 van de skinpoint skin --> mogelijk handpunten handpoints.push_back(Gazepoints[framenr-i]); }
46
A Programmacode
} } } else{ // //is nog niet genoeg gaze data om te detecteren of er skin is dus nemen we al de data dat er al is // for(int i=0;i<=framenr;i++){ if(skin.at(Gazepoints[framenr-i].y,Gazepoints[framenr-i].x)==255){ circle(rgb_frame,Gazepoints[framenr-i],10,Scalar(255,255,0),8,8,0); hand=1; } } } //middelpunt van de gaze zoeken door het gemiddelde te nemen van de handpoints for (unsigned int j=0;j3){ //we gebruiken meestal 3 hand=1; break; //hand flag opzetten //cout << "mogelijk hand gedetecteerd " <midden){ circle(rgb_frame,middelpunt,100,Scalar(0,255,0),15,8,0); if(framenr!=framenroud){ sprintf(filename,"./testbeelden/recht/hand1_%.2d.jpg",framenr); //gebruiken voor masterproefverslag imwrite(filename,rgb_frame);
A Programmacode
47
teller++; cout << "Het punt van de gaze is :" << middelpunt << " bij framenr " << framenr << " aantal: " <
48
A Programmacode
Main functie main.cpp
/* * Stijn Vinck - handdetectie versie 1.0 * * Masterproef Campus De Nayer E-ICT * Main lus + handdetectie mbv huidsegmentatie en gaze data */ #include "hand.hpp" bool Old = true; int AANTAL=20; int teller=0; Mat frame,rgb_frame, skin; const int slider_max=200; int slider; int framenroud; //hide the local functions in an anon namespace namespace { void help(char** av) { cout << "\nJe hebt een argument meegegeven, dit is niet nodig\n" "Gebruik ./" << av[0] << " \n" << "===================================================================" << endl; } } int main(int ac, char** av) { cout << "================================================================================" << endl; cout << "=== Stijn Vinck ===" << endl; cout << "=== Handdetectie op beelden afkomstig van egocentrische camera ===" << endl; cout << "=== versie 2.0 ===" << endl; cout << "================================================================================" << endl; cout << "=== Druk op spatie voor een afbeelding op te slaan " << endl; if (ac != 1) { help(av); return 1; } /* * Dit werkt als men met de webcam gaat werken * We hebben een video-input nodig van de eye-tracker zelf *
A Programmacode
49
std::string arg = av[1]; VideoCapture capture(arg); //try to open string, this will attempt to open it as a video file if (!capture.isOpened()) //if this fails, try to open as a video camera, through the use of an integer param capture.open(atoi(arg.c_str())); if (!capture.isOpened()) { cerr << "Failed to open a video device or video file!\n" << endl; help(av); return 1; }*/
//int aantal_frames=0; double t = (double)getTickCount(); //inlezen van gaze.wks met de gaze data in char FileName[200]; ifstream GazeCoFile; string Line; float time,DeltaTime,X_Gaze,Y_Gaze; char Movieframe[10]; int code; int one; int framenr; bool FrameAcquired=false; int lastFrame=999; GazeCoFile.open(WKS); cout << "=== Read wks file: " << WKS <<endl; vector Gazepoints; char grootte[50]; sprintf(grootte,"Grootte:"); namedWindow("handdetectie", WINDOW_AUTOSIZE); createTrackbar(grootte,"handdetectie",&slider,slider_max); setTrackbarPos(grootte,"handdetectie",15); while(!GazeCoFile.eof()) { getline( GazeCoFile, Line ); sscanf(Line.c_str(),"%d",&code); //cout << "Line = " << Line.c_str() << endl; Point P1(0,0); if(code == 777) { //cout << "New frame was found: "; sscanf(Line.c_str(),"%d%f%s%d%d",&code, &time,Movieframe, &one,&framenr); FrameAcquired = true; // read image
50
A Programmacode
//sprintf( FileName,"%s%08d%s",InputFolder, framenr+1,Filetype); sprintf( FileName,"%s%05d%s",InputFolder, framenr+1,Filetype);
frame = imread(FileName); if(frame.empty()) { cout << "COULD NOT READ IMAGE: " << FileName << endl; break; } } else{ if(code ==10){ sscanf(Line.c_str(),"%d%f%f%f%f",&code,&time, &DeltaTime,&X_Gaze, &Y_Gaze); if(FrameAcquired==true && X_Gaze <= 1 && X_Gaze >=-1 && Y_Gaze <= 1 && Y_Gaze >=-1) { // NEW PUPIL X_Gaze = frame.cols*X_Gaze; Y_Gaze = frame.rows*(1-Y_Gaze); //Y_Gaze= 0 --> onderaan de afbeelding ipv boven if(X_Gaze<0) X_Gaze = 0; if(Y_Gaze < 0) Y_Gaze = 0; if(X_Gaze>frame.cols) X_Gaze = frame.cols; if(Y_Gaze>frame.rows) Y_Gaze = frame.cols; P1.x = X_Gaze/2; //door de resize moeten we de gaze nog door 2 delen P1.y = Y_Gaze/2; //cout << "Gaze = " << P1 << " framenr= "<< framenr << endl; } }
} if(framenr==lastFrame) //Gazedata in een vector steken {
A Programmacode
51
// frame is already in vector // update last index if(Gazepoints[framenr].x ==0 && Gazepoints[framenr].y ==0) Gazepoints[framenr] = P1; else { Gazepoints[framenr].x +=P1.x; Gazepoints[framenr].x = Gazepoints[framenr].x /2; Gazepoints[framenr].y += P1.y; Gazepoints[framenr].y = Gazepoints[framenr].y /2; } } else { Gazepoints.push_back(P1); lastFrame = framenr; }
resize(frame,rgb_frame, Size(),0.5,0.5,INTER_CUBIC); //frame kleiner maken --> sneller skin=huiddetectie(rgb_frame, P1); handdetectie(skin,rgb_frame, Gazepoints, framenr, slider); //scanf("%*c"); } t = ((double)getTickCount() - t)/getTickFrequency(); cout << "Times passed in seconds: " << t << std::endl; return 0; }
B
Callgraph van kcachegrind
In onze bijlage hebben we de 2 schema’s van ons uiteindelijke algoritme, dat we met valgrind en kcachegrind hebben gemaakt. Hier is op te zien dat de huiddetectie een belangrijke functie is in ons algoritme, namelijk 59,69% van de totale tijd terwijl de functie handdetectie slechts 1,86% bevat. Van deze 1,86% gaat er nog eens 1,55% naar het tonen van het beeld met de functie imshow().
53
54
B Callgraph van kcachegrind
Figuur B.1: Main en huiddetectie functie
B Callgraph van kcachegrind
55
Figuur B.2: Main en handdetectie functie
FACULTEIT INDUSTRIELE INGENIEURSWETENSCHAPPEN TECHNOLOGIECAMPUS DE NAYER Jan De Nayerlaan 5 2860 SINT-KATELIJNE-WAVER, België tel. + 32 15 31 69 44 [email protected] www.iiw.kuleuven.be