Conduc ător știin țific : Conf. Dr. Ing. Remus Brad [605285]
1 UNIVERSITATEA “LUCIAN BLAGA” DIN SIBIU
FACULTATEA DE INGINERIE
CATEDRA DE CALCULATOARE ȘI AUTOMATIZ ĂRI
PROIECT DE DIPLOM Ă
Conduc ător știin țific : Conf. Dr. Ing. Remus Brad
Absolvent: [anonimizat]: Calculatoare
– Sibiu, 2012 –
UNIVERSITATEA “LUCIAN BLAGA” DIN SIBIU
FACULTATEA DE INGINERIE
2 CATEDRA DE CALCULATOARE ȘI AUTOMATIZ ĂRI
Interfa ță om-ma șin ă folosind
senzorul Kinect
Conduc ător știin țific: Conf. Dr. Ing. Remus Brad
Absolvent: [anonimizat]: Calculatoare
3 1. PREZENTAREA TEMEI …………………………………………… ………………………………………4
1.1 SCOP …………………………………………… …………………………………………… ………………………………4
1.2 OBIECTIVE …………………………………………… …………………………………………… ………………………4
1.3 REZUMAT …………………………………………… …………………………………………… ………………………..4
1.4 CERIN ȚE IMPUSE PENTRU FUNC ȚIONARE …………………………………………… ………………………….6
1.5 STRUCTURA LUCR ĂRI…………………………………………… …………………………………………… ……….7
2. CAPITOLUL I …………………………………………… …………………………………………… …………7
2.1 INTERFE ȚE DE LUCRU OM -MA ȘIN Ă – SCURT Ă INTRODUCERE …………………………………………… 7
2.2 INTRODUCERE ÎN DOMENIUL SENZORULUI KINECT …………………………………………… …………..12
2.3 TEHNOLOGIA UTILIZAT Ă DE SENZORUL KINECT …………………………………………… ………………12
2.4 TEHNOLOGIA „ LIGHT CODING ” ȘI CONSTRUIREA IMAGINI DE ADÂNCIME ……………………….13
2.5 ALGORITMUL DE SEGMENTARE AL IMAGINI FOLOSIT DE SENZORUL KINECT……………………..17
2.6 SEGMENTAREA IMAGINI ( „ USER SEGMENTATION ” )…………………………………………… ………20
2.7 ALGORITMUL DE SCHELETIZARE UTILIZAT DE SENZOTUL KINECT …………………………………..22
2.8 DESCRIEREA SKELETON -ULUI ( „ SKELETON TRACKING ” )…………………………………………… .26
3. CAPITOLUL II …………………………………………… …………………………………………… ………28
3.1 PLATFORMA .NET ( „ .NET FRAMEWORK ” )…………………………………………… …………………..28
3.2 MEDIUL DE DEZVOLTARE MICROSOFT VISUAL STUDIO 2010 ( C# )…………………………………29
3.3 BIBLIOTECA TASK PARALLEL …………………………………………… ……………………………………….30
3.4 BIBLIOTECA UI-AUTOMATION …………………………………………… ………………………………………33
3.5 BIBLIOTECA OPEN CV ( EMGU )…………………………………………… …………………………………….34
4. CAPITOLUL III …………………………………………… …………………………………………… …….35
4.1 ETAPELE REALIZ ĂRII PROIECTULUI …………………………………………… ………………………………..35
4.2 INTERFA ȚA DE LEG ĂTUR Ă CU SENZORUL KINECT …………………………………………… ……………38
4.3 MODULUL DE ECALIBRARE A SENZORULUI KINECT …………………………………………… ………….44
4.4 MODULUL DE CONTROL ȘI DETEC ȚIE A GESTURILOR …………………………………………… ………..61
4.5 MODULUL INTERACTIV DE TESTARE A GESTURILOR …………………………………………… …………94
5. CAPITOLUL IV …………………………………………… …………………………………………… …….96
5.1 REZULTATELE OB ȚINUTE …………………………………………… …………………………………………… ..96
5.2 DIFICULT ĂȚ I ÎNTÂMPINATE PE PARCURSUL DEZVOLT ĂRI PROIECTULUI ……………………………99
5.3 DOMENIUL DE UTILIZARE AL PROIECTULUI , EVENTUALE DEZVOLT ĂRI ULTERIOARE ȘI
CONCLUZI …………………………………………… …………………………………………… …………………………101
6. BIBLIOGRAFIE …………………………………………… …………………………………………… …..103
4 1.Prezentarea temei
1.1 Scop
Proiectul și-a propus ca scop principal crearea unei interfe țe de lucru om-ma șin ă
cu ajutorul unui senzor Kinect. Interac țiunea dintre utilizator și sistemul de calcul se
realizează prin intermediul unui protocol bazat pe gesturi. G esturile sunt recunoscute la
nivelul mâinilor, fiind compus din mimica degetelor . În principiu am urm ărit înlocuirea
func ților de baz ă ale mouse-ului, prin gesturile mâinilor, iar pentr u a demonstra buna
func ționare a acestei interfe țe am realizat o aplicatie interactiv ă de tip paint. În cadrul
paint-ului se pot desena anumite tipuri de forme, c um ar fi: cercuri, dreptunghiuri, lini,
pic ături, sau desenarea propriu-zis ă dup ă cum se mi șcă mâna pe ecran, adic ă dup ă
mi șcările mouse-ului. Aceste facilit ăți sunt selectate tot prin intermediul unui protocol
de la nivelul mâinilor. De asemenea exist ă și posibilitatea de manipulare a anumitor
imagini, preluate dintr-un fi șier de c ătre utilizator, prin: rota ți dup ă anumite axe și
scalare („zoom in” și „zoom out” ). Exist ă implementate și dou ă comezi pentru
controlul programului „Mozilla Firefox” . În acest caz am implementat doar comenzile
de „ go-back ” și „ go-forward ” . Dac ă nu se dore ște folosirea aplica ției paint, se poate
folosi separat comenzile pentru controlul mouse-ulu i.
1.2 Obiective
1. Realizarea unui sistem de ecalibrare a senzorului k inect în func ție de distan ța și de
mărimea mâini utilizatorului.
2. Realizarea unui protocol de interac țiune cu computerul prin intermediul unui
sistem de recunoa ștere a gesturilor mâinilor utilizatorului.
3. Realizarea unei aplica ții interactive de tip paint, controlat tot prin ges turi.
1.3 Rezumat
Proiectul este alc ătuit din trei compone principale și anume: interfa ța de ecalibrare
a senzorului kinect în func ție de distan ța fa ță de camerele acestuia și de m ărimea mâini
drepte (zona alc ătuit ă din palm ă și degete) a utilizatorului. Aceasta are rolul de a furniza
datele necesare pentru identificarea zonei minime d in cadrul imagini ini țiale, furnizate
de camera de adâncime a senzorului, în care se afl ă mâna utilizatorului. Este vorba de
aflarea laturilor unui p ătrat de m ărime minim ă ce încadreaza cel mai bine fiecare din
5 cele dou ă mâini ale utizatorului. Dup ă ce sa aflat distan ța și m ărimea minim ă necesare
încadr ări mâinilor, aceasta se va închide, acest lucru avâ nd loc atunci când utilizatorul
va lasa mâna dreapta în jos. A doua component ă este tot o interfa ță , de fapt aceasta este
interfa ța principal ă a proiectului. Datele calculate de componenta prec edent ă sunt
preluate în cadrul acesteia și cu ajutorul lor din imaginea de adâncime redat ă de senzor
se preia mai departe doar dou ă zone, separate, de interes, și anume acelea care con țin
mâna dreapt ă respectiv mâna stâng ă a utilizatorului. Pozi țile mâinilor utilizatorului sunt
aflate tot cu ajutoul senzorului, acesta având înco rporat un sistem intern de tracking
(urm ărire) a corpului utilizatorului/ ilor. Cu aceste da te deja aflate se poate prelua mai
departe din imaginea ini țial ă exact zonele de interes, care con țin în principiu doar mâna
dreapt ă/ stâng ă a utilizatorului. Prin acest mecanism se asigur ă o mai bun ă procesare a
imagini și un r ăspuns al sistemului de calul mai rapid la ac țiunile înteprinse de
utilizator.
Cea de a treia component ă const ă într-o aplica ție de tip paint. În cadrul acesteia
se pot creea diferite forme cu diferite culori, ace stea fiind comandate prin gesturile
simple de la nivelul mâinilor, este nevoie aici de utilizarea ambelor mâini.
Este foarte important ca atunci când s e schimb ă utilizatorul s ă se refac ă
ecalibrarea senzorului, astfel evitându-se micile n epl ăceri cum ar fi: distan ța de
recunoa ștere a gesturilor prea mare sau neîncadrarea total ă a mâinilor în imaginile
procesate. Oricum sistemul, senzorul kinect, este l imitat cu privire la distan ța optim ă de
lucru, la care func ționeaz ă corect, în sensul c ă dac ă suntem prea aproape de senzor (sub
800 milimetri) acesta nu sesizeaz ă utilizatorul, iar dac ă suntem prea departe (peste 4900
milimetri) nu se mai recunosc cum trebuie gesturil e, și în general formele corpului
utilizatorului.
Ca o idee de ansamblu a modului de func ționare ar fi: utilizatorul va aprinde
aplica ția, ini țial trebuie s ă se afle în picioare în fa ța senzorului kinect, pentru a putea fi
recunoscut întregul corp și s ă mi ște ambele mâini. O dat ă ce va fi afi șat ă imaginea
mâinilor pe ecran, acesta va putea controla mouse-u l printr-un protocol simplu bazat pe
gesturile mâinilor, în principiu de gesturile mâini drepte. Ca o mic ă și simpl ă
demonstra ție de utilizare a aplica ției de control, pentru a putea fi vizibil modul de
ac țiune al utilizatorului, este utilizarea programului de paint unde se vor putea desena
diferite forme cu diferite culori și manipula imagini. Acestea sunt de asemenea
controlate tot prin gesturi.
6 1.4 Cerin țe impuse pentru func ționare.
Pentru func ționarea aplica ției este nevoie de preinstalarea unui driver specia l
conceput pentru senzorul kinect, f ără acesta senzorul nu este recunoscut de Sistemul de
Operare de pe computer-ul utilizatorului. Acest dri ver se nume ște: „ Kinect for
Windows SDK ”, este dezvoltat de firma Microsoft, și se poate lua de pe site-ul oficial
gratuit.[5]
Cerin țele sistem minime pentru func ționarea și instalarea senzorului sunt:
1. Sistemele de Operare suportate: „Windows 7”,
„Windows 8 Developer Preview ”, „ Windows Embedded Standard 7 ”. Dezvoltarea
aplica ției s-a realizat pe sistemul de operare „ Windows 7 ” pe 32 de bi ți.
2. Cerin țe Hardware:
a. Procesor pe 32 de bi ți (x86) sau 64 de bi ți (x64).
b. Procesor Dual-Core cu frecven ța de 2,66 GHz sau un procesor mai rapid
sau cu mai multe core-uri. Aplica ția a fost dezvoltat ă pe un „Quad-Core
Q8300” cu frecven ță de procesare de 2.50 GHz .
c. USB 2.0 dedicat.
d. Un USB special folosit ca și alimentare cu energie electric ă a senzorului
(„ power supplies ” ) .
e. Minim 2 GB de RAM
3. Cerin țe Software:
a. „Microsoft Visual Studio 2010 Express” sau alt ă edi ție de
„Visual Studio 2010 ” sau o versiune mai nou ă.
b. „ NET Framework 4.0 ”.
4. Pentru utilizarea Skeletonului pentru C++ / C# / Vi sual Basic sunt necesare :
a. „ Microsoft DirectX SDK ” versiunea Iunie 2010 sau o versiune mai
nou ă.
b. Runtime pentru „ Microsoft DirectX 9 ” .
5. Pentru utilizarea Microfonului / facili t ăți de recunoa ștere a vorbiri sunt
necesare:
a. „Microsoft Speech Platform Runtime ” , v ersiunea 10.2, pentru Sistemele
de Operare cea pe 32 de bi ți, iar pentru cele pe 64 de bi ți versiunea pentru 64 de bi ți.
b. „ Microsoft Speech Platform – Software Developer Kit ”, versiunea 10.2
c. „ Kinect for Windows Runtime Language Pack ”, versiunea 0.9.
7 Punctele de la 1. la 4. sunt vitale pentru func ționare aplica ției, punctul 5. este op țional,
dat fiind faptul c ă în cadrul proiectului nu se utilizeaz ă recunoa șterea vocal ă. [5]
De asemenea mai este nevoie și de preinstalarea unei biblioteci dedicate proces ări de
imagini numit ă „Emgu” ,care este o versiune a biliotecii „ OpenCV ” special proiectat ă
pentru limbajul de programare C# . O scurt ă descriere a uneltelor folosite pentru
proiectarea aplica ției o voi face în capitolul 2.
1.5 Structura lucr ării
Capitolul I const ă în introducerea în domeniul interfe țelor de lucru om-ma șin ă și a
senzorului Kinect, la ce poate fi utilizat, întrebu in ță rile acestuia, cât și o prezentare
succint ă a unei structuri generale a acestuia și a algoritmilor folosi ți de acesta pentru
crearea imagini de adâncime, a skeleton-ului uman și a segment ări imagini.
În capitolul II este prezentat ă platforma utilizat ă în realizarea proiectului,
tehnologiile folosite și ce facilit ăți pot oferi acestea utilizatorilor, și mai ales
programatorilor.
Capitolul III prezint ă pa șii parcur și în implementarea aplica ției. Aici sunt
prezentate: modul de realizare a interfe țelor de lucru, protocolul de interac țiune și
algorimi folosi ți pentru recunoa șterea gesturilor de la nivelul mâinilor.
În capitolul IV sunt prezentate concluziile și rezultatele ob ținute în urma acestui
proiect, de asemenea și posibilele dezvolt ări ulterioare. Tot aici mai sunt prezentate și
dificult ățile întâmpinate pe parcursul dezvolt ări proiectului.
2.1 Capitolul I
2.1 Interfe țe de lucru Om-Ma șin ă – Scurt ă introducere.
Interac țiunea om-calculator („ Human-Computer Interaction – HCI ”) este știin ța
care se ocup ă cu proiectarea, evaluarea și implementarea sistemelor de calcul
interactive destinate uzului uman, și cu studiul fenomenelor importante existente în
acest context.
Din perspectiva știin ței calculatoarelor, accesul este pus pe interac țiune; mai precis
se refer ă la interac țiunea uneia sau mai multor persoane cu una sau mai multe ma șini de
calcul.
Luând în considerare no țiunea de ma șin ă, putem avea de-a face în locul clasicelor
8 sta ții de lucru cu ma șini de calcul încorporate („embedded”), ca p ărți ale bordurilor
avioanelor sau ale obi șnuitelor cuptoare cu microunde. Tehnicile de proiec tare a
interfe țelor acestor dispozitive sunt similare celor de pro iectare a interfe țelor grafice
utilizator ale unei sta ții de lucru.
Interfa ța utilizatorului reprezint ă partea vizibil ă a sistemului, prin intermediul ei
putându-se introduce informa ții, comenzi și modele (de altfel este singura component ă a
sistemului cu care utilizatorul intr ă în contact) .
O interfa ță de utilizator performant ă este flexibil ă, consistent ă, simpl ă și
adaptabil ă. .
Pentru a lucra cu un sistem, utilizatorii t rebuie s ă fie capabili s ă controleze
sistemul și s ă aib ă acces la st ările sistemului.
Termenul de „User Interface” (Interfa ță Utilizator) este folosit în special în
sistemele computerizate sau electronice. Ea este de fapt un „ layer ” care separ ă omul de
ma șina pe care o opereaz ă. Designe-ul unei astfel de interfe țe afecteaz ă cantitatea de
efort pe care userul trebuie s ă o consume pentru a introduce date în sistem și s ă
interpreteze ie șirea sistemului, și cât de mult dureaz ă s ă înve țe s ă-l utilizeze.
Concluzionând, interfa ța utilizator este partea unei aplica ții software care permite
utilizatorului:
– să interac ționeze cu calculatorul ;
– s ă-și îndeplineasc ă îndatoririle sau sarcinile ce-i sunt cerute („task ”).
Utilizabilitatea este gradul cu care se m ăsoar ă cât de mult se mapeaz ă interfa ța unui
sistem cu psihologia și fiziologia userului, asta ducând la gradul sistem ului de eficien ță
și satisfac ție .
Interfe țele de lucru om-ma șin ă au ap ărut odat ă cu ma șinile dar referindu-ne strict
la interfe țele cu sistemele de calcul, etapele dezvolt ării lor, în func ție de tipul dominant
de comunicare, au fost trei mari categorii : [8]
– „ Batch interface ”, 1945 – 1968 ;
– „ Comand-line interface ” , 1969-1983 ;
– Interfete grafice, din 1983 pân ă ast ăzi.
Interfa ța în linie de comand ă are urmatoarele avantaje / dezavantaje .
Avantaje:
– Permite scrierea clar ă și explicit ă a comenzilor, cu to și parametrii bine defini ți ;
– Ofer ă flexibilitate în utilizare ;
– Comunicarea cu sistemul de operare se fac e rapid si eficient .
9 Dezavantaje:
– Operatorul trebuie s ă cunoasc ă bine comenzile si efectele lor ;
-Este mai greu de utilizat de c ătre neprofesioni ști .
Interfa ța grafic ă are urmatoarele avantaje / dezavantaje .
Avantaje:
– Este intuitiv ă și u șor de folosit ;
– Poate fi utilizat ă și de c ătre neprofesioni ști ;
– Creeaz ă un mediu de lucru ordonat ;
– Permite crearea și utilizarea de aplica ții complexe, precum și integrarea acestora
în medii de lucru unitare .
Dezavantaje:
– Anumite operatii legate, de exemplu, de c onfigurarea sistemului pot s ă nu fie
accesibile din meniurile și ferestrele interfe ței grafice ;
Interfa ța ascunde anumite detalii legate de preluarea și execu ția comenzilor ;
– Folose ște mai multe resurse și este mai pu țin flexibil ă decât interfa ța în linie de
comand ă.
Filmele din domeniul fic țiunii ne prezint ă urm ătoarea posibilitate în dezvoltarea
interfe țelor, și anume cele neuronale, în care omul nu va mai folo si echipamente de
control, ci va ac ționa totul prin puterea gândului.
Interfe țele au dou ă componente principale:
– input (intrarea) – care în echipamentele d in tehnologia informa ției sunt tablete,
taste, butoane, microfoane, camere video , etc ;
– output (ie șirea) – ecrane text și imagine, difuzoare, echipamente de control
mecanic etc.
Aceste interfe țe const ă în tehnici de interac țiune care combin ă înțelegerea
capacit ăților umane obi șnuite (comunicare, mi șcare, cunoa ștere, percep ție) cu
dispozitive de I/O (Input/Output) și modalit ăți de percepție și ra ționare ale
calculatorului.
Așadar se încearc ă integrarea a numeroase nivele de tehnologie :
– Recunoa șterea sunetului, vorbiri și generarea acesteia ;
– Viziunea artificial ă ;
– Anima ție grafic ă și vizualizare ;
– Interpretarea limbajului ;
– Percep ție și feedback tactil („haptics ”) ;
10 – Înv ățare ;
– Modelare .
O viziune de ansamblu asupra modelelor de interac șiune om-ma șin ă se poate vizualiza
în figura 1.1 a) , iar fluxul datelor de interac țiune dintr-un asemenea sistem se poate
observa în figura 1.1 b).
a) b)
Figura 1.1 –a)- Modele de interac țiune: om – ma șin ă, b)-Fluxul informational
dintre om-ma șin ă, surs ă [9]
Tehnologia Multimedia versus Tehnologia Multimodal:
Un sistem multi-modal folose ște cel pu țin un simt (mod) de interac țiune
(de exemplu sim țul vizual și auditiv: un procesor de text rote ște cuvinte simultan cu
afi șarea lor pe ecran ) .
Un sistem multi-media folose ște diverse medii de comunicare a informa ției
(de exemplu un sistem de înv ățare bazat pe calculator folose ște imagini video, anima ții,
text, poze sau medii diferite care se bazeaz ă pe modul de interac țiune vizual). [9]
Tehnologii folosite în interfe țe multimodale :
1. Recunoa șterea vorbirii :
– felxibil, natural;
– sisteme comerciale ( de exemplu telefoanele mobil e ) .
La asemenea sisteme cu cât complexitatea este mai m are cu atât s-ar putea
strecura uneori erori nedorite în algoritmic ă.
2. În țelegerea limbajului:
– interpretarea limbajului (scris/vorbit ) ;
11 Aceast ă tehnologie presupune folosirea unui vocabular redu s/formul ări
standardizate.
3. „Pen-based gesture” (PDA, smart phones) :
– înlocuie ște tastatura ;
– interpretare linii, contururi, selec ții (punct sau arie), recunoa ștere a scrisului de
mân ă , etc.
4. Senzori magnetici, iner țiali, pentru urm ărirea mi șcărilor corpului :
– Senzori purta ți pe corp (de exemplu m ănu șa ) ;
5. Recunoa șterea sunetelor (non-verbale ) :
– Output: avertizare, semnalizare ;
– Input: declan șare de evenimente (de exemplu b ătut din palme, etc ) .
6. Dispozitive “haptic”-e (tactile ) :
– M ăsoar ă presiunea, viteza, localizarea ;
– Detec ția unor ac țiuni manuale ( manipulative sau explorative ). De e xemplu:
Joystick iDrive (joystick, cap rotativ folosit ca i nterfa ță de intrare pentru computerul de
bord al ma șinilor ) .
7. Viziune artificial ă :
– Recunoa șterea anumitor semne /gesturi cu semnifica ție ;
– Expresia facial ă, postura corporal ă, gestiuri ale mâinii, etc ;
– Percep ția este dat ă de camere de luat vederi plasate corespunz ător .
Interfe țe bazate pe viziune – directii :
1. Determinarea „Prezen ței și loca ției” : – detec ția fe ței, a corpului, urm ărirea
(tracking-ul) capului și a corpului în imagini succesive .
2. Determinarea „ Identit ății ”: – Recunoasterea fe ței, a mersului , etc .
3. Determinarea „ Expresiei ” : – Tracking-ul t r ăsăturilor faciale, modelarea și analiza
expresiei faciale .
4. Determinarea „Focaliz ării aten ției”: – Tracking-ul fe ței/capului, a privirii (ochilor).
5. Deterimnarea „Posturii și a mi șcărilor corporale” : – Modelarea și trackning-ul
corpului și a p ărților componente.
6. Determinarea „ Gesturilor ” : – Recunoa șterea gesturilor (mâna), tracking-ul
mâinii . [9]
12 2.2 Introducere în domeniul senzorului Kinect.
Cuvântul „senzor” este derivat din cuvântul latin „ sentire” care inseamn ă
„a percepe”. O defini ție din dic ționar atribuie cuvântului „senzor” semnifica ția de
„dispozitiv care detecteaz ă o schimbare într-un stimul fizic și o transform ă într-un
semnal care poate fi m ăsurat sau înregistrat” . Cuvântul „senzor” se poate folosi pentru
elementul sensibil însu și.
Senzorul kinect este un dispozitiv periferic sensib il la schimb ările de mi șcarea
obiectelor exterioare. Acesta permite utilizatorilo r s ă se foloseasc ă: fie de o consol ă
Xbox 360 fie de un Computer cu sistem de operare Wi ndows/ Linux, f ără ajutorul unui
controller fizic, ci doar folosind gesturi ale corp ului si comenzi vocale.
Kinect a fost lansat pe pia ță pentru prima dat ă în America de Nord la data de 4
Noiembrie 2010, iar in Europa in data de 10 Noiembr ie 2010.[1] Din momentul
apari ției pe pia ță a prezentat un succes enorm și înc ă men ține recordul mondial al celui
mai bine vândut dispozitiv electronic cu o medie de 133,33 de unit ăți vândute pe zi.
2.3 Tehnologia utilizat ă de senzorul Kinect.
Dup ă cum se observ ă în figura 1.2 senzorul are în componen ță dou ă camere de
adâncime „3D depth sensors” , o camer ă RGB, un microfon multi-strat și un picior
motorizabil. Kinect s-a construit pe dou ă tehnologi de baz ă: tehnologia dezvoltat ă intern
de „Rare”, care este o subdiviziune a companiei Mic rosoft Game Studio și este utilizat ă
în principiu pentru grafic ă, și pe tehnologia „PrimeSense Sensor ” (fig. 1.5), ut ilizat ă
pentru tehnologia din spatele camerelor.
Fig. 1.2: componentele fizice ale senzorului Kinec t. Sursa [2]
O alt ă tehnologie este utilizarea segment ării utilizatorului și „ Skeleton tracking ” ,
foarte importante în dezvoltarea aplica ției cât și în esen ța acestui dispozitiv, utilizat de
obicei pe post de controller, mai ales în jocurile dedicate consolelor.
13 Acesta dezvolt ă un sistem care poate interpreta anumite gesturi sp ecifice, f ăcând
astfel un control liber (prin gesturi) al posibilel or dispozitive electronice utilizând o
proiec ție , o camer ă infraro șu și un microchip special folosit pentru a urm ări (tracking)
mi șcarea de obiecte și persoane în trei dimensiuni. Acest sistem de scan er 3D se
nume ște „ Light Coding ” și se bazeaz ă pe reconstruc ția obiectelor 3D. [1]
2.4 Tehnologia „ Light Coding ” și construirea imagini de adâncime.
Tehnologia „ Light Coding ” func ționeaz ă prin codificarea volumului scenei cu
ajutorul luminii apropiate provenite de la lumina i nfraro șie (IR) . În principiu aceast ă
tehnologie are la baz ă detec ția mediului înconjurator prin intermediul unui pate rn de tip
plas ă construit ă din puncte care sunt constante in timp (în imagine a codificat ă a acesteia
componentei PS1080 ). PS1080 proceseaz ă imaginea infraro șie și produce o imagine de
adâncime pe fiecare frame.
PrimeSensor-ul controleaz ă un sistem de proiec ție infraro șu apropiat care este citit
sau preluat de la scen ă, utilizând un senzor standard de imagine de tip C MOS („ off-
the-shelf CMOS image sensor” ) pentru a produce ima ginea de adâncime de rezolu ție
640X480 sau 320X240 sau 80X60. Algoritmul sofistic at, rulat în paralel, pentru
descifrarea lumini codificate, primit ă, și crearea imagini de adâncime pe baza acestora,
este stocat în PrimeSence SoC (Sistem on Chip), car e este conectat la senzorul CMOS.
Componenta principal ă a PrimeSensor-ului de m ăsurare a adâncimii este sistemul de
proiec ție și detec ție a luminii infraro și. Acesta dup ă ce prime ște lumina codificat ă în
planul de referin ță integrat, provenit ă de la scen ă, aplic ă o metod ă de triangula ție activ ă
dintre aceasta și lumina provenit ă de la camera infraro șu pentru a estima adâncimea.
Triangula ția, din punct de vedere geometric, este un proces d e determinare a
loca ției unui punct prin m ăsurarea unghiurilor pân ă la acesta de la punctele cunoscute.
Atunci punctul poate fi fixat ca și al trei-lea punct apar ținând unui triunghi cu o singur ă
latur ă cunoscut ă și dou ă unghiuri cunoscute. Astfel putem calcula cu ajutor ul acesteia
distan ța punctului necunoscut pân ă la planul/ dreapta, care con ține punctele cunoscute,
cu ajutorul urm ătoarei formule: fig 1.3
În cazul senzorului kinect, conform [4] laserul inf raro șu emite o singur ă raz ă, care
este împ ărțit ă în multiple raze cu ajutorul unei re țele de difrac ție pentru a creea un
pattern constant în timp. Acest pattern este captat de camera infraro șu și este corelat ă cu
un pattern de referin ță . Patternul de referin ță este ob ținut prin preluarea unui plan la o
14 distan ță cunoscut ă fa ță de senzor, și este stocat ă în memoria senzorului. Când un punct
este proiectat pe un obiect, a c ărui distan ță fa ță de senzor este mai mic ă sau mai mare
decât cea a planului de referin ță , pozi ția punctului din imaginea infraro șu va fi mutat ă
în direc ția dat ă de linia de baz ă dintre proiec ția laser și centrul de perspectiv ă al camerei
(1) de unde rezult ă: (2)
Fig. 1.3. Modul de calcul al distan ței utilizând metoda triangula ției. Surs ă [1]
infraro șu. Distan ța de deplasare este m ăsurat ă pentru toate punctele printr-o simpl ă
opera ție de corela ție între imagini, care produce o imagine de dispari ție. Astfel pentru
fiecare pixel distan ța pân ă la senzor poate fi deci preluat ă din aceast ă imagine de
dispari ție.
Figura 1.4 ilustreaz ă rela ția dintre distan ța unui punct obiectiv „k” pân ă la planul
de referin ță și distan ța de dispari ție măsurat ă „d”. Pentru a exprima coordonatele 3D
ale punctului obiectiv se consider ă un sistem de coordonate cu originea în centrul de
perspectiv ă al camerei infraro șu. Axa „z ” este ortogonal ă pe planul imagini care
con ține punctul obiectiv, axa „x” este perpendicular ă pe axa „ z” în direc ția dat ă de linia
de baz ă „b”, dintre centrul camerei infraro șu și proiec ția laser, și axa „y” este
ortogonal ă pe „ x ” x și „ y ” , realizând un sistem de coordonate de drea pta.
Să presupunem c ă un obiect este pe planul de referin ță , la o distan ță „Zo”
fa ță de senzor, și un punct de pe obiect este capturat în planul de imagine al camerei
infraro șu. Dac ă obiectul este deplasat mai aproape/ departe fa ță de senzor, atunci loca ția
punctului pe planul imagini va fi deplasat ă pe direc ția „ x”. Aceast ă deplasare a
punctului este calculat ă cu ajutorul urm ătoarelor formule:
(3) bD=Zo Zk Zo − și fd=Zk D
Unde „ Zk” reprezint ă distan ța (adâncimea) punctului „ k” în spa țiul obiect, „ b” este
lungimea liniei de baz ă, „ f ” este lungimea focal ă a camerei infraro șu, „ D” este
15 deplasarea punctului „ k” în spa țiul obiect, „ d” este distan ța de dispari ție în spa țiul
imagine.
Astfel rela țiile de ob ținere a coordonatelor punctului obiect în planul de adâncime sunt:
(4) Zk=
dfp Zo Zo
*1+
(5) Xk= – ) ( xxo xk fZk ∇+−
(6) Yk= – ) ( yyo yk fZk ∇+−
Unde „f” este lungimea de focalizare a camerei infr aro șu, „xo”, „yo” offsetul punctului
principal, „ yx∇∇, ” coeficien ți de distorsiune a lentilelor, „b” lungimea bazei, „ Zo”
distan ța patternului de referin ță .
Fig. 1.4 reprezentarea schematic ă a rela ției de dispari ție pentru calculul adâncimi
unui punct „ k”. Surs ă [4]
Pentru o acurate țe mai mare a informa ților de adâncime, PrimeSensor-ul ruleaz ă
un proces numit „Registration”. Acest proces produc e o imagine aliniat ă per pixel, ceea
ce înseamn ă c ă fiec ărui pixel din cadrul imagini RGB îi corespunde un p ixel în
imaginea de adâncime ( este aliniat unui pixel din imaginea de adâncime). De asemenea
toate informa țile senzoriale (imaginea de adâncime, imaginea RGB și componenta
audio) sunt transferate host-ului prin intermediul interfe ței seriale USB 2.0.
În mare se poate spune c ă este vorba de c ățiva pa și pentru a putea ob ține imaginea
în adâncime a scenei. Ace știa sunt vizibili în figura figura 1.5 .
16
Fig. 1.5 Metodologia de lucru a PrimeSonsor-ului. S urs ă [3]
Componenta PS1080 SoC este un sistem muti-sens, pr oducând o imagine de
adâncime, de culoare și streaming audio sincronizat ă (cam in acela și timp) . Acesta nu
face nicio presupunere/ ipotez ă cu privire la Unitatea Central ă de Procesare (CPU) a
gazdei ( host-ului ), tot algoritmul de achizi ție a datelor de adâncime rulând pe acesta, și
numai cu o comunica ție minim ă asigurat ă prin portul USB ruleaz ă pe host.
De re ținut este faptul c ă acest algoritm este imun la lumina ambiental ă, acesta
func ționând la fel de bine atât într-un ambient lipsit d e lumin ă cât și într-unul cu
lumin ă.
Dup ă cum se poate observa și în figura 1.6 , componentele de baz ă și obligatorii
ale PrimeSens-ului sunt: camera infraro șu și senzorul de imagine CMOS, restul
componentelor fiind op ționale. De asemenea componenta PS1080 este esen ța acestui
principiu, în el fiind întregul aloritm de creare a imagini de adâncime și de scheletizare
a utilizatorului.
PrimeSens-ul este un dispozitiv care ajut ă un computer s ă perceap ă lumea în
dimensiuni 3D. PrimeSensor-ul este un dispozitiv de tipul „ end-to-end ” , care permite
computerului s ă perceap ă lumea în trei dimensiuni și s ă translateze aceste percep ți
într-o imagine sincronizat ă de adâncime, în aceea și manier ă în care o realizeaz ă și
oameni. Solu ția include un senzor, care observ ă scena (utilizatorii și mediul
înconjur ător ) , și o component ă perceptiv ă, sau supranumit ă „creierul”, care în țelege
interac țiunile dintre utilizator și mediul înconjur ător. Acest PrimeSensor se nume ște
„ NITE Middleware ” și este componenta de percep ție a sistemului.
17
Fig. 1.6 Componentele fundamentale ale PrimeSensor- ului . Surs ă [3]
2.5 Algoritmul de segmentare a imagini folosit de senzo rul kinect
Algoritmul folosit de senzor pentru a putea creea o imagine de adâncime, în
cadrul c ăreia este posibil ă doar identificarea corpului utilizatorului printr- un
identificator se nume ște „ GrabCut ” [13]. Noi putem extrage foarte reped e imaginea de
fundal din cadrul imagini de adâncime furnizate de senzor, în sensul c ă putem avea doar
utilizatorul în cadru, automat, f ără restul obiectelor din scen ă și f ără a utiliza noi al ți
algoritmi în plus.
Editarea de imagini cere abilitatea de a extrage re pede și u șor obiectele din cadrul
imaginilor digitale. Un obiect din prim-plan („ for eground ”) se refer ă la orice obiect de
interes dintr-o imagine. Fundalul unei imagini se r efer ă la to ți pixeli din imagine care
nu fac parte din prim-planul obiectului. Procesul d e separare a unei imagini în p ărțile de
prim-plan și fundal este cunoscut sub numele de segmentare al imagini.
„GrabCut” este un algoritm de segmentare a fundalul ui sau a obiectelor care
combin ă cele dou ă tehnici deja existente, și anume: tehnica bazat ă pe informa ția de
textur ă (culoare) sau tehnica bazat ă pe informa ția de contrast.
Figura 1.7- ilustra ția algoritmului „GrabCut”, utilizatorul deseneaz ă un dreptunghi
în jurul unui obiect, atunci obiectul este extras a utomat, surs ă [13].
18 Numele acestui algoritm vine de la „graph-cut” , fi ind bazat pe tehnici de utilizare
și reducere a arborilor. De obicei acest algoritm se efectueaz ă prin desenarea unui
dreptunghi în jurul obiectului de interes.
Un pseudocod al algoritmului se g ăse ște în sursa [14].
1) Cele trei lucruri/p ărți de intrare ale utilizatorului sunt: Partea de pri m-plan
(„foreground”), care apar ține obiectului, din figura 1.8, partea de
fundal („ background”), care nu apar ține obiectului, , și regiune
necunoscut ă („unknown”) , care poate fi ori prim-plan ori fund al, regiunea
dintre linia alb ă și cea ro șie din figura 1.8.
Figura 1.8- cele trei regiuni definite de c ătre utilizator, surs ă [13]
Aceat ă împ ărțire este de obicei realizat ă prin selectarea, de c ătre utilizator,
printr-un dreptunghi, a obiectului pe care dore ște s ă-l separe de restul imagini, un
fel de zon ă de interes. Astfel regiunea din interiorul dreptun ghiului va fi marcat ă
ca și necunoscut ă, iar cea din afar ă ca și fundal, ilustra ție în figura 1.7 .
2) Se va creea o segmentare ini țial ă a imaginii, în care to ți pixeli necunoscu ți
vor fi considera ți ca și prim-pla, deci ei vor fi plasa ți în clasa
„ foreground” , iar pixeli cunoscu ți vor fi plasa ți în clasa „background” .
3) Cele dou ă clase, „foreground” și „background” vor fi modelate cu ajutorul
modelului de mixturi Gaussian („Gaussian Mixture Mo dels” – GMMs ) .
Un mixt gaussian este un model probabilistic care p resupune c ă toate
datele de intrare sunt generate dintr-un amestec (m ixt) finit de distribu ții
gaussiene cu parametri necunoscu ți. Deci este o func ție parametric ă de
probabilit ăți de densitate reprezentând o sum ă ponderat ă a densit ăți de
componente gaussiene. Parametri GMMs sunt estima ți din date de
antrenament utiliz ănd o metod ă iterativ ă a valori maximizate a șteptate
(„Expectation-Maximization”) sau utilizând estimato rul maximum
aposteriori („Maximum A Posteriori”) dintr-un model foarte bine antrenat. FT
BT
19 Acest model este folosit pentru a clasifica pixeli unei imagini în
concordan ță cu cele dou ă clase men ționate mai sus. [15]
4) Fiecare pixel din clasa „foreground” este atribuit celei mai probabile
componente gaussiene în prim-plan-ul GMMs. Similar pixeli din fundal
„background” sunt atribui ți celei mai probabile componente gaussiene a
fundalului.
5) Se înva ță un nou GMM din seturile de pixeli create anterior, în pasul
anterior
6) Un graf este alc ătuit și este utilizat ă tehnica „Graph Cut” pentru a g ăsi o
nou ă clasificare pentru pixeli din prim-plan și fundal. Aceat ă tehnic ă poate
fi utilizat ă pentru a rezolva eficient o arie larg ă de probleme low-level în
„computer vision” și probleme care pot fi formulate în termeni și condi ți
de minimizare a energiei. Problema de minimizare a energiei poate fi
formulat ă ca și c ăutarea maximului într-un graf.[14]
Figura 1.9 – Un exemplu de graf pentru a segmenta foreground-ul și
background-ul, surs ă [14]
Graf-ul este format din noduri „ ni ” care au leg ături între ele cu ponderi „ wij ”
Aceste ponderi descriu cât de tare sunt conectate s au legate unele de altele.
Tăietura minim ă („min-cut”) dintre dou ă noduri este o modalitate de a separa
un graf în dou ă p ărți distincte cu efortul minim, prin minimizarea sume i
, unde I este setul de leg ături dintre nodurile care au fost t ăiate.
În figura 1.9 nodul „ n1 ” va fi clasificat ca și „ foreground ” ,iar restul vor
fi clasificate ca și „ background ” .
20 7) Se repet ă pa și 4-6 pân ă când clasificarea nu va mai diferi mult fa ță de cea
anterioar ă.
8) Se aplic ă o uniformizare a conturului obiectului segmentat.
GrabCut necesit ă patru tipuri diferite de informa ți pentru fiecare pixel în parte. Acestea
sunt :
• Culoare -o valoare RGB ;
• Cele trei zone : „ foreground”, „background” și „unknown” .
• Suprafa țe mat ă („Matte”) în pasul ini țial al segment ări, fie
suprafa ța mat ă pentru fundal fie cea a prim-planului.
• Indexul componentei în cadrul algoritmului GMM.
2.6 Segmentarea imagini ( „ User Segmentation ” )
Scopul segment ări imagini („ user segmentation ”) este s ă identifice și s ă
„ urm ăreasc ă ” („ track”) utilizatori în cadrul scenei. Fiec ărui utilizator, aflat în scen ă, i
se atribuie un unic și persistent identificator (ID) .Principalul rezult at al segment ări este
o hart ă de ID-uri care mapeaz ă fiecare pixel, apar ținând utilizatorului, cu ID-ul
corespunz ător. Aceast ă hart ă de identificatori este foarte util ă în cazul în care se dore ște
prelucrare exclusiv ă asupra corpului utilizatorului, în sensul c ă se poate elimina foarte
ușor elementele din cadrul scenei, adic ă a celor care nu apar țin corpului uman. Aceast ă
hart ă este valabil ă doar în cazul imagini de adâncime și a prelucr ări skeleton-ului.
Exist ă îns ă o limitare cu privire la num ărul de utilizatori din cadrul scenei. În cazul
imagini de adâncime se pot indentifica unic prin ID doar 7 utilizatori în acela și timp, iar
în cazul skeletonului se poate prelucra în acela și timp doar 2 utilizatori, primi doi
ap ăru ți în cadrul scenei, în general primi 2 utilizatori prelua ți în ordinea cresc ătoare a
ID-urilor din imaginea de adâncime. Algoritmul de c reare al skeleton-ului/ tracki-ului
utilizatorului folose ște aceat ă hart ă pentru a genera skeleton-ul.
Deci, în consecin ță , orice eroare (inacurate țe) produs ă de segmentarea utilizatorului va
produce de asemenea o eroare în procesul de trackin g a utilizatorului. Unele scenari
dificile care pot produce erori în segmentare inclu d:
1. Utilizatori care se mi șcă foarte aproape de obiectele din scen ă, cum ar fi,
pere ți, scaune, mobilier, etc. În acest caz senzorul tin de s ă asigneze
obiectul de contact, sau de care utilizatorul este foarte aproape, ca și
21 component ă o corpului ( uman ) și deci și acesta va fi identificat unic prin
ID-ul utilizatorului. În cazul în care utilizatorul se va dep ărta de acel
obiect, senzorul i și va corecta eroare și va con știentiza faptul c ă acel
obiect nu apar ține corpului uman, deci nu-l va mai identifica unic prin ID-
ul utilizatorului în cauz ă. Acest lucru s-a putut observa în urma dezvolt ări
și test ări aplica ției.
2. Doi utilizatori mi șcându-se în timp ce se ating. În aces caz nu se poa te
face corect distinc ția între componentele corpului fiec ărui utilizator și în
urma velor observate se încearc ă o aproxima ție, o mediere oarecum între
zonele de contact. În cazul în care cei doi utiliza tori se despart, în sensul
că nu or s ă mai aibe zone de contact se reface rapid harta de ID-uri, deci
este posibil ca utilizatori s ă nu mai aibe acela și ID pe care l-au avut în
trecut, în cazul în care în trecut cei doi nu au av ut zone de contact. Exit ă
îns ă și situa ți neplăcute, în sensul c ă se poate pierde de tot ID-ul unuia
dintre utilizatori, și acesta s ă fie confundat cu elementele din fundalul
scenei.
3. Doi utilizatori eclipsa ți de un al treilea ar putea duce la amestecare ID-
urilor acestora. Este evident faptul acesta, pentru c ă este oarecum
asem ănător cazului anterior. Se poate întâmpla ca doi dint re cei trei
utilizatori s ă aibe o suprapunere foarte mare de corpuri, sau s ă fie unul
dintre ei in contact direct cu ceilal ți doi. În acest caz se poate schimba
ID-urile, atunci când unul dintre cei trei se va di stan ța astfel încât s ă nu
mai aibe nicio zon ă de contact cu ceilal ți utilizatori.
4. Mi șcare senzorului în timpul în care segmentarea este activ ă.
Dac ă utilizatorul nu este vizibil pentru un timp mai m are de 10 secunde, atunci
utilizatorul este considerat pierdut și un eveniment special de sesizare a pierderi este
generat . În acest caz ID-ul lor este eliberat și li se va asigna un altul în cazul în care va
fi redetectat. Dat fiind faptul c ă ID-urile sunt reutilizabile, un alt utilizator poa te prelua
ID-ul utilizatorului pierdut la un moment dat in vi itor. Prin urmare este foarte important
să existe un eveniment special care s ă sesizeze acest lucru, pentru a se pute opri
tracking-ul vechiului utilizator. Acest lucru va as igura faptul c ă atunci când un utilizator
cu acela și ID este redetectat, se cere recalibrarea senzorul ui pe utilizator, în acest caz pe
noul utilizator.
22 2.7 Algortimul de scheletizare utilizat de senzorul k inect
În ceea ce prive ște algoritmul din spatele scheletiz ări corpului uman și a aceluia
de „tracking” nu se g ăsesc prea multe documente sau referin țe exacte cu privire la
descrirea algoritmul propriu.
În principiu la baza algoritmului ar sta dou ă metode: una care se bazeaz ă pe
probabilistic ă („Probabilistic tracking in a metric space”) , baz at ă pe c ăut ări într-un
spa țiu de solu ți, și una bazat ă pe algoritmi de înv ățare automat ă, cu ajutorul c ăreia se
încearc ă o c ăutare a unei func ți care s ă g ăseasc ă pozi ția corpului. La acesta din urm ă se
încearc ă g ăsirea unei rela ți / func ți care aplicat ă unei imagini s ă poat ă detecta o anumit ă
pozi ție deja înv ățat ă.
În articolul „Real-Time Human Pose Recognitionin Pa rts from Single Depth
Images” [7] este descris algoritmul de recunoa ștere a pozi ților/ipostazelor corpului
uman și de extragere, dintr-o singur ă imagine de adâncime, a unui mic set de de
coordonate 3D pentru pozi ția fiec ărui punct apar ținând unui skeleton. Algoritmul
prezentat în acest articol constituie componenta de baz ă a platformei pentru jocuri
dedicate senzorului kinect. Algoritmul este inspir at din cei de recunoa ștere a obiectelor
care împarte obiectele în p ărți. Aceast ă abordare este condus ă de dou ă obiective:
eficien ță computa țional ă și robuste țe. O singur ă imagine de adâncime este segmentat ă
în regiuni ale corpului dup ă o densitate probabilistic ă, cu p ărțile definite ca fiind spa țial
localizate în jurul punctelor de interes ale skelet on-ului. (fig. 1.7) . Reproiectând aceste
zone de interes în spa țiul real, se poate localiza modurile spa țiale pentru fiecare parte de
distribu ție și genereaz ă, astfel, (eventual mai multe) ponderi de încredere pentru
localizarea 3D a fiecarui punct al skeleton-ului. S egmentarea în p ărțile corpului se
realizeaz ă per pixel, aceast ă evaluare separat ă a fiec ărui pixel evit ă o c ăutare
combinatoric ă în spa țiul punctelor skeleton-ului. Pentru setul de antren ament se
genereaz ă imagini de adâncime realiste cu oameni, de m ărimi și forme diferite, în
posturi cât mai variate preluate toate dintr-o baz ă de date cu mi șcări. Se antreneaz ă o
profundă și diferit ă re țea / p ădure („forest”) de clasificatori, care evit ă supraînv ățarea
prin utilizarea a sute de mii de imagini de antrena ment. Au fost ale și arborii de decizie
deoarece ofer ă o clasificare rapid ă și eficient ă și pentru c ă pot fi eficient implementa ți
pe GPU. O re țea / p ădure de arbori de decizie este un ansamblu de arbor i, fiecare fiind
compus din noduri și frunze,dar și de anumite c ăi care pot fi urmate de diferi ți arbori
pentru o intrare particular ă. Aceasta este format ă dintr-un num ăr de arbori de decizie,
23 în cadrul c ăruia fiecare nod este format dintr-o valoare a func ției de compara ție a
adâncimii unui pixel pe anumite coordonate din cadr ul imagini (fig. 1.6) și un prag de
acceptare.
Aceast ă func ție de compara ție este de forma :
(7) ,
unde reprezint ă adâncimea pixelului „ x” în cadrul imagini „ I” , iar
parametri descriu offset-urile „ u ” și „ v”. În figura 1.6 se observ ă c ă
func ția va da un r ăspuns mai mare pentru punctele din partea de sus a corpului, iar o
valoare aproape de zero pentru cele din partea de j os. [7]
Figura 1.6 –Ilustrarea func ției de compara ție în adâncime a unui pixel. X-ul cu galben
indic ă pixelul care este clasificat, cercurile cu ro șu indic ă offset-ul pixelilor defini ți în
ecua ția func ției de compara ție. În imaginea a) cele dou ă exemple dau o mare diferen ță
în adâncime, în imaginea b) acelea și dou ă puncte dau o diferen ță de dâncime mai mic ă.
Sura [7]
Pentru a clasifica fiecare pixel în cad rul unei imagini se pleac ă din r ădăcina
arborelui și se evalueaz ă repetitiv func ția de adâncime a pixelilor, astfel se sare în
stanga sau în dreapta, în arbore, în func ție de acel prag. Când se ajunge la o frunz ă,
într-un anumit arbore de decizie, o valoare de dist ribu șie va fi înv ățat ă în concordan ță
cu o anumit ă parte a corpului. Apoi aceste distribu ții din cadrul tuturor arborilor este
preluat ă și f ăcut ă o medie a lor pentru a da clasificarea final ă.
Într-un final, modelele spa țiale ale pixelilor împ ărțiți pe zone de interes,
distribu țiile pixelilor, sunt calculate cu ajutorul algoritm ului de „ mean shift ”, în urma
căruia vor rezulta coordonatele 3D ale skeletonului.
24
Figura 1.7. Dintr-o singur ă imagine de adâncime, o distribu ție per pixel este aplicat ă
pentru a afla c ărei regiuni îi apar ține un pixel. Se observ ă zonele de culoare separate
pentru fiecare regiune de interes a corpului. Surs ă [7]
„ Mean shift ” este un algoritm de detec ție a maximului unei func ții de densitate,
dând ca și date de intrare valori discrete ale acestei func ți. Acesta este util și pentru
detec ția caracteristicelor densit ăți.
Algoritmul „mean shift” consider ă spa țiul ca o func ție de densitate de
probabilit ăți. În cazul în care prime ște ca și intrare un set de puncte, atunci algoritmul le
consider ă ca valori de baz ă ale func ției probabilitate de densitate. Dac ă sunt prezentate
regiuni dense sau grupuri (clustere) în spa țiul problemei, atunci acestea corespund
caracteristicelor sau eventual maximelor locale ale func ției probabilitate de densitate.
Pentru fiecare pixel din imagine (având o localizar e spa țial ă și o culoare particular ă) ,
algoritmul define ște o fereastr ă (zon ă) în jurul acestuia, un set de pixeli vecini (pe o
anumit ă distan ță spa țial ă și cu o anumit ă diatan ță de culoare). Pentru ace știa se
calculeaz ă media spa țial ă și media culori. Apoi se mut ă centrul ferestrei la coordonatele
deja calculate ca medie și culoare și se va repeta din nou algoritmul, pân ă cand acesta
va converge, adic ă pân ă când valoarea medie a coordonatelor spa țiale și a celor de
culoare nu se va mai modifica. La fiecare itera ție se poate considera c ă fereastra se mut ă
pe o zon ă tot mai dens ă a setului de intrare. [10]
Estimarea pozi țiilor corpului uman s-a concentrat asupra tehnicilo r care s ă nu
cear ă un num ăr foarte mare de imagini de antrenament de aceea se prefer ă oarecum
folosirea imaginilor de adâncime, pentru c ă se evit ă astfel dependen țele de culoarea
25 părului, hainelor, pielii utilizatorilor. De asemene ca și date de antrenament s-au folosit
imagini din baze de date care con țineau filmule țe cu dansatori, cu oameni mergând,
alergând, etc , care au fost îns ă clasificate astfel încât s ă nu existe dou ă pozi ți similare .
Clasificarea s-a realizat folosind distan ța Euclidian ă per corp (joint-urile corpului), deci
nu exit ă dou ă pozi ți mai apropiate de 5 cm una de alta.
Un semi-algoritm este descris mai jos [11], în cadr ul acestuia se folosesc 32 de
puncte pentru skeleton-ul corpului, fig 1.8
Figura 1.8 – Modul de lucru al clasificatorilor de pozi ție a corpului, surs ă [7]
Prima dat ă are loc clasificarea probabilit ăți fiec ărui pixel ca fiind unul din cele 32
de p ărți ale corpului. Apoi se determin ă probabilistic fiecare grup al p ărților corpului în
concordan ță cu acele p ărți. În final se prezint ă cea mai probabil ă pozi ție a corpului
utilizatorului.
Un astfel de algoritm, mai optimizat, rulea z ă în aproximativ 5 milisecunde per
frame (200 de frame-uri pe secund ă) pe un „Xbox 360 GPU”. Aceasta prelucreaz ă
cadru-cu-cadru și încearc ă s ă diferen țieze fomele și m ărimile diferite ale corpului, și s ă
interpreteze pozi țile rezultate pe baza celor deja înv ățate.
2.8 Descrierea Skeleton-ului („ Skeleton tracking ” )
Ipotezele de baz ă ale „ skeleton tracking-ului ” sunt: [6]
• Partea superioar ă a corpului utilizatorului este în cea mai mare par te în interiorul
câmpului de vizualizare. Deci trebuie evitate situa țile de genul: suprapunerea /
contactul direct cu al ți utilizatori sau obiecte din cadrul scenei.
26 • Distan ța ideal ă pentru a vizualizarea întregului corp al utilizato rilor și mi șcările
acestora este cam în jurul distan ței de 2,5 metri.
• Pentru rezultate mai bune, utilizatorul ar trebuie să nu poarte haine foarte largi.
Părul lung ar putea de asemenea degrada calitatea tra cking-ului.
Calibrarea senzorului pentru detec ția corect ă a skeleton-ului este folosit ă pentru
ajustarea modelului scheletului uman la propor țile corpului utilizatorului. Ecalibrarea
este necesar ă înainte de a începe tracking-ul utilizatorului. Ni ci o pozi ție nu este
recunoscut ă pân ă când nu s-a finalizat ecalibrarea. Pasul pentru ec alibrare ține în
prezent câteva secunde (aproximativ 3 secunde). Pen tru ecalibrare utilizatorul trebuie s ă
se afle în fa ța senzorului în urm ătoarea pozi ție ( fig. 1.9)
Fig 1.9 Pozi ția de calibrare. Surs ă [6]
Mâinile și capul utilizatorului trebuie s ă fie complet vizibile pe parcursul duratei
de calibrare. De asemenea utilizatorul nu trebuie s ă țin ă genunchi îndoi ți sau s ă aibe
corpul rotit în acest timp.
Skeleton-ul furnizeaz ă informa ți despre loca ția a maxim 2 utilizatori, care se afl ă
în cadrul scenei, cu date detailate despre pozi ția și orientarea acestuia. Aceste date în
aplica ți le putem g ăsi sub forma unor seturi de puncte, numite pozi țiile skeleton-ului,
care compun un skeleton. Acest skeleton reprezint ă pozi ția curent ă și postura
utilizatorului curent. Skeleton-ul este compus din 20 de puncte, tri-dimensionale, care
se numesc „Joints”, și caracterizeaz ă câte-o zon ă aparte a corpului uman. Acest set de
puncte se poate vizualiza în figura 1.20 a). Pozi țile skeleton-ului utilizatorului sunt
exprimate în coordonatele x,y,z. Spre deosebire de coordonatele imagini de adâncime,
aceste trei coordonate sunt exprimate în metri.
27
a) b)
Fig. 1.10. Punctele Skeleton-ului detectate de senz orul kinect a) , coordonatele
sistemului skeleton-ului și defini ția „Joint-urilor” b). Surs ă [6]
Axele x,y,z sunt axele corpului predefinite de senz orul de adâncime. Acesta este un
sistem de coordonate de tipul mâini drepte care pla seaz ă matricea senzorului în punctul
de origine cu axa pozitiv ă z extins ă în direc ția în care matricea senzorului pointeaz ă.
Axa pozitiv ă y se extinde în sus, iar axa x se extinde la stâng a (cu privire la
matricea senzorului), ca în figura 1.10 b) . Acest sistem cartezian se nume ște spa țiul
skeleton-ului tridimensional.
Dup ă cum se poate observa in fig 1.10 b) skeleton-ul es te împ ărțit în dou ă mari
zone: stânga („Left”) și dreapta („Right”). Aceast ă împărțire este datorat ă faptului c ă
senzorul va percepe imaginea scenei ca în oglind ă, o oglindire o scenei în percep ția
senzorului. S ă presupunem c ă ne afl ăm în fa ța senzorului în pozi ția descris ă în figura
1.10 b) . Dac ă ne uit ăm la ie șirea imagini de adâncime a senzorului, presupus a f i în
modul „oglind ă”, vom observa o reflectare în oglind ă a noastr ă pe ecran, dac ă mi șcăm
mâna dreapt ă vom observa c ă și în imaginea de adâncime se va mi șca mâna din zona
dreapt ă. De aceea algoritmul de scheletizare eticheteaz ă aceast ă parte ca fiind dreapta.
Câteva observa ți cu privire la algoritmul de scheletizare și anumite situa ți în care
ar putea calcula gre șit pozi țile sau orient ările skeleton-ului:
• Urm ărirea mi șcări mâini este mai pu țin stabil ă atunci când bra țul este aproape
de alte p ărți ale corpului, în special de trunchi. Dac ă ambele bra țe sunt apropiate
trunchi, la fel ca și atunci când sunt sunt apropiate ambele bra țe, s-ar putea ca
ambele s ă se amestece.
28 • Urm ărirea picioarelor este într-un fel nesigur ă și posibil eronat ă uneori. Acesta
func ționeaz ă mai bine atunci când utilizatorul st ă cu picioarele separate. De
asemenea mi șcările rapide și complexe ar putea duce la o e șuare a algoritmului.
• Pozi ția corpului poate deveni, de asemenea oarecum insta bil ă, dac ă capul nu
este vizibil.
• Bra țele și picioarele în pozi ți extrem de întinse ( spre exemplu aproape de limit a
de flexibilitate a corpului uman) ar putea fi pierd ute de c ătre tracker.
• În general mi șcările foarte rapide pot cauza eron ări ale algoritmului.
3. Capitolul II
3.1 Platforma .NET ( „ .NET Framework ” )
Platforma .NET este o platform ă general ă pentru dezvoltare de software. Aceasta
se bazeaz ă pe o ma șin ă virtual ă care ofer ă independen ță de programare unui
programator. Include un num ăr mare de biblioteci și asigur ă interoperabilitatea
limbajului (fiecare limbaj poate folosi cod scris î n alte limbaje) de-alungul câtorva
limbaje de programare. Programele scrise pentru .NE T se execut ă într-un mediu
software (ca și contrast cu mediul hardware-ul), cunoscut sub num ele de „Common
Language Runtime” ( CLR ) , care-i o ma șin ă virtual ă care asigur ă importante servici
precum: secutitate, managementul memoriei și manipularea execu ției. Clasele de
biblioteci împreun ă cu CLR constituie platforma .NET.
Biblioteca de baz ă ofer ă : interfe țe utilizator (UI), acces la date, conectivitate la baze
de date, criptare, aplica și web, algoritmi numerici, comunicare în re țea. Programatori
dezvolt ă programe prin combinarea codului lor surs ă cu platforma .NET și alte
biblioteci. Aceast ă platform ă tinde s ă fie utilizat ă de majoritatea noilor aplica ți create
pentru platforma Windows. Mediul de dezvoltare crea t pentru platforma .NET se
numeste Microsoft Visual Studio. Stiva claselor si bibliotecilor din cadrul platformei se
pot vizualiza în figura 2.0.[1]
În creeare aplica ției s-au utilizat clasele / bibliotecile WindowsFor ms , Parallel
LINQ și Task Parallel Library din .NET 4.0, a mediului de dezvoltare C# și a unei
blioteci „Window.Automation”. Acestea vor fi succin descrise în urm ătoarele
subcapitole.
29
Figura 2.1 –stiva de biblioteci a platformei .NET, surs ă [1]
3.2 Mediul de dezvoltare Microsoft Visual Studion 2 010 (C#)
Acest mediu poate fi folosit pentru a dez volta aplica ții tip consol ă sau grafice cu
interfa ță utilizator, aplica ții web, site-uri web și multe altele. Toate acestea se pot
realiza prin cod nativ sau cod gestionat disponibil pentru toate platformele suportate de
Microsoft Windows.
Visual Studio are inclus și suport „IntelliSense” (auto-complete) și desigur
refacorizarea codului (code refactoring). Debugger- ul integrat func ționeaz ă atât la nivel
de cod surs ă și la nivel ma șin ă. Alte unelte integrate în acest IDE includ un „pro iectant
de ferestre” (form designer) pentru aplica ții bazate pe o interfa ță , web designer, class
designer și un designer pentru scheme legate de o baz ă de date. Mediul suport ă și plug-
in-uri cu ajutorul c ărora se poate spori func ționalitatea la apropate toate nivelele –
inclusiv ad ăugarea de suport pentru controlul surselor de siste m și a unor seturi de
unelte noi precum editoare și designer-e visuale.
Visual Studio suport ă diferite limbaje de programare prin intermediul se rviciilor
de limbaje, care permit editorului de cod și a debugger-ului s ă suporte (cu un grad
diferit) aproape orice limbaj de programare, atâta timp cât exist ă acel serviciu de limbaj
specific. Limbajele integrate includ C/C++ (prin in termediul la Visual C++), VB.NET
(prin intermediul la Visual Basic .NET), C# (prin i ntermediul la Visual C#) și F# (care
este nou în Visual Studio 2010). Suport pentru alte limbaje precum M, Phyton, Ruby și
aletele este disponibil prin instalarea separat ă a servicilor acestor limbaje. Suport ă și
XML/XSLT, HTML/XHTML, javaScript și CSS. Exist ă și versiuni de Visual Studio
specifice doar pentru un anumit limbaj care ofer ă posibilit ăți mai limitate utilizatorului
(de exemplu Visual C#).
30 Acest mediu nu are suport pentru orice l imbaj de programare, solu ție sau
instrument intrinsec. În schimb, permite conectarea diferitelor tipuri de func ționalit ăți
(plug-in). O func ționalitate specific ă este codat ă ca un „pachet VS” (VSPackage). Când
este instalat func ționalitatea este disponibil ă ca un serviciu. Acest IDE ofer ă 3 servicii:
SvsSolution, care ofer ă posibilitatea de a enumera proiecte și solu ții, SVsUIShell, care
prevede ferestre și func ționalitate UI (inclusiv filele, bare de instrumente și ferestre
instrument) și SvsShell, care se ocup ă cu înregistrarea VSPackage. În plus, acest mediu,
de asemenea, este responsabil pentru coordonarea și activarea comunica țiilor între
servicii. Toate editoarele, designer-ele, tipurile de proiecte și alte instrumente sunt
implementate ca pachete VS (VSPackages). Visual Stu dio folose ște COM pentru a
accesa aceste pachete. [12]
3.3 Biblioteca Task Parallel
Multe computere din ziua de ast ăzi au Unit ăți Centrale de Procesare (CPU) cu
dou ă sau patru core-uri care permit execu ția simultan ă a mai multor thread-uri. Pentru a
profita de acest avantaj hardware, putem paraleliza codul pentru a distribui codul/
sarcinile pe mai multe procesoare. În trecut parale lizarea cerea manipularea thread-
urilor la nivelul de jos al program ări (low-level). Versiunea „ .NET Framework 4.0”
introduce o mai simpl ă utilizare a thread-urilor prin metode de scriere m ai eficiente, și
scalabilitate de cod paralel într-o expresie natura l ă, f ără a fi nevoie s ă se lucreze direct
cu thread-urile. A șadar s-a introdus o bibliotec ă nou ă numit ă „Task Parallel”. [16]
Biblioteca „Task Parallel” (TPL) este un s et de interfe țe de programare a
aplica ților (API) din cadrul directivelor „System.Threadin g” și
„System.Threading.Tasks”. Rolul acesteia este de a u șura munca dezvoltatorilor de
software în lucrul cu paralelismul la nivelul aplic a ților. Aceasta cre ște gradul de
paralelism din cadrul unei plica ți prin utilizarea eficient ă a tuturor procesoarelor care
sunt disponibile. În plus aceasta se ocup ă de parti ționarea datelor de prelucrat și
schedularea thread-urilor, modul de suspendare a ac estora, și alte detalii de nivel low-
level. În orice caz nu orice secven ță de cod este bine de paralelizat , spre exemplu dac ă
o bucl ă execut ă un mic num ăr de instruc țiuni la fiecar itera ție, sau aceasta nu ruleaz ă
pentru un num ăr mare de itera ți, atunci ad ăugarea paralelismului poate conduce la o
execu ție mai înceat ă a programului. Paralelismul, ca orice cod multithr eading, introduce
o anumit ă complexitate în cadrul execu ției unui program. [16]
31 Paralelismul la nivelul datelor se refer ă la scenariile în care aceea și opera ție este
executat ă în paralel pe elementele unuei colec ți de elemente sau matrici. Paralelismul la
nivel de date este suportat prin câteva supraînc ărc ări ale metodelor „For” și
„ForeEach” în cadrul clasei „System.Threading.Tasks .Parallel”. În acest caz colec țiile
de elemente sunt parti ționate astfel încât multiple thread-uri s ă prelucreze diferite
segmente în paralel. Aceast ă clas ă pune la dispozi ție metodele „Parallel.For” și
„Parallel.ForEach”, care sunte medote de prelucrare în paralel a blocurilor de date.
Programator nu trebuie s ă creeze thread-uri și nici s ă se preocupe de modul de împ ărțire
a blocurilor și alte lucruri de nivel low-level pentru prelucrare a în paralel. Ambele
metode dispun de func ți pentru a putea întrerupe sau opri o bucl ă din execu ție, de a
monitoriza starea buclelor pe alte thread-uri, de a men șine starea local ă a thread-ului,
de finalizare a obiectelor din thread-urile locale, de control al gradului de concuren ță , și
așa mai departe. Aceste func ți sunt: „ParallelLoopState”, „ParallelOptions”,
„ParallelLoopResult”, „CancellationToken” , „Cancel lationTokenSource” . [16], [17]
În cadrul proiectului s-a utilizat metoda „Prallel .For” pentru a cre ște viteza de
prelucrare a unor tablouri de dimensiuni mari de da te.
Beneficile utiliz ări acestei metode se pot observa în urm ătorul exemplu:
Bucla normal ă , secven țial ă, „ For ” :
for (int i = 0; i < 100; i++)
{
doWork(i);
}
Unde func ția „ doWork() ” este o func ție care face ni ște calcule matematice pe numere
aleatoare, corpul func ției este urm ătorul:
private static void doWork(int instance)
{
double result =
Math.Acos(new Random().NextDouble() ) *
Math.Atan2(new Random().NextDouble( ), new Random().NextDouble());
for (int i = 0; i < 20000; i++)
{
result += (
Math.Cos(new Random().NextDoubl e()) *
Math.Acos(new Random().NextDoub le()));
}
}
Rulând aceste cod pe un sistem cu patru core-uri, u n sistem pe care a fost creeat ă și
aplica ția, se poate observe urm ătoarea activitate pe core-uri, fig. 2.2, și o durat ă de
execu ție de aproximativ 14 secunde.
32
Figura 2.2- modul de rulare a programului pe un pro cessor „ Quad Core Q8300 ” cu
frecven ța de procesare de 2.50 GHz.
Scriind aceast ă bulc ă cu ajutorul metodei „Parallel.For” se poate observ a un impact
semnificativ asupra execu ției programului. Acest lucru se poate observa atât prin modul
de împ ărțire a sarcinilor pe cele patru core-uri, figura 2.3 , cât și asupra vitezei de
procesare, aceasta sc ăzând pân ă la 4,7 secunde.
System.Threading.Parallel.For(0, 100, d elegate(int i) // i =>
{
doWork(i);
}
);
Figura 2.3-modul de rulare al programului utilizând metoda „ Parallel.For ” pe acela și
procesor
Sintaxa metodei utilizate, ca și cea din cadrul proiectului, este:
System.Threading.Parallel.For(valoare de start, val oare de stop, i=>
{
doWork(i);
});
Num ărul de thread-uri difer ă de la procesor la procesor în func ție de num ărul de
core-uri disponibile în sistem , de obicei aceste sunt în num ăr de (num ăr-core-uri *2)-1.
De asemenea aceast ă biliotec ă ofer ă și metode pentru crearea și rularea mai
multor task-uri independente în paralel. Un task r eprezint ă o opera ție asincron ă, și într-
o oarecare m ăsur ă este echivalent ă cu creearea unui nou thread cu o prioritate mai ma re.
Utilizarea task-urilor se rezum ă la dou ă benefici:
1. O utilizare mai bun ă și mai eficient ă a resurselor sistemului.
2. Un control programatic mai bun decât cel folosit pe ntru thread-uri. Task-urile
ofer ă un set bogat de API-uri pentru: a șteptare, suspendare, continuare,
manipulare de excep ți, și multe altele.
33 Pentru acestea se folose ște metoda „ Parallel.Invoke ”, care permite rularea oric ărui
num ăr arbitrar de instan țe în paralel. Un exemplu ilustrativ, care execut ă în paralel patru
func ți, date ca și parametri metodei men ționate.
static void Main(string[] args)
{
Parallel.Invoke(A, B, C, D);
}
public static void A(){}
public static void B(){}
public static void C(){}
public static void D(){}
Metodele A(), B(), C(), D() vor fi asignate fiecare unui thread în func ție de
disponibilitatea lor și vor fi executate în paralel. De asemenea num ărul de thread-uri nu
este întotdeauna egal cu num ărul de parametri, acestea variind în func ție de
optimizatorul sistemului care se ocup ă de asignarea thread-urilor.
3.4 Biblioteca UI-Automation
Biblioteca „Microsoft Ui Automation” ofer ă un cadru de accesibilitate care permit
aplica ților Windows s ă pun ă la dispozi ție și s ă consume informa ți programatice despre
interfe țele utilizator (UI-User Interface). Aceasta ofer ă acces programatic spre
majoritatea elementelor componente ale interfe țelor de pe desktop. Aceasta permite
tehnologie asistat ă cum ar fi cititoare de ecran, pentru o oferi infor ma ți despre UI
utilizatorilor și de a manipula UI prin alte mijloace decât standar dele de intrare. UI
Automation permite de asemenea script-uri automate de testare pentru a interac ționa cu
UI. Prin utilizarea acesteia și urmând designe-ul accesibilit ăți practice, dezvoltatori de
programe pot face ca aplica țiile care ruleaz ă pe Windows s ă fie mai accesibile pentru
mul ți utilizatori cu dezabilit ăți de auz, v ăz sau de mi șcare. [18]
Din punctul de vedere ai dezvoltatorilor de softwar e exist ă dou ă modalit ăți de a
utiliza aceast ă bibliotec ă și anume: de a crea sprijin pentru controlul utiliza torilor
(folosind facilit ățile API) și crearea de aplica ți care folosesc interfa ța de baz ă a UI
Automation pentru a comunica cu elementele UI (folo sind API-ul pentru clien ți) .
Aceata expune, fiecare component ă a UI, aplica ției client sub forma unui element
de tipul „AutomationElement”. Aceste elemente sunt cuprinse într-o structur ă
arbirescent ă, cu desktop-ul ca r ădăcin ă. Clien ți pot filtra aceast ă arborescen ță în func ție
de necesit ățile aplica ției lor. De asemenea structura standard a arboresce n ței poate fi
vizualizat ă foarte u șor prin folosirea aplica ției „UI Spy”, care este inclus ă în cadrul
34 setului de dezvoltare. Structura arborescent ă creeat ă de aceast ă bibliotec ă se poate
vizualiza în figura 2.4.
Figura 2.4-arborescen ța creat ă de UI Automation. Surs ă [19]
Obiectele „AutomationElement” expun propriet ățile comune ale elementelor UI
pe care le reprezint ă. Una dintre aceste propriet ăți este cea a tipului de control, care
define ște tipul și func ționalitatea de baz ă a elementului, ca o entitate unic ă de
recunoa ștere ca de exemplu: un buton sau un check box de pe o interfa ță . În plus,
elementele expun modele de control care ofer ă propriet ățile specifice tipului lor de
control. Modelele de control expun și metode care permit clien ților s ă ob țin ă informa ți
spuplimentare despre element și s ă poat ă oferi date de intrare acestuia. Adic ă se pot
selecta, de exemplu, elemente de scriere cum ar fi: textbox-uri, richbox-uri,etc. și se pot
completa cu ce date dorim noi. Ca și dezvoltatori de software aceast ă bibliotec ă ne
permite accesare oric ărui element de pe UI-ul unei aplica ți cât și modificarea
propriet ăților lui și accesul metodelor disponibile ca și cum ar face parte din aplica ția
noastr ă.
De exemplu putem accesa aplica ția „Calculator”, a sistemului de operare, prin
intermediul acestei biblioteci, și s ă-i d ăm comanda s ă adune automat 2 numere. Cu alte
cuvinte se poate accesa orice component ă a calculatorului, orice buton, putem chiar s ă-i
dăm s ă afi șeze și numerele care le adun ă.
3.5 Biblioteca OpenCV ( Emgu )
OpenCV ( Open Source Computer Vision) este o bibliotec ă de func ții de
programare în timp real, dezvoltat ă de Intel. Este liber spre utilizare de c ătre orice
utilizator și se concentreaz ă în principal pe procesarea imaginilor. Se poate lu a gratuit
de la adresa: http://sourceforge.net/projects/opencvlibrary/ . Aceasta poate fi folosit ă
35 pe mai multe platforme de programare. În dezvoltare a proiectului am folosit
„Emgu CV” care este tot OpenCv îns ă proiectat ă special pentru lucrul cu platforma
„ .NET ”. Este o bibliotec ă scris ă în limbajul de programare optimizat „ C ” și poate
profita de procesoarele multicore.
Aceata poate fi utilizat ă la aplica ți de genul: recunoa ștere feței,recunoa șterea
gesturilor, interfe țe om-ma șin ă, la locomo ție, la tracking, recunoa șterea de obiecte, etc.
De asemenea include și algoritmi de înv ățare automat ă cum ar fi: arbori de decizie,
Support Vector Machine (SVM), clasificatori Bayesie ni, re țele neuronale, etc.
4. Capitolul III
4.1 Etapele realiz ării proiectului
În cadrul acestui proiect s-a urm ărit trei idei pricipale și anume: realizarea unei
interfe țe de ecalibrare a senzorului kinect, în func ție de noi utilizatori care doresc s ă
utilizeze interfa ța de lucru, realizarea interfe ței de lucru dintre utilizator și sistemul de
calcul prin intermediul gesturilor, bazate pe util izarea ambelor mâini, și în cele din
urm ă realizarea unei aplica ți interactive gen „ paint”. Deci cele trei problem e care vor
fi rezolvate sunt: realizarea unei aplica ți care s ă ofere utilizatorilor un cadru de lucru și
testare a senzorului kinect, extragerea informa ților de pozi ție de la senzor și
recunoa șterea formelor (mân ă, degete).
Astfel proiectul va oferi un control asupra func ților de baz ă ale mouse-ului și
anume: click drepta, click stânga, dublu click și mi șcarea pe ecran a cursorului, și
controlul asupra aplica ției „ Mozilla Firefox ”, aici putem controla comand a de
„ go-back ” și „ go-forward ”. De asemenea în cadrul aplica ției gen „ paint ” se pot
desena diferite forme, dar se pot manipula și diferite poze, pe care utilizatorul le va
selecta dintr-un fi șier. A șadar aceasta a fost prima etap ă și anume stabilirea scopului și
a obiectivelor acestui proiect.
A doua etap ă const ă în determinarea cerin țelor hardware și software necesare
dezvolt ări proiectului, procurarea senzorului kinect precum și a utilitarelor necesare
pentru accesarea acestuia.
A treia etap ă cuprinde execu ția proiectului sau mai bine spus realizarea scopuri lor
și obiectivelor precizate mai sus. Avansarea în dezv oltarea aplica ției s-a realizat pas cu
36 pas și printr-o serie de test ări (spre exemplu dup ă achizi ționarea senzorului au fost
efectuate teste asupra func țion ări celor dou ă camere, cea de adâncime și cea video,
precum și asupra motorului, de la baza senzorului, a recun oa șteri vocale și a
recunoa șteri skeleton-ului uman). Pentru realizarea proiect ului îns ă, era de ajuns doar
dac ă se testa skeleton-ul și camera de adâncime. Practic întregul proiect a fo st realizat
pe module, urmând ca la final acestea s ă fie puse cap la cap și testate laolalt ă. Astfel
într-o prim ă faz ă s-a realizat partea de ecalibrare a senzorului, at ât în func ție de distan ța
minim ă și maxim ă fa ță de camere cât și a schimb ări unghiului de vizualizare a acestora
prin modificarea pozi ției piciorului motorizabil. Dup ă realizarea acestei etape a urmat
crearea detectoarelor de unghiuri sau mai bine spus a algoritmului de detec ție a
degetelor unei mâini. În mare parte s-a pus accentu l pe lucrul cu mâna dreapt ă, datorit ă
faptului c ă majoritatea utilizatorilor sunt dreptaci. A șadar algoritmi de detec ție a
degetelor au fost concepu ți ini țial doar pentru mâna dreapt ă, iar mai apoi au fost
adapta ți și pentru mâna stâng ă. Dup ă crearea algoritmului de detec ție și num ărare a
degetelor a urmat crearea protocolului de interac țiune dintre utilizator și sistem, ini țial
și acesta a fost conceput tot pentru mâna dreapt ă. Dup ă ce am stabilit protocolul de
control al mouse-ului, care este controlat în princ ipiu de gesturile mâini drepte, am creat
modulul de paint, aici comenzile sunt bazate pe ges turile ambelor mâini. Chiar și a șa,
testarea bunei func țion ări a comenzilor s-a efectuat, ini țial, f ără punerea în func țiune a
comenzilor mouse-ului. Astfel protocolul a fost pro iectat în mare parte principial și
verificat prin afi șare, pe interfa ța de lucru, a st ări fiec ărui gest recunoscut. Dup ă ce
gesturile au fost destul de clar alese și testate, au fost introduse comenzile pentru mouse
și cele pentru desenarea și manipularea imaginilor din cadrul aplica ției interactive de
paint.
Desigur, ca în orice aplica ție interactiv ă , bazat ă pe un control, pot ap ărea efecte
nedorite sau probleme de func ționalitate, care nu apar atunci când un modul
func ționeaz ă independent, îns ă când sunt puse s ă func ționeze împreun ă, unele pot
introduce inferen țe care s ă afecteze buna func ționare a celorlalte. Un exemplu ar fi:
atunci când sunt active ambele interfe țe de lucru, atât cea de control cât și cea de paint,
pot ap ărea mici imperfec țiuni la recunoa șterea exact ă a comenzilor. Acest lucru este
nedorit și trebuie înl ăturat cât mai bine.
În ultima faz ă, dup ă ce au fost rezolvate toate problemele ap ărute, au fost realizate
câteva teste pentru a vedea modul de comportare a î ntregului protocol pe sistemul de
calcul utilizat.
37 Testele au fost destul de greu de realizat datorit ă faptului c ă trebuia s ă se adopte o
pozi ție în care s ă nu se mi ște deloc, ca s ă se poat ă lucra cu debuger-ul oferit de
Microsof Visual Studio. De asemenea testarea thread -urilor a fost foarte mult u șurat ă cu
ajutorul acestui debuger, care a fost îmbun ătățit pentru a facilita lucrul cu thread-uri.
Așadar în dezvoltarea proiectului s-a utilizat ca și component ă hardware un
singur senzor kinect „Xbox 360” și trei componente software: o interfa ță de ecalibrare a
senzorului, o component ă de control a func ților mouse-ului și a aplica ției „ Mozilla
Firefox ” și o aplica ție gen paint, toate fiind componente ale întregului proiect.
Modul de utilizare și conectare a componentelor software cu senzorul ki nect va fi
descris în cele ce urmeaz ă. Cele trei module din figura 3.1 descriu în mare modul de
func ționare a aplica ției.
Figura 3.1 – Schema bloc a aplica ției.
Ini țial aplica ția va accesa modulul de control și detec ție a gesturilor. Acesta este
de fapt interfa ța principal ă a aplica ției din care se pot accesa atât modulul de ecalibra re
a senzorului kinect, interfa ța de ecalibrare, cât și modulul interactiv pentru testarea
gesturilor, care este de fapt aplica ția gen paint.
De remarcat faptul c ă, ceea ce se observ ă în cadrul figuri 3.1, colorat cu verde, nu
este obligatoriu de realizat la fiecare rulare a ap lica ției, ci doar atunci când se schimb ă
utilizatorul. Aplica ția starteaz ă automat cu anumite date despre utilizator, aceste date
38 fiind preluate întotdeauna dintr-un fi șier („ date.txt” ), în care se stocheaz ă ni ște valori
de ecalibrare pentru senzor. Aceste valori rezult ă în urma activ ări modulului de
ecalibrare a senzorului.
Restul modulelor este oarecum obligatorie, vital în s ă pentru controlul func ților
mouse-ului și controlul comenzilor de „ go-back” și „ go-forward” ale aplica ției
„ Mozilla Firefox ” , este modulul de control și detec ție a gesturilor. Al treilea modul,
cel interactiv r ămâne la alegerea utilizatorilor, dac ă vor s ă-l acceseze sau nu. Acesta nu
are un impact negativ asupra bunei rul ări a aplica ției dac ă nu se va accesa deloc.
Trecerea din modulul de ecalibrare în cel de contro l și detec ție a gesturilor se va
face automat, tot printr-un gest al utilizatorului. De asemenea trecerea din al doilea
modul în cel interactiv pentru testarea gesturilor se va face prin op țiunea utilizatorului.
Leg ătura sau mai bine spus interfa ța dintre senzor și cele trei module se
realizeaz ă prin intermediul unei clase „ Kinect.cs ”, în cadr ul c ăreia se vor face set ările
adecvate comunic ări cu senzorul.
Aceast ă clas ă și cele trei module vor fi detailat descrise și am ănun țite în
urm ătoarele subcapitole.
4.2 Interfa ța de leg ătur ă cu senzorul Kinect.
Pentru a se accesa senzorul kinect din cadrul aplic a ției este necesar ă instalarea
unui program special, un driver, „ Kinect for Windo ws SDK ”. Discu țile cu privire la
instalarea și cerin țele minime ale acestuia se reg ăsesc în cadrul capitolului 1,
subcapitolul „ Cerin țe impuse pentru func ționare ”.
Clasa din cadrul aplica ției care se ocup ă de interfa țarea senzorului cu aplica ția se
nume ște „ Kinect.cs ”. În cadrul acesteia se creeaz ă un obiect de tipul senzorului kinect,
se vor seta op țiunile pentru camera de adâncime și pentru prelucrarea skeleton-ului.
Pentru accesarea senzorului, din cadrul aplica ției, este nevoie de importarea unei
referin țe, special conceput ă pentru lucrul cu acest tip de senzor, și anume:
„ Microsoft.Kinect ” . Rolul referin ței este de a realiza accesul aplica ției la toate
metodele și componentele senzorului. Acest lucru îns ă nu este de ajuns, de aceea în
cadrul clasei „ Kinect.cs ” este necesar ă includerea biblioteci „ Microsoft.Kinect ” .
Clasa „ Kinect.cs ” con ține un obiect de tipul „ KinectSensor ”, care repre zint ă un
singur senzor Kinect. Modul de interac țiune dintre acest obiect și senzor cât și dintre
modulul de control se poate vizualiza în cadrul fig uri 3.2. Prin intermediul acestui
39 obiect se pot accesa toate facilit ățile oferite de SDK-ul, oferit de cei de la Microsof t,
pentru acest periferit, și anume: camera de adâncime, camera video, skeleton -ul și
piciorul motorizabil. În unele medii de dezvoltare cum ar fi „ PrimeSense ” se poate
accesa și camera infraro șu.
Figura 3.2-Schimbul de informa ți dintre senzor – obiectul „ KinectSensor ” și
modulul de control și detec ție a gesturilor.
Aceste obiecte „KinectSensor ” sunt elementele unei colec ți de tipul
„ KinectSensorCollection ”. Aceasta con ține o colec ție de senzori Kinect, în sensul c ă la
un sistem de calcul se pot conecta mai multe dispoz itive de acest gen. Pentru a accesa
unul dintre aceste dipozitive este nevoie de o sele c ție, în func ție de statusul acestora, în
sensul c ă se vor selecta doar acele dispozitive care sunt co nectate.
În cadrul aplica ției aceast ă selec ție este ca o interogare, scris ă sub forma:
KinectSensor sensor = from sensorToCheck in Ki nectSensor.KinectSensors
where sensorToCheck.Stat us == KinectStatus.Connected
select sensorToCheck).Fi rstOrDefault();
Prin intermediul acestei sintaxe se va selecta prim ul senzor, conectat și preg ătit de
comunicare cu sistemul, din colec ția de senzori: KinectSensor.KinectSensors , (colec ția
„ KinectSensorCollection ” ).
„ KinectStatus ” este o enumera ție , foarte important ă în lucrul cu senzorul,
datorit ă faptului c ă la orice moment de timp se poate afla stadiul comu nica ției cu acesta.
Aceasta enumera ție contine urm ătoarele elemente:
• „Connected ” – indic ă faptul c ă senzorul este pe deplin conectat și c ă este
preg ătit pentru transmiterea datelor c ătre gazd ă.
• „ DeviceNotGenuine”- dispozitivul nu este autentic.
• „ DeviceNotSupported”- dispozitivul nu este recunos cut de sistemul de calcul.
• „ Disconnected”- dispozitiv deconectat.
• „ Error” – a avut loc o eroare în comunicarea cu se nzorul.
• „ Initializing”- are loc ini țializarea senzorului.
40 • „ InsufficientBandWidth” – USB-ul de conectare al s enzorului la sistem nu are
destul ă l ărgime de band ă necesar ă pentru comunica ție.
• „ NotPowered” –senzorul nu este conectat la sursa d e energie.
• „ NotReady” – anumite componente ale senzorului nu sunt preg ătite înc ă de
comunica ție.
• „ Undefined” –status nerecunoscut.
De asemenea în cadrul acestei clase s-a creeat o me tod ă care seteaz ă
componentele senzorului pentru comunica ția cu sistemul de calcul. Aceat ă metod ă este
apelat ă pentru a realiza recep ția imaginilor de adâncime și a joint-urilor skeleton-ului
utilizatorului. Corpul acesteia este urm ătorul:
public int
testare(System.EventHandler<Microsoft.Kinect.DepthI mageFrameReadyEventArgs>
DepthImageReady,
System.EventHandler<Microsoft.Kinect.SkeletonFrameR eadyEventArgs> SkeletonsReady)
{
int ok = -1;
try
{
if (InitializeKinectServices(this.s ensor, DepthImageReady,
SkeletonsReady) == 1)
ok = 1;
else
ok = 0;
}
catch
{
ok = 0;
}
return ok;
}
Aceasta are ca și parametri dou ă evenimente care se vor ocupa de recep țile provenite de
la senzor. Parametrul „ Microsoft.Kinect.DepthImageFrameReadyEventArgs ” este
responsabil de furnizarea datelor de la evenimentul „KinectSensor.DepthFrameReady”.
Acesta reprezintând momentul când datele unui frame (cadru) sunt preg ătite pentru
transmitere, de la senzor spre sistemul de calcul. Analog, paramentrul
„Microsoft.Kinect.SkeletonFrameReadyEventArgs ” va fi responsabil de recep ția datelor
provenite de la skeleton, de la algoritmul de schel etizare din senzor. Ace ști doi
parametri fac leg ătura spre func țile de tratare a evenimentelor provenite de la senz or.
Astfel cele provenite de la imaginea de adâncime vo r fi tratate de metoda primit ă ca și
parametru prin „ Microsoft.Kinect.DepthImageFrameReadyEventArgs ”, iar cele provenite
de la skeleton vor fi tratate de metoda primit ă ca și parametru prin
„Microsoft.Kinect.SkeletonFrameReadyEventArgs ”.
41 Așadar în cadrul acestei metode se va face ini țializarea serviciilor senzorului,
acest lucru se va realiza prin intermediul metodei: „ InitializeKinectServices ”, al c ărei
corp este urm ătorul:
public int InitializeKinectServices(KinectSensor se nsor,
System.EventHandler<Microsoft.Kinect.DepthImageFram eReadyEventArgs>
DepthImageReady,
System.EventHandler<Microsoft.Kinect.SkeletonFrameR eadyEventArgs> SkeletonsReady)
{
int ok = -1;
// Application should enable all stream s first.
try
{
sensor.DepthStream.Enable(DepthImageFormat.Resoluti on320x240Fps30);
sensor.SkeletonStream.Enable();
sensor.DepthFrameReady += DepthImag eReady;
sensor.SkeletonFrameReady += Skelet onsReady;
sensor.SkeletonStream.Enable(new Tr ansformSmoothParameters()
{
Smoothing = 0.5f,
Correction = 0.5f,
Prediction = 0.5f,
JitterRadius = 0.05f,
MaxDeviationRadius = 0.04f
});
}
catch
{
Console.Write("EROARE INITIALIZARE SENZOR KINECT");
}
try
{
if (!sensor.IsRunning)//numai daca nu ruleaza sa fie startat
sensor.Start();
ok = 1;
}
catch
{
ok = 0;
}
return ok; }
Aceast ă metod ă va returna valoarea 1 în cazul în care s-a reu șit ini țializarea
serviciilor senzorului kinect și 0 altfel.
Metoda „ sensor.DepthStream.Enable(DepthImageFormat.Resoluti on320x240Fps30) ”
activeaz ă serviciul de lucru cu camera de adâncime. Aceasta va creea mereu un frame
(cadru) de dimensiunea: 320X240 și va fi un num ăr de 30 de astfel de cadre pe secund ă.
Parametrul „ DepthImageFormat ” reprezint ă o structur ă prin intermediul c ăruia se
poate seta op țiunile formatului tuturor cadrelor pe care dorim s ă le primim de la senzor.
42 Acestea pot fi de trei tipuri: „ Resolution640x480Fps30 ”, „Resolution320x240Fps30”,
„Resolution80x60Fps30”, la toate difer ă doar rezolu ția cadrelor.
Metoda „ sensor.SkeletonStream.Enable ” va activa serviciul pentru scheletizare a
utilizatorilor. Aceasta va furniza datele skeleton- ului în cadrul rezolu ției setate pentru
camera de adâncime, adic ă 320X240 și se vor furniza tot 30 de cadre pe secund ă.
Sintaxele: „ sensor.DepthFrameReady+=DepthImageReady ” și
„sensor.SkeletonFrameReady+=SkeletonsReady” vor face leg ăturile pentru trat ări
evenimentelor, ap ărute de la senzor, pentru skeleton și pentru imaginea de adâncime.
„DepthImageReady ” și „ SkeletonsReady ” sunt metodele unde se vor face trat ările
evenimentelor pentru imaginea de adâncime respectiv pentru skeleton. Sintaxele
„sensor.DepthFrameReady ” și „sensor.SkeletonFrameReady” sunt evenimentele provenite
de la senzor spre aplica ție în momentul când aceste date sunt gata de transf erat spre
sistem.
Metoda sensor.SkeletonStream.Enable(new TransformSmoothPa rameters()
{
Smoothing = 0.7f,
Correction = 0.5f,
Prediction = 0.5f,
JitterRadius = 0.05f,
MaxDeviationRadius =0.04f
});
va seta parametri de netezire (smoothing ) pentru a lgoritmul de scheletizare.
„TransformSmoothParameters” este o structur ă care contine 6 elemente de netezire care
se vor aplica imagini de adâncime pentru a procesa scheletizarea.
Aceste elemente sunt:
• „Correction” – are rolul de a seta valoarea de core c ție, acesta poate lua valori
între 0.0-nicio corec ție și 1.0 corec ție total ă. Valoare ini țial ă este de 0.5.
Valorile mai mici sunt mai lente în corec ția datelor, iar cele mai mari corecteaz ă
datele brute mai rapid.
• „JitterRadius” – seteaz ă valoarea razei pentru reduc ția de jitter, se d ă în metri.
Valoarea ini țială este 0.05 (5 cm).
• „MaxDeviationRadius” – stabile ște raza maxim ă la care pozitiile filtrate se pot
abate de la datele brute. (un fel de nivel de zgomo t minim).
• „Prediction” – seteaz ă num ărul de cadre predic ționate.
• „Smoothing” – seteaz ă cantitatea de netezire a imagini de adâncime. Ia v alori
între 0.0 –nicio netezire și 1.0-netezire total ă.
43 Conform documentului [20] filtrarea utilizat ă de SDK-ul kinect-ului se bazeaz ă pe
metoda exponen țial dubl ă „ Holt”. Func ția exponen țial ă este utilizat ă pentru a modela
rela țile în care o schimbare în variabila independent ă „x”, d ă aceea și modificare
propor țional ă în variabila dependent ă „ y”, rela ția (1).
(8)
Func ția dublu exponen țial ă este o constant ă ridicat ă la putere de o func ție exponen țial ă.
(9)
Cel mai simplu mod de a netezi o serie de date (pun cte de date m ăsurate la
intervale de timp uniform distante) este de a cacul a o medie mobil ă simpl ă, cu ie șirea ca
fiind media ultimelor „x” puncte de date. Aceast ă nivelare se bazeaz ă pe acest lucru
prin atribuirea de ponderi exponen țial descresc ătoare cu cât datele prelevate sunt mai în
vârst ă; unul sau mai mul ți parametri de filtrare determin ă ponderile atribuite punctelor
de date. Netezirea devine o simpl ă medie ponderat ă a setului anterior de date, anterior
netezite. Aceasta nu va func ționa pân ă când nu a fost recep ționat un num ăr destul de
date. De asemenea nivelarea exponen țial dubl ă se efectueaz ă în dou ă faze. În prima faz ă
datele sunt ajustate la tendin ța perioadei precedente, prin ad ăugarea la ultima valoare de
netezire. În a doua faz ă tendin ța este actualizat ă, este exprimat ă ca difern ța dintre
ultimele dou ă valori. În algoritmul propus de „ Holt” cea de-a d oua trecere nu mai este
necesar ă datorit ă ponderilor. A șadar aceast ă metod ă permite estim ări de nivel (Lt) și
pant ă (Bt), care urmeaz ă s ă fie ajustate la fiecare nou ă observa ție. Un algoritm al
acestui tip de netezire se poate g ăsi în articolul „Double exponential Smoothing
Algorithm” [21].
În cadrul proiectului startarea senzorului se reali zeaz ă doar atunci când acesta nu
ruleaz ă, nu a fost deja startat, pentru c ă el este utilizat și în modulul de ecalibrare dar și
în modulul de control și detec ție a gesturilor. Activarea se face cu ajutorul apel ări unei
metode „ Start”, iar verificarea dac ă acesta nu este deja activat se face prin verificar ea
unui flag de tip boolean „ IsRunning ” .
if (!sensor.IsRunning)//numai daca nu ruleaza sa fi e startat
sensor.Start();
De asemenea în cadrul acestei clase, „Kinect.cs” s- au creeat și metodele pentru
dezactivarea func țion ări senzorului.
public void
UninitializeKinectServices(System.EventHandler<Micr osoft.Kinect.DepthImageFrameRe
adyEventArgs> DepthImageReady,
System.EventHandler<Microsoft.Kinect.SkeletonFrameR eadyEventArgs> SkeletonsReady)
{
sensor.DepthFrameReady -= DepthImageRea dy;
44 sensor.SkeletonFrameReady -= SkeletonsR eady;
}
public void
FinalUninitializeKinect(System.EventHandler<Microso ft.Kinect.DepthImageFrameReady
EventArgs> DepthImageReady,
System.EventHandler<Microsoft.Kinect.SkeletonFrameR eadyEventArgs> SkeletonsReady)
{
sensor.DepthFrameReady -= DepthImageRea dy;
sensor.SkeletonFrameReady -= SkeletonsR eady;
sensor.Stop();
}
Metoda „ UninitializeKinectServices ” va dezactiva handlerele de tratare a
evenimentelor, f ără a opri definitiv senzorul. Aceasta este utilizat ă în cadrul modulului
de ecalibrare. Se opteaz ă pentru aceasta metod ă datorit ă faptului c ă la trecerea dintr-un
modul în altul trebuiesc schimbate doar handlerele de tratare a evenimentelor primite de
la senzor.
Metoda „ FinalUninitializeKinect ” va fi apelat ă doar atunci când se va ie și din
aplica ție. Dac ă nu s-ar apela metoda „Stop() ”, pentru senzor, ace sta ar r ămâne activ,
ruleaz ă în continuare, îns ă poate fi accesat de alte aplica ți.
Aceast ă clas ă se instan țiaz ă o singur ă dat ă, și se creeaz ă un singur obiect de tipul
„KinectSensor ” pentru întreaga aplica ție.
4.3 Modulul de ecalibrare a senzorului Kinect.
Acest modul este obligatoriu de activat doar atunci când se schimb ă utilizatorul,
astfel se pot evita micile nepl ăceri cum ar fi: neîncadrarea total ă a mâinilor în cadrul
imaginilor procesate și distan ța de recunoa ștere a gesturilor poate fi mai mic ă. De
re ținut este faptul c ă cu cât mâna utilizatorului este mai mare cu atât a lgoritmul merge
mai bine și distan ța de recunoa ștere a gesturilor cre ște. De semenea, întregul algoritm se
găse ște în cadrul clase: „ Ecalibrare.cs”.
Modul de func ționare a acestui modul este descris, în pa și mari, în cadrul figuri
3.3.
Explicarea componentelor acestui modului se va real iza în cele ce urmeaz ă.
A. Partea de segmentare a imagini de adâncime.
Segmentarea imagini se realizeaz ă la primirea fiec ărui cadru de la senzor.
Acesta este realizat ă în cadrul func ției de tratare a evenimentului de primire a unui
cadru de adâncime de la senzor.
45 Setarea metodelor de tratare a evenimentelor atât p entru imaginea de adâncime cât
și pentru skeleton, s-a realizat în cadrul proiectul ui prin urm ătoarea secven ță de cod:
if (GlobalClass.Senzor.testare(DepthImageReady, Ske letonsReady) == 1)
this.status.Text = "senzor kinect f unctional";
else
this.status.Text = "eroare senzor k inect";
„ GlobalClass” este o clas ă intermediar ă utilizat ă pentru memorarea elementelor de care
este nevoie s ă fie accesate din toate celelalte module. Aceasta a re de fapt rolul de clas ă
global ă în care se vor memora valorile globale ale aplica ției, evitând astfel și multipla
instan țiere a acestora. În cadrul ei sunt implementate doa r func țiile de setare și accesare
a obiectelor globale. De asemenea aceast ă clas ă nu are nevoie de instan țiere, nu are
constructor, elementele ei fiind accesate prin nume le clasei și con ține trei elemente:
un obiect de tipul „ Kinect ” , unul de tipul „ Eca librare ” și unul de tipul „ Control”.
Obiectul „ Kinect” este cel prin care se va face co nexiunea la senzor, de tipul clasei
descrise în subcapitolul 3.2, obiectul de tipul „Ec alibrare” reprezint ă modulul de
ecalibrare a senzorului, iar obiectul de tipul „Con trol” reprezint ă modulul de control și
detec ție a gesturilor. Prototipul acesteia este urm ătorul:
class GlobalClass
{
private static Kinect senzor;
private static Ecalibrare secundar;
private static Control primar;
public static Kinect Senzor
{
get { return senzor; }
set { senzor = value; }
}
public static Ecalibrare Secundar
{
get { return secundar; }
set { secundar = value; }
}
public static Control Primar
{
get { return primar; }
set { primar = value; }
}
}
}
Așadar prin secven ța de cod if (GlobalClass.Senzor.testare(DepthImageReady,
SkeletonsReady) == 1) se va testa dac ă senzorul este func țional și se va atribui metodele
de tratare a evenimentelor, trimise de la sensor, p rin metodele „ DepthImageReady ” și
„SkeletonsReady”.
46
Figura 3.3 – Schema bloc a modulului de ecalibrare a senzorului kinect.
47 Deci segmentarea imagini se va realize în cadrul co rpului metodei
„DepthImageReady ”. În cadrul acestui pas, segmentarea imagini repre zint ă parcurgerea
imagini de adâncime, preluate de la senzor, și detectarea tuturor obiectelor din harta de
ID-uri, despre care am discutat în capitolul 2, car e apar țin utilizatorului curent. Adic ă va
rămâne mai departe în imaginea de procesare doar corp ul utilizatorului care va avea
culoarea alb ă.
Corpul acestei metode este urm ătorul:
private void DepthImageReady(object sender, DepthIm ageFrameReadyEventArgs e)
{
using (this.imageFrame = e.OpenDepthIma geFrame())
{
if (imageFrame != null)
{
imageFrame.CopyPixelDataTo(this .pixelData);
. . . . . . . . . . . . . . . . . . . . . .
DoW1(this.pixelData);
unsafe
{
fixed (byte* po = this.dept hFrame32)
{
IntPtr ptr = (IntPtr)po ;
BitmapAdancimeMaini1 = new Bitmap(320, 240, 960,
System.Drawing.Imaging.PixelFormat.Format32bppRgb, ptr);
ImagineFaraBackground = new Image<Emgu.CV.Structure.Rgb,
byte>(BitmapAdancimeMaini1);
img = new Image<Emgu.CV .Structure.Rgb, byte>(BitmapAdancimeMaini1);
}
}
}
}
}
În momentul când sistemul va notifica aplica ția c ă un cadru de adâncime este
gata, prin evenimentul „ DepthFrameReady”, se utili zeaz ă acest eveniment pentru a
copia datele pixelilor de la senzor într-un vector, „ pixelData ”, de tipul, de date, „short”.
Astfel pentru a accesa cadrul de date, care este re turnat de la senzor, utilizez metoda
„OpenDepthImageFrame()”. Prototipul acesteia este: „public DepthImageFrame
OpenDepthImageFrame()”. O dat ă ce am ob ținut accesul la cadru, utilizez metoda
„ CopyPixelDataTo ”, pentru a copia datele în memoria local ă.
Dup ă ce datele au fost copiate într-un vector, se va ap ela algoritmul de segmentare
al imagini, realizat prin intermediul metodei „ DoW1 ”. În cadrul acesteia se va parcurge
întregul vector de date, al imagini de adâncime, pe ntru a identifica toate obiectele care
sunt unic identificate de ID-urile utilizatorilor. Astfel se va creea o imagine în cadrul
căreia vor r ămâne doar utlizatori.
Corpul acestei metode este urm ătorul:
private void DoW1(short[] pixel)
48 {
int player;
int index, indexColor;
Parallel.For(0, 239, y =>
{
for (int x = 0; x < 320; x++)
{
index = (y * 320 + x);
player = pixel[index] & DepthImag eFrame.PlayerIndexBitmask;//7
if (player != 0)//player index
{
indexColor = (y * 320 + x) * 4;
this.depthFrame32[indexColor] = 255;
this.depthFrame32[indexColor + 1] = 255;
this.depthFrame32[indexColor + 2] = 255;
}
}
});
}
Pentru a rula cât mai repede aceast ă c ăutare am utilizat metoda „ Parallel.For”,
despre care am men ționat în capitolul 2. Datele despre pixeli noi imag ini, care va
con ține doar copurile utilizatorilor, vor fi p ăstrate într-un vector, „depthFrame32”, de
dimensiune: rezolutie_imagine_de adâncime *4 (320*2 40*4). Am înmul țit cu 4 pentru
că informa ția de culoare a unui pixeli va fi stocat ă sub forma RGBA, unde R reprezint ă
valoarea pentru culoarea ro șu, G-verde, B-albastru și A-informa ția alfa. Cele 4
informa ți vor avea fiecare un byte (1 octet), deci culoarea obiectelor din noua imagine
va fi reprezentat ă pe 32 de bi ți.
Informa țile preluate de la senzor cuprind atât date despre ID-urile utilizatorilor,
adic ă obiectele care apar țin aceluia ș utilizator, cât și informa ți despre adâncime, cât de
aproape sau de departe se g ăsesc obiectele de senzor. Astfel fiecare pixel din imaginea
de adâncime este reprezentat pe 16 bi ți, din care utlimi 3 bi ți reprezint ă indexul
utilizatorului, iar restul, de 13 bi ți, reprezint ă datele despre adâncime. Fiecare obiect
care apar ține utilizatorului va avea codificat pe cei 3 bi ți ID-ul acestuia, celelalte
obiecte av ănd codificat 0, adic ă nu apar țin nici unui utilizator. Se poate observa, dup ă
cum am mai men ționat, c ă num ărul maxim de utilizatori din cadru nu poate fi mai mare
decât 7, de la 1 la 7 inclusiv.
Dac ă presupune c ă informa ția de adâncime este de forma:
{0100 1011 1001 0}{010}, atunci pentru a afla index ul utilizatorului se realiz ă un ȘI
logic între aceasta și „ DepthImageFrame.PlayerIndexBitmask ”, care are valoarea 0x07,
ca mai jos:
49 (0100 1011 1001 0010) AND (0000 0000 0000 0111) = 0 000 0000 0000 0010 = 2, deci
ID-ul utilizatorului va fi 2.
Pentru a afla informa ția de adâncime se va realiza o shiftare la dreapta cu 3 bi ți ca mai
jos:
(0100 1011 1001 0010) >> 3= 0000 1001 0111 0010 = 2418 ( mm).
Deci în aplica ției fiecare utilizator va avea corpul desenat cu al b, în cadrul imagini
rezultate în urma segment ări.
if (player != 0)//player index
{
indexColor = (y * 320 + x) * 4;
this.depthFrame32[indexColor] = 255;
this.depthFrame32[indexColor + 1] = 255;
this.depthFrame32[indexColor + 2] = 255;
}
Variabila „ indexColor” va fi offset-ul pixelului d in cadrul imagini de adâncime, unde y
reprezint ă num ărul liniei, iar x num ărul coloanei.
Dup ă finalizarea execu ției acestei metode se merge mai departe, în cadrul metodei
„ DepthImageReady ”, și se va creea un pointer c ătre vectorul în care se p ăstreaz ă datele
segment ări cu scopul de a forma din acestea o imagine de ti p Bitmap, spre a fi folosit ă
mai apoi pentru restul prelucr ărilor .
Declara ția „ using ” din cadrul metodei are rolul de a defini un domen iu de
aplicare, în afara c ăruia un obiect sau mai multe obiecte vor fi elimina te. Deci orice
obiect creeat în cadrul declara ției va fi valabil doar în interiorul acesteia, în a far ă acesta
va fi distrus, în sensul c ă se vor elibera toate resursele care iau fost aloca te. Acest lucru
se va realiza prin apelarea metodei „IDisposable” , o metod ă specific ă limbajului de
programare C#.
Cuvântul cheie „ unsafe ” denot ă un context nesigur, ceea ce este necesar pentru
orice opera ție care implic ă pointeri. F ără aceast ă directiv ă în cadrul limbajului de
programare C# nu se pot folosi pointeri.
De asemenea cuvântul cheie „ fixed ” previne colectorul „garbage collector ” de la
relocarea unei variabile mobile. Aceast ă declara ție este permis ă numai într-un context
nesigur și stabile ște un pointer la o variabil ă și pointeaz ă aceea și variabil ă în timpul
execu ției. Deci nu putem folosi aceste variabile, pointer i, în afara acestei declara ți. F ără
aceast ă declara ție pointeri c ătre variabile mobile ar fi imposibili deoarece cole ctorul de
resurse ar putea muta variabilele imprevizibil. Com pilatorul C# ne permite s ă atribuim
pointeri numai variabilelor aflate intr-o zon ă fix ă.
Rezultatul procesului de segmentare se poate vizua liza în figura 3.4 b) .
50
a) b)
Figura 3.4 – Compara ție între imaginea nesegmentat ă a) și cea segmentat ă b)
Aceast ă seven ță de cod va fi rulat ă la fiecare cadru primit de la senzor.
B. Selec ție skeleton utilizator.
Selec ția skeleton-ului utilizatorului este necesar ă în detec ția pozi ției mâini
drepte și pentru a putea prelua exact m ărimea optim ă pentru încadrarea mai departe a
mâinilor.
Preluarea setului de coordonate 3D ale skeleton-ulu i, se realizeaz ă în momentul
când sistemul va notifica c ă datele specifice acestuia sunt gata, aceasta reali zându-se
prin evenimentul „SkeletonFrameReady”. La apari ția acestui eveniment datele despre
pixeli, provenite de la senzor, sunt copiate în vec torul de tipul „Skeleton”. Structura
„Skeleton” con ține informa ți despre un cadru de date provenite din pipeline-ul de
scheletonizare. Aceasta con ține: timpul de procesare al imagini de adâncime pen tru a
creea aceast cadru skeleton, num ărul cadrului celui mai recent cadru de adâncime,
coordonatele planului podelei, și un vector de tipul structuri „SkeletonData”. Fiec are
element al vectorului de structuri „SkeletonData” c on ține informa ți cu privire la un
singur skeleton, în esen ță ea este cea care ne ofer ă coordonatele skeleton-ului,
con ținând un vector de 4 coordonate de tipul structuri „Joints”. Trei coordonate sunt: x,
y, z, iar cea de a patra este vectorul unitate. Str uctura „Joints” este indexat ă de
elementele enumera ției „JointType” care con ține cele 20 de joint-uri specifice unui
skeleton. De asemenea „SkeletonData” con ține o enumera ție care ne indic ă care
elemente din aceast ă structur ă con ține date valide. Aceasta se nume ște
„SkeletonTrackingState” și con ține 3 elemente, cea care ne intereseaz ă în cadrul
51 dezvolt ări proiectului este „SkeletonTrackingState.Tracked” , care ne indic ă faptul c ă
toate pozi țile joint-urilor sunt urm ărite. Acesta va fi utilizat la selec ția skeleton-ului
utilizatorului.
Secven ța de cod pentru cele men ționate se găse ște în corpul metodei cu prototipul
private void SkeletonsReady(object sender, Skeleton FrameReadyEventArgs e)
și este urm ătoarea:
using (SkeletonFrame skeletonFrame = e.OpenSkeleton Frame())
{
if (skeletonFrame != null)
{
Skeleton firstplayer;
//Gets the length of the skelet on array.
if ((this.skeletonData == null) ||
(this.skeletonData.Length != skeletonFrame.Skeleto nArrayLength))
{
this.skeletonData = new Ske leton[skeletonFrame.SkeletonArrayLength];
this.SkeletStatus.Text = "s keleton functional";
}
skeletonFrame.CopySkeletonDataT o(this.skeletonData);
firstplayer = (from s in this.s keletonData where s.TrackingState ==
SkeletonTrackingState.Tracked select s).FirstOrDefa ult();
}
}
Prin intermediul instruc țiuni:
if ((this.skeletonData == null) ||
(this.skeletonData.Length != skeletonFrame.Skele tonArrayLength))
se verific ă mereu dac ă trebuie s ă se m ăreasc ă lungimea vectorului de primire a datelor
de tipul „ Skeleton” de la sensor. Astfel „skeleton Frame.SkeletonArrayLength”
reprezint ă num ărul de elemente din cadrul skeleton-ului.
C. Preluare coordonate 3D pentru mâna dreapt ă.
Dup ă selectarea skeleton-ului corespunz ător utilizatorului, explicat în sec țiunea
anterioar ă, se poate prelua foarte simplu coordonatele 3D cor espunz ătoare joint-ului
mâini drepte.
Secven ța de cod, care se afl ă tot în corpul metodei „ SkeletonsReady ”,
corespunz ătoare este urm ătoarea:
if (firstplayer != null && firstplayer.Joints.Count > 0)
{
Joint rigthHandJoin = firstplayer.Joints[JointType. HandRight];
pctDreapta = GetSkeletonPosition(rigthHa ndJoin.Position);
}
Se verific ă dac ă în cadru exist ă vre-un utilizator și dac ă i s-a putut prelua joint-urile
despre skeleton-ului. Apoi se va prelua joint-ul co respunz ător mâini drepte. Preluarea
52 coordonatelor 3D ale acesteia în coordonatele imagi ni de adâncime se realizeaz ă prin
metoda „GetSkeletonPosition”. Corpul func ției este urm ătorul:
public System.Windows.Point GetSkeletonPositio n(SkeletonPoint joint)
{
DepthImagePoint pct;
pct = GlobalClass.Senzor.sensor.MapSkel etonPointToDepth(joint,
DepthImageFormat.Resolution320x240Fps30);
return new System.Windows.Point((int)pc t.X, (int)pct.Y);
}
Metoda „ MapSkeletonPointToDepth ” va mapa un punct, de tipul celor de adâncime,
provenit de la joint-ul primit ca și parametru, al skeleton-ului, utilizând unu anumit
format, în cazul aplica ției „ DepthImageFormat.Resolution320x240Fps30 ”. Deci aceast ă
metod ă va returna coordonatele 3D reale, în formatul imag ini de adâncime, pentru mâna
dreapt ă.
D. Preluare zon ă de interes din cadrul imagini de adâncime.
Acest pas este realizat cu scopul de a mic șora imaginea asupra c ăreia se fac
prelucr ările, astfel se mic șoreaz ă automat și timpul de prelucrare pentru procesare. Este
unul dintre cei mai importan ți pa și, fiindc ă întregul algoritm, restul pa șilor, se bazeaz ă
pe aceast ă nou ă imagine.
Dup ă ce restul pa șilor anteriori au fost parcur și cu succes se adopt ă o reducere a
spa țiului imagini de prelucrat. Acest lucru se realizea z ă prin secven ța de cod:
GetRoiMana(this.ImagineFaraBackground), care se reg ăse ște în corpul metodei
„SkeletonsReady”. Parametrul acestei func ți este întreaga imagine rezultat ă în urma
pasului de segmentare a imagini de adâncime. M ărimea zonei de interes este definit ă ca
fiind un dreptunghi de m ărime: 60X60 , de m ărime fix ă, pentru a face încadrarea mâini
mai u șor.
Corpul metodei este urm ătorul:
public void GetRoiMana(Image<Emgu.CV.Structure.Rgb, Byte> img)
{
this.rectD.X = (int)pctDreapta.X – 30;
this.rectD.Y = (int)pctDreapta.Y – 30;
this.rectD.Height = 60;
this.rectD.Width = 60;
img.ROI = rectD;
using (imageD = new Image<Rgb, byte>(im g.ROI.Size))
{
imageD = img.Copy();
}
}
53
Zona de interes este un p ătrat, de fapt, sub numele „ rectD ” . Coordonatele: „ rectD.X ”
și „rectD.Y” definesc coordonatele din stânga sus ale acestuia, acest lucru se poate
vizualiza în figura 3.5 a). De asemenea coordonatel e: X și Y ale mâinii drepte se g ăsesc
în mijlocul p ătratului.
Așadar conform teoriei, mijlocul p ătratului se g ăsesc la coordonatele
(rectD.width + rectD.width/ 2, rectD.height – rectD .height/ 2) , deci pentru a afla
punctele rectD.X și rectD.Y se va face o transla ție pe axa X cu valoarea „ –
rectD.width/2 ” și pe axa Y cu „ – rectD.height/2 ”.
Pentru a seta zona de interes în cadrul imagini s-a utilizat metoda „ROI ” din
cadrul biblioteci Emgu (OpenCv), care va defini o r egiune rectangular ă în cadrul
imagini, ilustra ție în figura 3.5 b), asupra c ăreia se poate aplica diferite metode de
prelucrare. [22]
a) b)
Figura 3.5- a) Modelul de construc ție a zonei de interes, b) Ilustrarea modului de
ac țiune a zonei de interes,sursa [22].
Mai departe aceast ă regiune va fi copiat ă într-o zon ă de memorie, „imageD ”, prin
intermediul metodei „ Copy() ” din cadrul biblioteci Emgu. A șadar mai departe procesare
se va efectua asupra imagini imageD.
54 E. Extragere contur mân ă, polinom hull, și a celui mai mic dreptunghi care
încadreaz ă conturul
Dup ă ce s-a definit zona de interes se vor aplica alori tmi de procesare asupra
imagini pentru a putea mai apoi calcula m ărimea zonei de interes și distan ța optim ă de
lucru a senzorului.
Prelucrarea se realizeaz ă în cadrul corpului metodei „ ExtractContourAndHull ”.
Corpul acesteia este urm ătorul:
private void ExtractContourAndHull(Image<Emgu.CV.St ructure.Rgb, Byte> image)
{
Image<Gray, byte> skin = image.Convert<Emgu .CV.Structure.Gray, Byte>();
using (MemStorage storage = new MemStor age())
{
Contour<Point> contours =
skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHO D.CV_CHAIN_APPROX_SIMPLE,
Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
Contour<Point> biggestContour = nul l;
Double Result1 = 0;
Double Result2 = 0;
while (contours != null)
{
Result1 = contours.Area;
if (Result1 > Result2)
{
Result2 = Result1;
biggestContour = contours;
}
contours = contours.HNext;
}
if (biggestContour != null)
{
Contour<Point> currentContour =
biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
hull =
currentContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTA TION.CV_COUNTER_CLOCKWISE);
box = currentContour.GetMinArea Rect();
}
}
}
Imaginea de procesat este mai întâi convertit ă în nuan țe de gri cu ajutorul metodei
„ image.Convert<Emgu.CV.Structure.Gray, Byte>() ”, din cadrul biblioteci Emgu.
Aceast ă metod ă realizeaz ă media aritmetic ă a componentele de culoare, ale imagini
Rgb, iar rezultatul îl va memora în cadrul noi imag ini: „ Image<Gray, byte> skin ”.
Structura „ MemStorage ” este utilizat ă pentru a stoca structuri de date dinamice,
cresc ătoare, cum ar fi: secven țe de date, contururi, grafuri, subdiviziuni, etc. A ceasta
este organizat ă sub forma unei liste de blocuri de memorie de dime nsiuni egale, câmpul
„ botom” reprezint ă începutul acestei liste iar câmpul „top ” va repre zenta blocul
55 current utilizat, dar nu îneap ărat și ultimul bloc din list ă. Toate lucurile dintre „ bottom”
și „top”, nu inclusiv și ultimul, sunt considerate complet ocupate, iar to ate blocurile
dintre „ top” și ultimul bloc, sunt considerate libere și partea „top” este par țial ocupat ă-
spa țiul liber con ține num ărul de octe ți r ăma și la finalul zonei „top ”.
Structura acesteia este urm ătoarea:
typedef struct CvMemStorage
{
struct CvMemBlock* bottom;/* primul bloc alocat */
struct CvMemBlock* top; /* blocul current utilizat- vârful stivei */
struct CvMemStorage* parent; /* împrumut ă noi blocuri din memorie */
int block\_size; /* m ărimea blocului */
int free\_space; /* spa țiul liber în cadrul blocului current dat de num ărul de octe ți din bloc */
} CvMemStorage
Conturul se va realiza cu ajutorul func ției „ FindContours ” din cadrul biblioteci
Emgu. Un contur este o list ă de puncte care reprezint ă, într-un fel sau altul, o curb ă într-
o imagine. Aceat ă reprezentare poate fi diferit ă, depinde de circumstan țe. În Emgu
contururile sunt reprezentate de secven țe în care fiecare intrare, în secven ță , codific ă
informa țiile despre loca ția urm ătorului punct de pe curb ă. [23]
Prototipul func ției este urm ătorul:
int FindContours(
CvChainApproxMethod method = CV_CHAIN_APPROX_SIMPLE ,
CvContourRetrievalMode mode = CV_RETR_LIST,
CvMemStorage* storage,
);
Unde parametrul CV_RETR_LIST – reprezint ă modul de reprezentare a contururilor
unei imagini, figura 3.9. Acesta preia toate contururile din cadrul imagini și la adaug ă
într-o list ă; CV_CHAIN_APPROX_SIMPLE -reprezint ă metoda de aproximare a
contururilor , acestea sunt reprezentate sub forma lan țului „Freeman ”, figura 3.6 b) ,
îns ă este o metod ă mai simplificat ă prin care se vor comprima segmentele: verticale,
orizontale și diagonale p ăstrând doar punctele terminale ale acestora.
Pentru g ăsirea contururilor se utilizeaz ă o metod ă derivat ă din cea propus ă de
Suzuki și Abe [26] . Aceast ă metod ă se bazeaz ă pe urm ărirea contururilor din cadrul
imaginilor binarizate. Aceasta deriv ă o secven ță de coordonate din lan țul de coordonate
ale conturului de l, grani ța dintre o component ă conectat ă reprezentat ă de pixeli de 1,
(component ă 1) și o component ă conectat ă reprezentat ă de pixeli de 0 (component ă 0-
fundalul sau o gaur ă în contur). Pentru a face aceast ă separa ție în cadrul imagini se
56 utilizeaz ă dou ă tipuri de conecxiuni între pixeli: conexiunea de o rdin 4 și cea de ordin 8,
ilustrare figua 3.7.
a) b)
Figura 3.6- a) – lan țul de mi șcări numerotate de la 0-7, b)-modul de reprezentare a
contururilor prin lan țul Freeman, surs ă [23]
Figura 3.7-cenexiunile între pixeli vecini, surs ă [24]
Așadar o component ă de tipul 0 trebuie privit ă ca o conexiune de 8 (4) pixeli, iar cele
de tipul 1 ca o conexiune de 4 (8), ilustrare a împ ărțiri unei imagini în figura 3.8.
Figura 3.8-ilustrare împ ărțire imagine binarizat ă în componente de tipul 0 și 1, surs ă
[23]
57
În cadrul figuri 3.8 componentele etichetate cu „ c X ” reprezint ă un contur, iar
cele etichetate cu „ hX ” reprezint ă o gaur ă sau fundalul, iar „ X” este un num ăr. Unele
dintre aceste contururi, cele cu linie întrerupt ă, reprezint ă contururile exterioare ale
regiunilor albe (ale componentelor 1), iar cele cu linie punctat ă care pot fi contururi
interioare sau un contur exterior al unei g ăuri (componentele de 0). A șadar fiecare
component ă 1 are o singur ă frontier ă exterioar ă care-o separ ă de componenta 0 din jur,
iar g ăurile sunt date de separa țile dintre o component ă 1 și una de 0, cu condi ția ca
componenta de 0 s ă fie înconjurat ă de cea de 1.
La sfâr șitul g ăsiri contururilor se va creea arborescen ța de conturui, ilusta ție
figura 3.9 pentru imaginea din figura 3.8.
Dup ă ce am ob ținut secven ța de contururi, trebuie c ăutat cel mai mare contur,
adic ă acel contur a c ărui arie este cea mai mare, fiindc ă acesta va costitui de fapt
conturul mâini utilizatorului. Deci se va parcurge întreaga secven ță de contururi și se va
prelua aria fiec ăruia.
while (contours != null)
{
. . . . .
contours = contours.HNext;
}
Figura 3.9- ilustrare a arborescen ței rezultate în urma algoritmului de detec ție a
contururilor, surs ă [23].
58 ipixiyPreluarea ariei fiec ărui contur se realizeaz ă cu ajutorul func ției „ Area ”,
(contours.Area;).
Aceast ă func ție calculeaz ă aria unei regiuni, contur, în cazul aplica ției, compus din „n”
puncte : = ( , ) , 0<=i<=n, 0p=np , ca un moment spa țial : [24].
(10) Arie = 21∑
=− −−n
iiiiiyxyx
11 1
Dup ă g ăsirea conturului mâini, se calculeaz ă polinomul hull. Polinomul hull
reprezint ă cel mai mic polinom convex care încadreaz ă perfect o anumit ă regiune, în
cazul aplica ției, o secven ță de puncte. Acest lucru se realizeaz ă cu ajutorul func ției, din
Emgu, „GetConvexHull”. Se caut ă acest polinom convex tocmai pentru a putea mai
apoi s ă se g ăseasc ă m ărimea optim ă, a regiuni de interes, în care se va încadra mâna
dreapt ă. C ăutarea aceasta va fi descris ă în urm ătoarea sec țiune (pas al implement ări) .
Aceast ă func ție utilizeaz ă algoritmul Sklansky. Un semialgoritm al acestuia s e
găse ște în sursa [27].
1. Se caut ă un vertex convex și se eticheteaz ă cu 0p.
2. Restul punctelor r ămase se eticheteaz ă în ordinea acelor de ceasornic,
începând cu 0p .
3. Se plaseaz ă trei „ monede” pe vertexurile urm ătoare și se eticheteaz ă:
0p – „ back ”, 1p- „center ”, 2p- „ front”.
4. În cazul în care cele trei monede formeaz ă un viraj la dreapta (sau sunt
colineare ),
– se ia „back ” și se plaseaz ă pe vertexul din înaintea celei „ front” .
– apoi partea „ back” devine „front ”, „ front” dev ine „ center”, iar „ center ”
devine „back ”.
Dac ă nu (cele trei monede formeaz ă un viraj la stânga) :
– se ia „ center” și se plaseaz ă pe vertexul din spatele monedei„ back”.
– se înl ătureaz ă vetexul pe care a fost „ center ”
– apoi „ center” devine „ back”, „ back” devine „ cen ter”.
5. Repet ă pasul 4 pân ă când „front” se suprapune peste vertexul 0p, cel de
început și monedele formeaz ă un viraj la dreapta.
În urma rul ări acestui algoritm va rezulta o secven ță de vertexuri care formeaz ă
polinomul convex, ilustra ție figura 3.10 b).
59
a) b)
Figura 3.10 – a) imagine ini țial ă, b)- imagine cu contur și polinomul convex hull.
Dup ă aflarea vertexurilor polinomului convex hull, se c aut ă centru conturului,
pentru c ă distan ța optim ă va ține cont de centrul conturului. Pentru aceasta se c aut ă cel
mai mic dreptunghi care încadreaz ă acest contur, acel dreptunghi de arie minim ă care
încadreaz ă conturul. Metoda utilizat ă se nume ște: „GetMinAreaRect” și este tot o
metod ă din Emgu. Aceast ă metod ă va returna o structur ă care con ține: vertexuri, în
num ăr de 4, în ălțime, l ățimea , aria, și alte detali care descriu acest dreptunghi. Metoda
se folose ște de polinomul hull pentru a-l încadra într-un dre ptunghi, ilustrare figura 3.11
sau fig. 3.26 b).
Figura 3.11 – dreptunghiul circumscris polinomului convex hull.
F. Calcularea celei mai mari distan țe de la centrul mâini la polinomul hull
Dup ă cum am men ționat anterior , centrul mâini va fi de fapt centru l conturului
acesteia, adic ă centrul dreptunghiului care încadreaz ă acest contur. A șadar se va
parcurge întreaga secven ță de vertexuri ale polinomului hull, și se va calcula distan ța de
la acestea la centrul dreptunghiului. Se va alege c ea mai mare distan ță , cu ideea c ă
aceasta va include cel mai bine întreaga mân ă a utilizatorului. Metoda, din cadrul
60 aplica ției, care se ocup ă de acest cacul este: „ GetMaxRaza() ”, care va returna indexul
vertexului a c ărui dinstan ță este maxim ă. Corpul acesteia este urm ătorul:
public void GetMaxRaza()
{
hullArray = hull.ToArray();
double dist = 0, max = 0;
int index = 0;
for (int i = 0; i < hullArray.Length; i ++)
{
dist = Math.Pow(box.center.X – hull Array[i].X, 2) +
Math.Pow(box.center.Y – hullArr ay[i].Y, 2);
if (dist > max)
{
max = dist;
index = i;
}
}
this.indexi = index;
}
G. Vizualizare rezultat pe interfa ța cu utilizatorul.
Dup ă parcurgerea pa șilor anteriori se pot vizualiza rezultate algoritmu lui pe
interfața de lucru cu utilizatorul, dar nu înainte de a cal cula exact raza cercului
circumscris, care este de fapt m ărimea optim ă a zonei de interes, și distan ța maxim ă de
la centrul conturului mâini spre extremele acestuia , polinomul hull. Raza cercului
înscris mâini, în urma unor teste, s-a dovedit a fi de m ărime optim ă cam la jum ătatea
razei mari.
razaDreaptaMare = (float)linie.Length;
razaDreaptaMica = razaDreaptaM are / 2;
Rezultatele și interfa ța de lucru pot fi vizualizate în figura 3.12.
De asemenea din cadrul interfe ței se poate modifica și pozi ția motoarelor cu
ajutorul unui slide bar. Se pot vizualiza și anumite detalii cu privire la distan ța mâini
drepte a utilizatorului fa ță de senzor, raza cercului circumscris și raza cercului înscris.
În aceast ă figur ă imaginea cu mâna utilizatorului, partea stâng ă, ilustreaz ă distan ța
maxim ă g ăsit ă, de la centul mâini la extremele acesteia, linia d e culoare portocalie, iar
imaginea din dreapta ilustreaz ă razele cercurilor, cercul galben este cel circumsc ris, cel
albastru este cel înscris, ambele având razele calc ulate pân ă atunci .
61
Figura 3.12- interfa ța de lucru cu utilizatorul pentru modulul de ecalib rare a senzorului
kinect .
H. Salvare date ecalibrare senzor.
Condi ția de salvare și p ărăsire a modulului de ecalibrare const ă în momentul când
utilizatorul las ă mâna dreapt ă în jos. Din momentul acesta se vor salva trei vari abile în
fi șierul „date.txt ”. Cele trei date sunt: distan ța final ă a mâini utilizatorului fa ță de
senzor, raza cercului circumscris și raza cercului înscris. Aceste date vor fi mai apo i
utilizate în modulul de control și detec ție a gesturilor.
Aceast ă salvare este util ă datorit ă faptului c ă utilizatorul nu mai trebuie s ă refac ă
ecalibrare senzorului de fiecare dat ă când se releaz ă aplica ția. Datele sunt preluate și
validate în cadrul modulului de control.
4.4 Modulul de Control și Detec ție a Gesturilor.
Acest modul este esen ța aplica ției, aici au loc toate prelucr ările gesturilor, precum
și a activ ări comenzilor atât pentru controlul mouse-ului cât și pentru cele dedicate
modulului interactiv, aplica ția gen paint. Și acest modul se va conecta direct la senzorul
kinect.
62
Figura 3.13
63 Acest modul este compus din urm ătoarele clase: „ Control.cs ”, „
ManaDreapta.cs”, „ ManaStanga.cs”, „HarrisCorner.cs ” , „ Mouse.cs ” .
Modul de func ționare a acestui modul se poate vizualiza în cadrul figuri 3.13,
unde sunt descri și pa și de implementare a acestui modul.
Explicarea modului de implementare a fiec ărui pas, din figura 3.13, și a modului
de func ționare a acestuia sunt descrise mai jos.
A. Segmentarea imagini de adâncime.
Ca și în cazul modulului prezentat anterior și aici avem nevoie de segmentarea
imagini pentru a putea procesa mai u șor imaginile. De asemenea și aici vom avea cele
dou ă metode de tratare a evenimentelor provenite de la senzor, și anume:
„DepthImageReady” și „SkeletonsReady ” din cadrul clasei „Control.cs”.
De asemenea și în acest caz segmentarea se va realiza în corpul metodei de tratare
a evenimentului de apari ție a imagini de adâncime. Recep ționarea datelor despre pixeli
se realizeaz ă în aceea și manier ă ca și în cazul modulului de ecalibrare, îns ă fa ță de
acesta, aici avem strict nevoie, în imagine, doar d e mâini.
Algoritmica din spatele acesteia pleac ă de la premiza c ă utilizatorul va avea
întotdeauna mâinile în fa ța corpului, adic ă distan ța mâinilor pân ă la senzor s ă fie mai
mic ă decât distan ța pân ă la cap (aceast ă condi ție se va verifica în metoda
„SkeletonsReady ”) .
Așadar pentru a r ămâne doar cu ambele mâini în cadru se va parcurge î ntreaga
imagine de adâncime, provenit ă de la senzor , și se va p ăstra doar acele componente,
părți ale corpului utilizatorului, care se g ăsesc la cea mai mic ă distan ță fa ță de acesta.
Acest lucru se va realiza într-un mod paralel, cu a jutorul metodei
„System.Threading.Tasks.Parallel.Invoke ” . Cu ajutorul acesteia se va încerca rularea
în
paralel a 10 metode, care au rolul de a c ăuta cea mai mic ă distan ță la care se afl ă una
dintre componentele corpului utilizatorului. Întrea ga logic ă se g ăse ște în cadrul corpului
metodei „ DoBackgroundWork ”. Secven ța paralelizabil ă este scris ă în urm ătorul mod:
System.Threading.Tasks.Parallel.Invoke(
() => CautAdancime(this.pixel Data, 0),
() => CautAdancime1(t his.pixelData, 7680),
() => CautAdancime2(t his.pixelData, 15360),
() => CautAdancime3(t his.pixelData, 23040),
() => CautAdancime4(t his.pixelData, 30720),
() => CautAdancime5(t his.pixelData, 38400),
64 () => CautAdancime6(t his.pixelData, 46080),
() => CautAdancime7(t his.pixelData, 53760),
() => CautAdancime8(t his.pixelData, 61440),
() => CautAdancime9(t his.pixelData, 69120)
);
Astfel fiecare thread va avea de c ăutat într-un set de 7680 de pixeli. În totalitate
sunt 320X240, adic ă 76800, un num ăr destul de mare de parcurs pe un sigur fir de
execu ție, a șadar am decis s ă le împart pe 10 fire ca totul s ă se execute mult mai repede.
Toate metodele sunt identice, difer ă doar zona de început și cea de sfâr șit asupra
căruia se va prelucra. Corpul unei astfel de metode e ste prezentat mai jos:
private void CautAdancime(short[] pixel, int start)
{
int DistantaMaximaKinectime = 5000;
short player;
int realDepth;
int fin = 7680 + start;
for (int i16 = start; i16 < fin; i16++)
{
player = (short)(pixel[i16] & DepthImage Frame.PlayerIndexBitmask);//7
realDepth = pixel[i16] >> DepthImageFram e.PlayerIndexBitmaskWidth;//
if (player != 0)
{
if (realDepth < DistantaMaximaK inectime)
DistantaMaximaKinectime = r ealDepth;
}
}
this.ad[0] = DistantaMaximaKinectime;
}
Fiecare thread va c ăuta, în zona lui, distan ța minim ă pentru fiecare utilizator și o
va ad ăuga într-un vector de minime, și anume: „ this.ad ”.
Dup ă ce s-a g ăsit distan ța minim ă, se vor prelua din imaginea de adâncime toate
obiectele identificate unic de ID-urile utilizatori lor, care se g ăsesc la distan ța dat ă de
intervalul [distan ță minim ă-100, distan ță minim ă+100], adic ă în vecin ătatea distan ței
minime. Acest lucru este necesar pentru a putea pre lua doar mâinile, f ără nimic altceva.
Segmentarea propriu-zis ă se realizeaz ă de abea acum. Și în acest caz se va utiliza
paralelizarea, secven ța de cod care se ocup ă de aceasta este urm ătoarea:
Parallel.Invoke(
() => DoW1(this.p ixelData, max, min, 0),
() => DoW2(this.p ixelData, max, min, 32),
() => DoW3(this.p ixelData, max, min, 64),
() => DoW4(this.p ixelData, max, min, 96),
() => DoW5(this.p ixelData, max, min, 128),
() => DoW6(this.p ixelData, max, min, 160),
() => DoW7(this.p ixelData, max, min, 192),
() => DoW8(this.p ixelData, max, min, 224),
() => DoW9(this.p ixelData, max, min, 256),
() => DoW10(this. pixelData, max, min, 288)
65 );
Variabilele „ max ” și „ min ” desemneaz ă adâncimea minim ă și maxim ă de
acceptare a pixelilor din imaginea de adâncime.
max = this.DistantaMaximaKinect + 100;
min = this.DistantaMaximaKinect – 100;
Și în acest caz metodele sunt indentice, ceea ce dif er ă fiind zonele asupra c ăruia se
realizeaz ă procesarea. Și în acest caz fiecare thread va ac ționa asupra 7680 de elemente.
Corpul unei astfel de metode este urm ătorul:
private void DoW1(short[] pixel, float max, float min, short start)
{
short player;
int realDepth;
int index, indexColor;
short stop =(short) (start + 32);
for (short y = 0; y < 240; y++)
{
for (short x = start; x < stop; x++)
{
index = (y * 320 + x);
player =(short) (pixel[index] & DepthImag eFrame.PlayerIndexBitmask);//7
realDepth = pixel[index] >> DepthImageFra me.PlayerIndexBitmaskWidth;
if (player != 0)//player index
{
if (realDepth >= min && rea lDepth <= max)
{
indexColor = (y * 320 + x) * 4;
this.depthFrame[indexCo lor] = 255;
this.depthFrame[indexCo lor + 1] = 255;
this.depthFrame[indexCo lor + 2] = 255;
}
}
}
}
}
Imaginea rezultat ă în urma segment ări este ilustrat ă în figura 3.14.
Figura 3.14- imaginea segmentat ă.
66 B. Selec ție skeleton.
Selec ția skeleton-ului este identic ă cu cea de la modulul de ecalibrare, preluarea
setului de joint-uri ale corpului utilizatorului, a dic ă a informa ților despre pozi ția
utilizatorului, este preluat ă în cadrul metodei „ SkeletonsReady ” din cadrul clasei
„Control.cs ”.
Tot în cadrul acestei metode se vor realiza și urm ători pa și.
C. Preluare coordonate 3D pentru cele dou ă mâini, cap și sholduri.
Dup ă ce selec ția skeleton-ului utilizatorului a fost realizat ă se poate prelua oricare
dintre cele 20 de coordonate 3D ale corpului utiliz atorului.
Preluarea coordonatelor 3D atât pentru ambele mâini și sholduri c ăt și pentru cap
este vital ă pentru a procesa mai departe restul pa șilor.
Dintre cele 3 coordonatele specifice loca ției capului se va utiliza doar cele de pe
axa Y și de pe axa Z. Cea de pe axa Z este util ă pentru a ști dac ă utilizatorul are mâinile
în fa ța corpului, iar cea de pe axa Y este utilizat ă pentru mi șcarea mouseului, și
validarea pozi ților mâinilor. De obicei pentru a se face recunoa șterea corect ă a gestului
trebuie s ă fim mai aproape de senzor, iar dac ă ridic ăm mâna mai sus de nivelul capului
s-ar putea ca mâna s ă ias ă din unghiul de vizualizare al camerei.
Coordonatele mâinilor vor fi utilizate pentru pozi ționarea zonei de interes și
pentru calcularea m ărimi acesteia.
Coordonatele sholdurilor sunt utilizate în validare a gesturilor, acest lucru va fi
explicat pe parcurs.
Preluarea acestor coordonate se realizeaz ă în cadrul aplica ției prin urm ătoarea
secven ță , g ăsit ă în cadrul metodei „ SkeletonsReady ” din cadrul clasei „Control.cs ” :
Joint rigthHandJoin = firstplayer.Joints[JointType. HandRight];
//selectez mana dreapta
Joint leftHandJoin = firstplayer.Joints[JointType. HandLeft];
//selectez mana stanga
pctDreapta = GetSkeletonPosition(rigthHandJoin.Po sition);
pctStanga = GetSkeletonPosition(leftHandJoin.Posi tion);
var pctSholdD = GetSkeletonPosition(firstplayer.Joi nts[JointType.HipRight].Position);
var pctSholdS = GetSkeletonPosition(firstplayer.Joi nts[JointType.HipLeft].Position);
var cap = GetSkeletonPosition(firstplayer.Joints[Jo intType.Head].Position);
Metoda „ GetSkeletonPosition ” este aceea și cu cea de la modulul de ecalibrare.
67 D. Calcul m ărimi zone de interes pentru ambele mâini.
Acest pas este foarte important în cadrul acestui m odul. M ărimea zonelor de
interes este modificat ă atât în func ție de datele preluate de la modulul de ecalibrare, cât
și de distan ța mâinilor fa ță de senzor. Prin recalcularea continu ă a acestor dimensiuni se
reduce m ărimea dimensiunilor imaginilor asupra c ărora se vor aplica urm ători pa și.
Astfel dac ă utilizatorul se va apropia de senzor dimensiunea z onei de interes va cre ște,
iar dac ă se va dep ărta aceasta se va mic șora.
Acest lucru se realizeaz ă prin urm ătoarea secven ță de cod (exemplu doar pentru
calculul dimensiuni zonei de interes pentru m ăna dreapt ă, similar se realizeaz ă și pentru
mâna stâng ă):
//regula de trei simpla pentru aflare raza cerc cir cumscris pentru patratul meu
//scalare cerc dupa adancime user mana
//presupun ca utilizatorul are aceeasi marime pentr u amandoua mainile
razanouaD = (float)((float)(this.constantaM + 15) / rigthHandJoin.Position.Z);
this.rectD.X = (int)pctDreapta.X – (int)razanouaD / 2;
this.rectD.Y = (int)pctDreapta.Y – (int)(razanouaD / 1.25);
this.rectD.Height = (int)razanouaD + 10;
this.rectD.Width = (int)razanouaD + 5;
razaD = (float)((float)(this.constataMica – 7) / r igthHandJoin.Position.Z);
Pentru calcularea acestor noi dimensiuni se va folo si regula de trei simpl ă,
ilustrat ă mai jos.
Să presupunem c ă dup ă ce s-a realizat modulul de ecalibrare, noile date despre
adâncimea optim ă și m ărimile razelor cercurilor circumscris și înscris sunt „x1, x2, x3
”.
Așadar pentru calculul noi m ărimi a zonelor de interes se realizeaz ă regula:
Pentru adâncimea x1……………………….. avem raza cercului circumscris x2
Pentru noua adâncime x4 ( știut ă)………….avem raza x
Deci (11) x= 12*4
xxx = x4*q (o constant ă egal ă cu 12
xx).
Variabila „ constantaM ” este de fapt constanta pentru calculul noi raze a cercului
circumscris, notat ă cu „ razanouaD ”. Similar se calculeaz ă și raza cercului înscris, notat ă
cu „ razaD ”. Variabila „x4” din exemplu va fi distan ța mâini fa ță de senzor, adic ă
coordonata Z, valoarea de adâncime.
68 Modul de construc ție a dreptunghiului, pentru delimitarea zonelor de interes , este
similar cu cel ilustrat în figura 3.5 a), îns ă de aceast ă dat ă va fi un dreptunghi.
E. Preluare zone de interes din imaginea de adâncime.
Dup ă ce s-a calculat dimensiunea clar ă a dreptunghiului, pentru a delimita cele
dou ă zone de interes, care încadreaz ă, separat, mâna stâng ă și cea dreapt ă, se pot creea
dou ă noi imagini care vor con ține doar palmele mâinilor. Aceast ă opera ție este
executat ă numai în cazul în care mâinile se g ăsesc deasupra sholdurilor și nu se
reg ăsesc deasupra nivelului capului. Acest lucru este s emnalizat printr-un flag: „ validD ”
, pentru mâna dreapta și „validS” , pentru mâna stâng ă. Modul de setare / resetare a
acestor flag-uri este realizat prin urm ătoarea secven ță de cod:
if (pctDreapta.Y < pctSholdD.Y &&
rigthHandJoin.Position.Z<firstplayer.Joints[JointTy pe.Head].Position.Z)
validD = 1;
else
validD = 0;
if (pctStanga.Y < pctSh oldS.Y && leftHandJoin.Position.Z <
firstplayer.Joints[JointType.Head].Position.Z)
validS = 1;
else
validS = 0;
Modul de preluare a acestora este analog aceluia ș algoritm folosit și la modulul de
ecalibrare. Rezultatul acestei opera ți poate fi vizualizat în figura 3.15.
Figura 3.15 –Ilustrarea rezultatului în urma aplic ări pasului de preluare a zonelor
de interes.
69 F. Extragere contururi mâini, polinome hull, a celor mai mici dreptunghiuri
care încadreaz ă conturul și a defectelor polinomului hull. (valabil pentru
ambele mâini).
Acest pas este identic pentru ambele mâini. A șadar voi explica algoritmul doar
pentru mâna dreapt ă. Metodele care se ocup ă de aceast ă parte se g ăsesc în cadrul
claselor: „ManaDreapta.cs” și „ ManaStanga.cs” și se numesc
„ExtractContourAndHull”.
Partea de g ăsire a conturului mâini este identic ă cu cea de la modulului de
ecalibrare a senzorului, îns ă aici conturul va fi salvat în cadrul unei imagini de
dimensiune: 100X100. Aceast ă imagine va fi utilizat ă în pasul calculului intersec ților cu
linile de control. De asemenea și polinomul convex hull va fi salvat în cadrul unei
imagini de aceea și dimensiune, urmând ca aceasta s ă fie utilizat ă mai apoi la pasul de
detectare a num ărului de degete ale mâini. Secven țele de cod care se ocup ă de acestea
sunt:
Fcontur.Draw(biggestContour, new Rgb(Color.White), 1);
CvInvoke.cvDrawContours(hullimag, hull, new MCvScal ar(255, 0, 0), new
MCvScalar(255, 0, 0), 0, 2, Emgu.CV.CvEnum.LINE_TYP E.CV_AA, new Point(0, 0));
În acest caz imaginea pentru contur va fi: „ Fcontur ”, în cadrul c ăreia se va
desena conturul mâini cu o culoare alb ă, iar imaginea pentru polinomul hull va fi
„hullimag ” în cadrul c ăreia acesta va fi colorat cu ro șu.
De asemenea tot în interiorul acestei metode se vor afla și a șa numitele defecte de
convexitate, ilustra ție figura 3.16 . Aceast ă metod ă utilizeaz ă polinomul hull și conturul
obiectului din cadrul polinomului. A șadar aceste defecte reprezint ă diferen ța dintre
polinomul hull și conturul obiectului.
Acestea sunt utilizate mai apoi la pasul de calcula re a num ărului de degete.
Metoda de preluare a acestor defecte este „ GetConvexityDefacts ”, iar secven ța
urm ătoare reprezint ă apelul acesteia:
defectArray = biggestContour.GetConvexityDefacts(st orage,
Emgu.CV.CvEnum.ORIENTATION.CV_COUNTER_CLOCKWISE);
Așadar aceasta se aplic ă conturului mâini, și va returna un vector de tipul
„ CvConvexityDefect” , orientate (numerotate) în or dinea acelor de ceasornic. Aceast ă structur ă este
de forma: [25]
70
Figura 3.16-ilustrarea defectelor unei mâini, (A-H)
typedef struct CvConvexityDefect
{
CvPoint* start; /* punctul conturului de unde înc epe defectul */
CvPoint* end; /* punctul conturului unde se termi n ă defectul */
CvPoint* depth_point; /* cel mai îndep ărtat punct fa ță de punctual hull care are defect*/
float depth; /* distan ța dintre punctual cel mai îndep ărtat și polinomul convex hull*/
} CvConvexityDefect;
O ilustra ție a defectelor unei mâini se poate vizualiza în ca drul figuri 3.17, a
rezultatului acestei mâini. În cadrul acestei figur i punctele ro și reprezint ă punctele
„depth_point ” (de adâncime), iar cele verzi sunt atât pucte de „ start ” (de început) cât și de
„end ” (de sfâr șit). De obicei, în cazul mâinilor, punctul de „ end ” al unui defect coincide
cu cel de „ start ” al urm ătorului defect, de aceea aceste puncte nu sunt dese nate cu alte
culori.
Num ărul acestor puncte difer ă în func ție de pozi ția mâini, de forma acesteia și de
înclina ția acesteia în cadrul imagini.
Figura 3.17-rezultatul algoritmului de detec ție a defectelor de convexitate.
71 G. Caculul m ărimi dreptunghiului înscris mâini. (valabil pentru ambele
mâini)
Acest pas este important pentru detec ția degetelor utilizatorului, din cadrul
fiec ărei imagini rezultate în urma pasului de preluare a zonelor de interes din imaginea
de adâncime. Acesta va fi foarte util la pasul de c alculare a num ărului de degete și a
detec ției gesturilor pentru controlul mouse-ului și al aplica ției gen paint. Se calculeaz ă
în aceea și manier ă cu calcularea dreptunghiului pentru zona de intere s. Urm ătoarea
secven ță de cod ilustreaz ă calculu pentru dreptunghiul înscris pentru mâna st âng ă.
this.rectSmic.X = (int)stanga.box.center.X – (int)r azaS;
his.rectSmic.Y = (int)stanga.box.center.Y – (int)ra zaS;
this.rectSmic.Height = (int)razaS * 2; ;
this.rectSmic.Width = (int)razaS * 2;
unde variabila „ stanga.box.center ” reprezint ă centrul conturului mâini stângi
care a fost calculat în pasul anterior, variabila „ razaS ” reprezint ă raza cercului înscris
acesteia, calculat ă analog ca cea a cercului circumscris.
Similar se va proceda și pentru calcularea m ărimi dreptunghiului înscris mâini
drepte. Rezultatul acestui pas este ilustrat în fig ura 3.18
Figura 3.18 – ilustrarea rezultatului pasului de ca lculare a dreptunghiului înscris.
H. Calcul num ăr degete mâini.
Dup ă cum am mai men ționat un rol foarte important în detec ția num ărului de
degete îl are pasul anterior (F) și anume acela de detec ție a defectelor de convexitate ale
conturului mâini. Tot ca și în cadrul pasului anterior voi explica algoritmul utilizat doar
pentru mâna dreapt ă, pentru mâna stâng ă fiind similar.
Metoda care se ocup ă de acest lucru, pentru mâna dreapt ă se nume ște
„DrawAndComputeFingersNumD ” și se g ăse ște în cadrul clasei „ ManaDreapta.cs”, iar
72 pentru mâna stâng ă „ DrawAndComputeFingersNumS ” și se g ăse ște în interiorul clasei
„ManaStanga.cs”.
Acest algoritm se va executa numai în anumite condi ți, și anume atunci când
mâna noastr ă va fi dreapt ă,îndreptat ă în sus. Adic ă este nevoie ca aceasta s ă aibe
contact, sau mai bine spus s ă existe un contact cu o linie de control aflat ă în partea de
jos a imagini asupra c ăruia se va executa algoritmul. Acest lucru îns ă nu este de ajuns,
se dore ște oarecum ca mâna s ă fie orientat ă cu degetele în sus, în urma intersec ției cu
linia de control se asigur ă faptul c ă mâna este în sus, îns ă nu se poate spune c ă și
degetele sunt orientate tot în susul imagini. O ilu stra ție a acestei valid ări se poate
observ ă în figura 3.19.
Cele dou ă puncte de contact cu linia de control, în cadrul f iguri desenat ă cu ro șu,
sunt colorate cu verde. Punctul colorat cu galben r eprezint ă mijlocul acestei lini de
control. Pentru a asigura oarecum orientarea mâini cu degetele în sus se pune condi ția
ca punctul de mijloc al acestei drepte de control s ă fie între cele dou ă puncte de
intersec ție.
Metoda care se ocup ă de acest lucru se nume ște „ ValidareGestDreapta ” și se afl ă
în cadrul clasei „Control.cs ”.
Figura 3.19-ilustrare a pozi ției valide pentru algoritmul de num ărare al degetelor
mâinilor.
Corpul acestei metode este urm ătorul:
public bool ValidareGestDreapta()
{
Point pct2 = new Point();
Point pcentru = new Point();
int distanta;
Rgb r = new Rgb(System.Drawing.Color.Wh ite);
LineSegment2D linie;
/* căutarea primului punct de contact cu linia de c ontrol de la stanga la dreapta*/
for (short x = 0; x < imageD.Width – 1; x++)
{
if (imageD[this.imageD.Height – 7, x].Equals(r))
{
73 pct1.X = x;
pct1.Y = imageD.Height – 2;
break;
}
}
for (short x = (short)(imageD.Width – 1 ); x >= 0; x–)
{
if (imageD[this.imageD.Height – 7, x].Equals(r))
{
pct2.X = x;
pct2.Y = imageD.Height – 2;
break;
}
}
distanta = (int)(Math.Abs(pct1.X – pct2 .X));
linie = new LineSegment2D(pct1, pct2);
pcentru.X = imageD.Width / 2;
pcentru.Y = imageD.Height – 7;
if (pcentru.X > pct1.X + distanta / 4 & & pcentru.X < pct2.X)
//daca se afla mijlocul liniei intre pct de contact 1 si 2 al mainii cu dreapta de control
{
return true;
}
else
return false;
}
Similar va ar ăta și metoda de validare a pozi ției pentru mâna stâng ă. Aceasta se
nume ște „ ValidareGestStanga ” și se afl ă implementat ă tot în clasa „Control.cs ”.
Dup ă procesul de validare a pozi ției se trece mai departe la implementarea
propriu-zis ă a algoritmului de num ărare a degetelor. Acest algoritm se bazeaz ă pe
unghiul creeat între dou ă degete consecutive, și pe rezultatul algoritmului de g ăsire a
defectelor specifice mâini. Metoda, din cadrul apli ca ției, care se ocup ă de acest lucru se
nume ște „ DrawAndComputeFingersNumD ”, pentru mâna dreapt ă, și se afl ă implementat ă în
cadrul clasei „ManaDreapta.cs”, iar pentru mâna stâ ng ă, aceasta este
„ DrawAndComputeFingersNumS ” și se afl ă implementat ă în cadrul clasei „ManaStanga.cs”.
Așadar acest algoritm se bazeaz ă în principiu pe ipoteza c ă unghiurile dintre dou ă
degete este ascu țitunghic, ilustrare în figura 3.20 a). Unghiurile A -D sunt unghiurile
care ne intereseaz ă în principiu. Acestea sunt de fapt unghiurile form ate de punctele de
defect, și anume: între punctele de început, de adâncime și de sfâr țit al unui element de
tipul structuri „ CvConvexityDefect” , care au rezultat în urma algoritmului de găsire a
defectelor.
Pentru a afla tipul acestor unghiuri s-a utiliza te orema cosinusului.
Teorema cosinusului (numit ă și regula cosinusului pentru laturi) este o teorem ă
referitoare la unghiurile și laturile unui triunghi. Aceat ă teorem ă este aplicabil ă oric ărui
tip de triunghi și este enun țat ă astfel:
74 Într-un triunghi oarecare ABC, cosinusul unghiului „ α” este egal cu raportul
dintre diferenta sumei p ătratelor laturilor unghiului, cu p ătratul laturii opuse unghiului,
și dublul produsului laturilor unghiului, ilustra ție in figura 3.20 b).
a) b)
Figura 3.20-a)-unghiuriele de interes dintre degete le mâini, b)-ilustrare a teoremei
cosinusului într-un triunghi oarecare.
Formula acestei teoreme, conform cu ilustra ția din figura 3.20 b) este urm ătoarea:
(12) αcos ***2222bccba −+= ;
Așadar în func ție de semnul cosinusului se poate afla natura unghi ului calculat.
Pentru a fi ascu țitunghic semnul acestuia trebuie sa fie pozitiv (ad ic ă se afl ă în
cadranul I sau IV).
Aceast ă teorem ă nu se va aplica tuturor punctelor de defecte g ăsite, ci doar
acelora care vor avea punctele de adâncime în cadru l cercului înscris mâini și care vor
avea punctele de start și de sfâr șit deasupra acestuia, ilustra ție in figura 3.21. Se adopt ă
aceast ă abordare tocmai pentru a scoate din calcul restul punctelor care nu fac parte din
cele care caracterizeaz ă degetele.
Dup ă aceast ă selec ție se va mai face înc ă o clasificare a punctelor r ămase, acestea
trebuie s ă aibe adâncimile deasupra, pe axa Y, centrului cont urului mâini (în figura 3.21
punctul de culoare mov este centrul conturului mâin i calculat la pasul F). Se adopt ă și
aceast ă clasificare datorit ă faptului c ă din anumite pozi ți ale mâini, mai ales în ceea ce
prive ște pozi ția degetului mare, se poate accepta anumite puncte care nu sunt în esen ță
degetele utilizatorului.
75
Figura 3.21-ilustrare cerc înscris și defetele g ăsite.
Dup ă aceasta clasificare se va aplica teorema cosinusul ui. Prima dat ă se vor
calcula m ărime laturilor care compun unghiul (ilustrare figur a 3.20 a) ) , iar apoi
urmeaz ă o evaluare a acestor m ărimi. Se verific ă dac ă acestea sunt destul de mari astfel
încât s ă fie cu siguran ță acolo un deget. Compararea se face cu în ălțimea celui mai mic
dreptunghi care încadreaz ă conturul mâini, mai exact cu o zecime din m ărimea acestuia.
Aceast ă dimensiune a fost aleas ă în urma mai multor test ări. Acest pas este necesar
deoarece, în cazul în care utilizatorul va ține mâna închis ă, îns ă un prea bine strâns ă
astfel înc ăt s ă se încadreze în totalitate în cercul înscris, este posibil ca algoritmul s ă
detecteze degete false. Exemple illustrate în figur a 3.22
Pentru toate punctele care au trecut de aceste clas ific ări se va calcula dimensiunea
celei de a treia laturi, se va aplica teorema cosin usului, și se va verifica natura unghiului
rezultat.
Figura 3.22-exemple care pot duce la falsa detec ție a degetelor.
76
Dup ă execu ția acestui pas toate puncte care au trecut vor fi p ăstrate separat într-o
colec ție de puncte, se vor p ăstra toate cele trei puncte caracteristice unui def ect. Aceast ă
salvare este necesar ă mai apoi pentru procesul de prelucrare a recunoa șteri gesturilor.
O observa ție foarte important ă este aceea c ă algoritmul num ără de fapt „g ăurile”
din conturul mâini. Deci se pleac ă de la ipoteza c ă toate defectele care au trecut de
aceste clasific ări formeaz ă o astfel de „gaur ă”, și ca aceasta este alc ătuit ă din dou ă
degete.
Corpul unei astfel de func ți este urm ătorul:
public void DrawAndComputeFingersNumD(Image<Emgu.CV .Structure.Rgb, Byte> image,
float razaMare, float raza)
{
this.fingerNumD = 0;
double unghi;
double a, b, c;
short nr = 0;
PointF startPoint = new PointF();
CircleF depthCircle1;
PointF depthPoint = new PointF();
PointF endpoint = new PointF();
float marime = box.size.Height / 10;
depthCircle1 = new CircleF(box.center, raza + ma rime);
float q = (float)Math.Pow(depthCircle1.Radius, 2 );
try
{
if (degete != null || degete.Count > 0)
degete.Clear();
if (defectArray != null && hullArray != null && defectArray.Count() > 1)
{
for (short i = 0; i < this.defectArray.Length ; i++)
{
startPoint.X = (float)defectArray[i].Start Point.X;
startPoint.Y = (float)defectArray[i].Start Point.Y;
depthPoint.X = (float)defectArray[i].Depth Point.X;
depthPoint.Y = (float)defectArray[i].Depth Point.Y;
endpoint.X = (float)defectArray[i].EndPoin t.X;
endpoint.Y = (float)defectArray[i].EndPoin t.Y;
if (Math.Pow(depthCircle1.Center.X – startPoint.X, 2) + Math.Pow(depthCircle1.Center.Y –
startPoint.Y, 2) >= q &&//distanta de la pct start l acentrul cercului
Math.Pow(depthCircle1.Center.X – endpoint.X, 2) + M ath.Pow(depthCircle1.Center.Y – endpoint.Y,
2) >= q &&
Math.Pow(depthCircle1.Center.X – depthPoint.X, 2) + Math.Pow(depthCircle1.Center.Y –
depthPoint.Y, 2) < q)//sa fie toate in afara cercul ui maini
{
if (hullArray.Contains(defectArray[i].StartPoin t) &&
hullArray.Contains(defectArray[i].EndPoint)&& defec tArray[i].DepthPoint.Y < box.center.Y + raza)
{
//regula triunghiului cosinusului
c = Math.Sqrt((defectArray[i].DepthPoint.X – defectArray[i].StartPoint.X) *
(defectArray[i].DepthPoint.X – defectArray[i].Start Point.X)
+ (defectArray[i].DepthPoint.Y – defectArray[i].Sta rtPoint.Y) * (defectArray[i].DepthPoint.Y –
defectArray[i].StartPoint.Y));
b = Math.Sqrt((defectArray[i].DepthPoint.X – defec tArray[i].EndPoint.X) *
(defectArray[i].DepthPoint.X – defectArray[i].EndPo int.X) +
(defectArray[i].DepthPoint.Y – defectArray[i].EndPo int.Y) * (defectArray[i].DepthPoint.Y –
defectArray[i].EndPoint.Y));
//ptr ca daca nu ia si ce-i mai mic…knd degetele sunt inchise
//pentru ca altfel ia in plus si degetele cand sun t inchise uneori dc nu au le pun o limitare
77 if (c > marime && b > marime)
{
a = Math.Sqrt((defectArray[i].StartPoint.X – d efectArray[i].EndPoint.X) *
(defectArray[i].StartPoint.X – defectArray[i].EndPo int.X) +(defectArray[i].StartPoint.Y –
defectArray[i].EndPoint.Y) * (defectArray[i].StartP oint.Y – defectArray[i].EndPoint.Y));
unghi = Math.Pow(b, 2) + Math.Pow(c, 2) – Math. Pow(a, 2);
unghi = unghi / (2 * b * c);
if (unghi >= -0.7)
{
degete.Add(defectArray[i].StartPoint);
degete.Add(defectArray[i].DepthPoint);
degete.Add(defectArray[i].EndPoint);
nr += 1;
}
}
}
}
}
}
}
catch
{
Console.WriteLine("eroare DrawAndCo mputeFingersNumD");
}
if (nr < 1)
this.fingerNumD = DetectieUnSingurD eget(raza, razaMare);
else
this.fingerNumD = (short)(nr + 1);
}
Aceast ă varinat ă de num ărare a „ g ăurilor” nu func ționeaz ă și în cazul în care
avem un singur deget, fiindc ă nu va trece de prima clasificare și anume aceea în care
punctul de start și de sfâr șit al unui defect s ă se g ăseasc ă, amândou ă, deasupra cercului
de control înscris. Deci dac ă utilizatorul va ar ăta un singur deget algoritmul descris mai
sus nu-l va detecta. Pentru aceasta se va folosi im aginea hull, creeat ă la pasul F, și un
detector de unghiuri, Harris.
Acest detector va rula doar atunci când algoritmul de num ărare a degetelor va
indica faptul c ă utilizatorul nu are niciun deget ridicat. În acest caz exist ă dou ă variante:
fie utilizatorul chiar are un deget ridicat îns ă algoritmul nu-l detecteaz ă, fie are mâna
închis ă, sub form ă de pumn. Acest detector este implementat în cadrul clasei
„ HarrisCorner.cs”.
Detectorul Harris se va realiza pe o imagine în nua n țe de gri, fiind mai u șor de
lucrat cu acestea. Un unghi/ col ț este definit, din punctul de vedere al spa țiului unei
imagini, ca fiind acele p ărți caracterizate de localiz ări unde intensitatea variaz ă foarte
mult în ambele direc ți, adic ă și pe direc ția X și pe Y (ambele derivate par țiale pe
direc ția X și Y sunt mari) .[28]
Pentru o anumit ă direc ție [u,v] varia ția de intensitate se poate calcula astfel:
78
(13) 2
),(, ) ( ),(yIvxIuw yxVi
yxle coordonate la ferestrei centrul in ii
i vu∂∂+∂∂=∑
∀,
unde xIi
∂∂ și yIi
∂∂ vot fi calculate similar ca mai jos (figura 3.32), iar iweste
valoarea func ției fereastr ă gaussian ă pe pozi ția „ i ” .[28]
Aceat ă ecua ție mai poate fi scris ă și sub forma:
(14)
=++=vuMvuBv Cuv Au yxVvu ][ 2 ),(2 2
, , unde
(15) wyI
xICwyIBwxIA ⊗∂∂
∂∂=⊗∂∂=⊗∂∂= )(,)(,)(2 2,
(16)
=BCCAM ,
iar operatorul ⊗ este operatorul de convolu ție
Aceast ă din urm ă scriere a varia ției intensit ăți se nume ște mume ște metoda de
caclul Harris și va fi utilizat ă în algoritmul pentru detec ție a unghiurilor dintr-o imagine.
Figura 3.23-calculul varia ției intensit ăți.
79
Clasificare punctelor imagini utilizând valorile pr opri ale matricei M se poate
vizualiza în cadrul figuri 3.24.
Un unghi este detectat atunci când 21,λλ sunt mari și intesitatea cre ște în toate
direc țile.
Astfel evaluarea pentru unghiuri este dat ă de urm ătoarea ecua ție:
(17) 2)) (()det( ),( Mtrace kMyxC −= ,
unde:
(18) 2
21)det( CAB M −==λλ ,
(19) BA Mtrace +=+=21)( λλ ,
=k o constant ă cu valori cuprinse în intervalul [ 0.04 , 0.06 ]. Cu cât aceast ă constant ă
este mai mare, mai pu ține unghiuri sunt detectate, iar cu cât este mai mi c ă detectorul
este mai senzitiv și va detecta mai multe unghiuri.
mari sunt 21λλ
Figura 3.24 –clasificarea punctelor unei imagini .[ 28]
Algoritmul acestui detector, realizat în cadrul pro iectului este urm ătorul:
1. Se calculeaz ă derivatele pe direc ția X și Y ale imagini, conform celor
explicate mai sus, figura 3.23, ecua țile 13, 14, 15.
(20)
2. Calculez produsul derivatelor pentru fiecare pixel. 00
21
≈≈
λλ
80 (21)
3. Aplic un filtru gaussian, adic ă convolu ția cu func ția fereastr ă gaussian ă.
4. Pentru fiecare pixel ),(yx din cadrul imagini se calculeaz ă harta de
răspunsuri pentru m ăsurarea unghiurilor, se calculeaz ă ),(yxC. Constanta
k va avea valoarea 0.04.
5. Se realizeaz ă o filtrare a noi h ărți dup ă o anumit ă valoare, în cazul
aplica ției este valoare 25000.
6. Se p ăstreaz ă doar maximele din cadrul imagini.
Rezultatul rul ări acestui detector, adic ă punctele maxime de schimbare de
intensitate din imagine, vor fi memorate într-un ve ctor. Apoi asupra cestor puncte se va
aplica o clasificare dup ă distan ța dintre ele, și dup ă pozi ția acestora. Este nevoie de
ultima clasificare pentru a putea face exact difere n ța dac ă este un deget, sau mâna este
închis ă. Astfel punctele r ămase dup ă prima clasificare trebuie s ă se afle în afara unui
cerc de control cu raza „razam”, care este de fapt raza cercului înscris plus înc ă
jum ătate din aceasta. (ilustra ție algoritm figura 3.25) .
Secven ța care se ocup ă cu preluarea acestor punctelor, se g ăse ște în corpul
metodei, „ GetUnghiuri ” din clasa „ManaDreapta.cs” sau „ManaStanga.cs”. Secven ța de
cos care se ocup ă de acest lucru este:
float razam = raza + raza / 2;
pts = harris.harris(hullimag.Convert<Gray, byte>(). Bitmap);
//treshold dupa distanta intre unghiuri
if (pts != null && pts.Count() > 0)
{
for (short i = 0; i < pts.Count – 1; i++)
{
distanta = (short)(Math.Sqrt(Math.Pow(pts[i].X – pt s[i + 1].X, 2) +
Math.Pow(pts[i].Y- pts[i + 1].Y, 2)));
//distanta dintre punctele detectate de metoda harr is
if (distanta >= Math.Pow(raza / 2, 2))
{
distanta = (short)(Math.Sqr t(Math.Pow(pts[i].X – box.center.X, 2)
+ Math.Pow(pts[i].Y – box.center.Y, 2)));
//de la cercul mare la centru maini
if (distanta >= razam – raz a / 10)//peste raza cercului
intermediar de raza "razam"
{
. . . . . . . . . . . . . . . . . . . . .
81
a) b)
Figura 3.25-)-a)-imaginea ini țial ă, b)- ilustrarea modului de func ționare a algoritmului
pentru detec ția unui singur deget.
În cadrul figuri 3.25 ceea ce este colorat cu verde este polinomul hull, cercul ro șu
este cercul înscris mâini, cel galben este noul cer c de control, iar ceea ce este de culoare
mov reprezint ă rezultatul final, în cazul de fa ță se va detecta un deget.
I. Calcul intersec ți lini de control cu conturul mâini.
Acest pas este în principiu de ajutor atunci când a lgoritmul de num ărare al
degetelor nu detecteaz ă exact num ărul acestora. Aceste e șecuri pot fi datorate erorilor
din cadrul imagini furnizate de senzor, sau de prel uare a punctelor caracteristice celor
dou ă mâini de la senzor, sau fie chiar și de la algoritmul în sine. De asemenea aceast
lucru este de mare ajutor și-n cazul recunoa șteri gesturilor.
Ideea de principiu este urm ătoarrea: se vor trasa în jur de 4 lini de control, în
cadrul imagini de contur, și se calculeaz ă pe rând intersec țile acestora cu conturul.
Aceste lini se calculeaz ă pe baza celui mai mic dreptunghi care încadreaz ă conturul
mâini. Întreg algortimul este implementat în cadrul metodei „ intersectii_Control ” din
clasa „ ManaDreapta.cs” și clasa „ ManaStanga.cs ” .
Așadar se vor prelua vertexurile acestuia, ilustrate în figura 3.26 a) , și la o
anumit ă dist ănță pe axa „Y ” , se vor trasa acesete lini de control . Cele 4 lini vor fi la o
distan ță de: 2, 6, 10 și 14 fa ță de vertexul num ărul 2 al dreptunghiului de încadrare al
mâini (figura 3.26 b) ) .
82
a) b)
Figura 3.26 – a) – modul de numerotare a vertexului celui mai mic dreptunghi care
încadreaz ă mâna , b) – ilustrearea celor 4 lini de control pe imaginea de contur a mâini.
În cadrul figuri b) liniile de culoare galben ă sunt cele patru lini de control trasate
în func ție de vertexul num ărul 2 al dreptunghiului care încadreaz ă mâna, iar linia de
culoare verde este latura dreptunghiului înscris mâ ini. Ceea ce este de culoare ro șie
reprezint ă cel mai mic dreptunghiul care încadreaz ă conturul mâini.
Scopul acestor intersec ți este de a valida num ărul exact al degetelor ar ătate de
utilizator, iar utlima intersec ție, cea cu latura dreptunghiului înscris, este util izat ă pentru
a face distinc ția pozi ției degetelor în pasul de detec ție a gesturilor.
J. Detec ție gesturi control mouse.
Dup ă ce s-au parcurs cu brio to ți pa și anteriori se va trece la detec ția și
recunoa șterea gesturilor de la nivelul mâinilor utilizatoru lui. Gesturile se bazeaz ă pe
num ărul degetelor ar ătate de utilizator pe fiecare dintre cele dou ă mâini, dar și de
pozi țile acestora fa ță de sholduri. Aceste demersuri se vor discuta pe pa rcursul
urm ătorilor pa și și o parte și în cadrul acestuia.
În principiu exist ă trei tipuri de controale oferite de aplica ție: cel de control al
mouse-ului, cel al anumitor componente din programu l „ Mozilla Firefox” , și cel de
control al modulului interactiv, aplica ția gen paint.
Controlul mouse-ului este unul din obiectivele prin cipale ale acestui proiect. Prin
protocolul bazat pe gesturi se pot controla urm ătoarele func ți, ale mouse-ului: mi șcarea
acestuia pe ecranul utilizatorului, click dreapta, click stânga și dublu click. Mi șcarea
83 mouse-ului pe ecran se realizeaz ă cu ajutorul mâini stângi, iar celelalte comenzi se
ralizeaz ă cu ajutorul mâini drepte.
Modul de ac țiune al detec ției fiec ărui gest, de la nivelul mâini drepte, este ilustrat
în lini mari în cadrul urm ătoarei figuri , figura 3.27. (aceast ă schem ă poate s ă prezinte
mici diferen țe de la gest la gest) . Pentru ac țiunea de mi șcare a mouseului pe ecran sunt
de ajuns doar pa și parcur și anterior, pentru c ă se va ține cont doar de num ărul degetelor
ar ătate de utilizator, pozi ția mâini și modul de înclinare a cesteia ne mai fiind necesar e ,
pentru a conferi mobilitate utilizatorului în mi șcare, și în controlul ac țiuni.
Verificarea pozi ției valide pentru recunoa șterea gestului mâini se realizeaz ă prin
verficarea cazului în care mâna se afl ă în cadru, și prin verificare pozi ției acesteia .
Aceasta se realizeaz ă cu ajutorul metodei „ ValidareGestDreapta ” din cadrul clasei
„Control.cs ”, și a fost descris ă în cadrul pasului de calcul al num ărului degetelor ar ătate
de utilizator (pasul H).
Dac ă s-a trecut de aceast ă verificare se trece la calcularea înclina ției mâini,
aceasta indic ă într-o oarecare m ăsura orientarea degetelor și a mâini. Acest lucru se
rezum ă la calculul pantei unei drepte. Este vorba despre calcularea pantei laturi celui
mai mic dreptunghi care încadreaz ă mâna, ilustra ție figura 3.28.
Formula matematic ă de calculare a pantei dintre dou ă puncte, utilizat ă și-n
proiect, este: Fie dou ă puncte ),(AAyxA și ),(BByxB , atunci panta dreptei AB este:
(22) =AB m
ABAB
xxyy
−−
De obicei, pentru recunoa șterea gesturilor, aceast ă pant ă trebuie s ă fie cuprins ă în
intervalul [0, 1] .
Dup ă acest pas se va verifica dac ă mâna stâng ă este l ăsat ă în jos, adic ă valoarea
coordonatei pe axa „ Y ” este mic ă decât cea a sholdului stâng. Dac ă aceast ă condi ție
este îndeplinit ă se va verifica valoarea pantei dreptei dreptunghiu lui și num ărul
degetelor ar ătate de utilizator. În func ție de aceasta se va trece la verificare gesturilor.
Aceast ă etapă este implementat ă în corpul metodei „ Comenzi_mouse ” din clasa „
Control.cs ” și este în fond o succesiune de condi ți în func ție de anumite criteri de
diferen țiere al protocoalelor .
84
Figura 3.27- schema bloc a detec ției gesturilor pentru mouse.
Figura 3.28-ilustrare a dreptunghiului minim de înc adrare a conturului mâini.
Dreapta de culoare galben ă ne va da orientarea mâini în cadrul imagini.
85 În cele ce urmeaz ă se vor descrie gesturile valide pentru controlul c elor trei func ți
ale mouse-ului, controlate de mâna dreapt ă.
Pentru func ția de click stânga se adopt ă un protocol bazat pe un singur deget, cel
ar ătător, sau dou ă lipite – degetul ar ătător și cel mijlociu .(figura 3.29) .
Figura 3.29 – gestul pentru click stânga
Pentru recunoa șterea acestui gest se utilizeaz ă se va utiliza dreptunghiul înscris mâini
pentru a putea diferen ța despre care deget este vorba. Pentru aceasta se v a împ ărți latura
de sus a dreptunghiului înscris în 3 și 4 p ărți egale pentru a face o încadrare a punctelor
de intersec ție a degetului cu aceast ă latur ă. (figura 3.30).
Condi țile de indentificare a gestului este ca punctele P1 și P2 din figura 3.30 s ă
îndeplineasc ă urm ătoarele condi ți:
(23)
≥ ≤≥
XPXPșiXPXPXPXP
. 4. 2. 3. 2. 3. 1
Dac ă se întâmpl ă cumva ca utilizatorul s ă țin ă lipite 3 sau 4 degete, algoritmul de
num ărare le va num ăra ca pe un singur deget. Pentru acest caz se va fa ce o verificare a
grosimi degetelor, de fapt a distan ței dintre punctele P1 și P2. Aceast ă distan ță ar trebui
să fie undeva cam la o șesime din lățimea dreptunghiului (a laturi cu care se face
intersec ția).
Figura 3.30-algoritmul pentru distinc ția degetelor utilizatorului
86
De asemenea este nevoie și de o validare a existen ței degetului în cadru, pentru c ă
uneori algoritmul de num ărare nu va detecta degetul. Aceasta se realizeaz ă cu ajutorul
celor 4 lini de control, descrise în pasul de calcu l al intersec ției linilor de control cu
conturul mâini, figura 3.26. A șadar dac ă se g ăsesc 3 perechi de puncte, pe linii de
control diferite, atunci este detectat un deget. ( ilustra ție figura 3.30).
Aceste verific ări, se fac în cadrul metodelor „ verificare_pozitie_click ” și
„Validare_Click0 ” din clasa „ManaDreapta.cs ” .
Pentru func ția de dublu click se adopt ă un protocol bazat pe dou ă degete
desp ărțite, și anume degetul ar ătător și cel mijlociu. (figura 3.31) .
Figura 3.31- gestul pentru comanda dublu click
Pentru aceasta este nevoie de o validare a celor do u ă degete. Aceast ă validare se
realizeaz ă cu ajutorul celor 4 linii de control, figura 3.26. Validarea const ă în faptul c ă
dac ă se g ăsesc 4 puncte pe o aceea și linie atunci acestea confirm ă faptul c ă în cadrul
imagini sunt 2 degete, figura 3.34 b). Aceast ă verificare se g ăse ște în cadrul metodei
„Validare_2_degete ” din cadrul clasei „ManaDreapta.cs ”.
Detec ția propriu-zis ă a gestului se realizeaz ă astfel:
1. Se va verifica faptul ca nu cumva unul dintre deget e s ă fie degetul mare .
Acest lucru se realizeaz ă prin c ăutarea degetului mare în cadrul
vectorului care memoreaz ă degetele detectate. Condi țile ca unul dintre
acestea s ă fie degetul mare sunt: (ilustra ție figura 3.32).
87
Figura 3.32
(24)
<>≤
YPYPYPYPXPXP
. 2. 3. 1. 3. 1. 3
, acest algoritm este implementat în cadru metodei
„GetMaxXDegetMare ” din cadrul clasei „ManaDreapta.cs ”.
2. Apoi se vor prelua valorile minime și maxime pe axa Y, din vectorul de
puncte care reprezint ă degetele utilizatorului.
3. Se verific ă dac ă punctul de maxim este în stânga punctului de minim ,
ilustra ție în figura 3.34, deci XPXP . 2. 1<, P1-puncul de maxim, P2-
punctul de minim.
Func ția pentru detectarea minimului pe axa Y se nume ște „ GetMinYSus ” , iar
pentru detec ția maximului „ GetMaxYSus ” și se g ăsesc amândou ă în cadrul clasei
„ManaDreapta.cs”.
a) b)
Figura 3.34-a)-minimul și maximul pe axa Y, b)-validarea existen ței celor dou ă degete.
88 Pentru func ția de click dreapta se adopt ă un protocol bazat pe un num ăr de trei
degete desp ărțite, și anume: degetul mare, degetul ar ătator și degetul mijlociu (figura
3.35) .
Figura 3.35-gestul pentru comanda dreapta click.
Detec ția acestui gest este la fel ca cel pentru comanda d ublu click doar c ă aici
trebuie ca unul dintre cele trei degete s ă fie degetul mare. De asemenea se utilizeaz ă și
validatorul de confirmare a existen ței celor dou ă degete, ar ătător și mijlociu, bazat pe
liniile de control (este cel de la de la comanda du blu click).
Pentru func ția de mi șcare a mouse-ului pe ecran este nevoie ca mâna stân g ă s ă fie
lăsat ă în jos, și utilizatorul s ă nu aibe niciun deget ridicat, (ilustra ție figura 3.36).
Figura 3.36-pozi ția mâini stângi pentru mi șcarea mouse-ului pe ecran. Sursa [21]
Metodele de accesare a func ților mouse-ului se g ăsesc implementate în cadrul
clasei „Mouse.cs”. Aceste metode sunt: „ GetRezolutieEcran ”- func ție care are rolul de
a prelua rezolu ția ecranului principal al utilizatorului, „ GetMousePositionX ”- preia
coordonata x a pozi ției cursorului pe ecran, „ GetMousePositionY ”- preia coordonata y a
cursorului, „ Move ”- mi șcă cursorul pe ecran la o anumit ă pozi ție ),(yx de pe ecran,
89 „ClickLeftMouse ”- simuleaz ă comanda de click stânga a mouse-ului, „ DoubleClick ”-
simuleaz ă comanda de dublu click, „ RigthClick ”- simuleaz ă comanda click dreapta.
Pentru a simula aceste comenzi este nevoie de acces area evenimentelor specifice
mouse-ului. Acest lucru se realizeaz ă prin importarea metodelor „ mouse_event ”,
necesar ă simul ări comenzilor și „ SetCursorPos ”, necesar ă pentru a mi șca cursorul pe
ecran, din biblioteca "user32".
Secven ța pentru importarea acestor metode este urm ătoarea:
[DllImport("user32.dll", CharSet = CharSet.Auto, Ca llingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int
dwExtraInfo);
[DllImport("user32")] public static extern int Set CursorPos(int x, int y);
Pentru simularea comenzilor, de exemplu pentru clic k stânga, se utilizeaz ă evenimentul
specific mouse-ului. Exemplu pentru metoda „ ClickLeftMouse ”:
public void ClickLeftMouse()
{
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0 , 0);
}
MOUSEEVENTF_LEFTDOWN și MOUSEEVENTF_LEFTUP sunt ni ște constate care vor simula
func țile mouseului.
Gestul pentru op țiunea de „go-back” este acela de a ar ăta cu mâna dreapt ă 2
degete, ca și cel din figura 3.39, iar mâna stâng ă s ă fie l ăsat ă în jos lâng ă corp.
Gestul pentru optiunea de „go-forward” se compune d intr-un mun ăr de 5 degete
ar ătate cu mâna dreapt ă și mâna stâng ă l ăsat ă în jos lâng ă corp.
Căutarea acestei aplica ției „Mozilla Firefox” se realizeaz ă doar atunci când sunt
detectate aceste gesturi. Pentru aceasta se utilize az ă biblioteca
„System.Windows.Automation ”, prezentat ă în capitolul 2.
Pentru început se va accesa arborescen ța creeat ă de aceasta prin r ădăcin ă,
considerat ă a fi desktop-ul, apoi se va c ăuta în cadrul acesteia elementul al c ărui nume
de clas ă va fi cea specific ă programului „Mozilla Firefox”. În cazul în care s- a g ăsit
aplica ția, elementul din arborescen ță se pot accesa componentele acestuia dup ă nume.
Dac ă acesta a fost g ăsit se va invoca metoda specific ă, pentru a se putea efectua
comanda. Secven ța de cod care se ocup ă de aceasta este urm ătoarea (exemplu doar
pentru comanda de „go-back”, pentru „go-forward” se procedeaz ă la fel ):
AutomationElement rootElement = AutomationElement.R ootElement;
if (rootElement != null)
{
90 Automation.Condition condition = new
PropertyCondition(AutomationElement.ClassNameProper ty, "MozillaWindowClass");
. . . . . .
appElement = rootElement.FindFirst( TreeScope.Children,
condition);
if (appElement != null)
{
. . . . . .
Automation.Condition btnBackCondition = new
PropertyCondition(AutomationElement.NameProperty, " Back");
AutomationElement btnBack = appElement.FindFirst( TreeScope.Subtree,
btnBackCondition);
if (btnBack == null)
{
LogMessage("Error finding b ack button");
return;
}
InvokePattern btnBackPattern = btnBack.GetCurrentPa ttern(InvokePattern.Pattern)
as InvokePattern;
btnBackPattern.Invoke();
Clasa „ InvokePattern ” are rolul de a reprezenta controale care ini țiaz ă sau efectueaz ă o
singur ă ac țiune, lipsit ă de ambigitate și nu men ține starea atunci când este activat ă.
Controlalele care i și p ăstreaz ă starea, cum ar fi casetele de selectare „check box es” și
„ radio buttons” trebuie s ă utilizeze alte tipuri de clase.
K. Detec ție gesturi pentru aplica ția paint.
Pentru aplica ția interactiv ă gen paint s-au utilizat un num ăr de 12 gesturi bazate pe
activit ățile ambelor mâini ale utilizatorului. În aces caz g esturile nu mai sunt atât de
stricte, se ține mai mult cont de num ărul degetelor de la ambele mâini, câte sunt la mâna
stâng ă și câte sunt la mâna dreapt ă.
Acestea gesturi sunt:
1. Gestul pentru culoare. Pentru aceasta utilizatorul trebuie s ă arate 5 degete
cu mâna stâng ă și mâna dreapt ă s-o lase în jos, sub sholdul dprept.
2. Gestul pentru desenarea pe ecran în func ție de mi șcarea mouseului pe
ecran. Pentru aceasta utilizatorul trebuie s ă arate 5 degete cu mâna dreapt ă,
niciun deget cu mâna stâng ă, și mâna stânga s ă fie deasupra sholdului
stâng.
3. Gestul pentru a desena un cerc pe ecran. Utilizator ul trebuie s ă arate 4
degete cu mâna stâng ă și mâna dreapt ă s ă fie în jos. Cele patru degete
91 ar ătate trebuie să fie ca în cadrul figuri 3.37. Acest gest este vali dat prin
faptul c ă niciunul dintre degete nu trebuie s ă fie degetul mare.
Figura 3.37-gestul pentru comanda desen ări unui singur cerc.
4. Gestul pentru a desena un dreptunghi. Utilizatorul trebuie s ă arate cu mâna
dreapt ă 4 degete, figura 3.37, iar mâna st ăng ă s ă fie desupra sholdului și s ă
nu arate niciun deget.
5. Gestul pentru desenarea unei lini. Utilizatorul tre buie s ă arate 4 degete cu
mâna stâng ă și 4 cu mâna dreapt ă, ambele ca în cadrul figuri 3.37.
6. Gestul pentru desenarea unei pic ături. Utilizatorul trebuie s ă arate 2 degete
cu mâna stâng ă, acelea și dou ă ca și pentru comanda dublu click a
mouse-ului, figura 3.31, iar mâna dreapt ă s ă se afle deasupra sholdului drept și
să nu arate niciun deget.
7. Gestul pentru rota ția pe axa X a unei imagini. Utilizatorul trebuie s ă arate
3 degete cu mâna stâng ă, figura 3.38, dreapta deasupra sholdului și s ă nu
arate niciun deget. Acest gest este detectat prin f aptul c ă niciunul dintre
cele trei degete nu trebuie s ă fie cel mare, iar minimul pe axa Y s ă fie între
celelalte dou ă degete.
Figura 3.38-gest pentru rota ția pe axa X.
92 8. Gestul pentru rota ția pe axa Y a unei imagini. Utilizatorul trebuie s ă arate
3 degete cu mâna dreapt ă, figura 3.38, stânga deasupra sholdului și s ă nu
arate nici un deget.
9. Gestul pentru rota ția pe axele X și Y a unei imagini. Utilizatorul trebuie s ă
arate 3 degete cu mâna dreapt ă si 3 degete cu stânga, figura 3.38.
10. Gestul pentru comanda „ zoom in ”. Utilizatorul tr ebuie s ă arate cu
ambele mâini 2 degete, cu mâna stâng ă ca și la dublu click, figura 3.31, iar
cu mâna dreapt ă ca și gestul de confirmare a comenzi pentru desenarea
unui singur obiect, figura 3.39.
11. Gestul pentru comanda „ zoom out ”. Utilizatorul t rebuie s ă arate cu mâna
stâng ă 2 degete, ca și la dublu click, figura 3.31, iar mâna dreapt ă s ă fie
deasupra sholdului și s ă nu arate nici un deget.
12. Gestul de confirmare a desen ări unui singur obiect și pentru „ zoom in ” și
„ zoom out ”. Utilizatorul trebuie s ă arate cu mâna dreapt ă 2 degete, figura
3.39, și mâna stâng ă s ă fie deasupra sholdului și s ă nu arate niciun deget.
Acesta este utilizat în contextul desen ări unui singur obiect, atunci când
utilizatorul dore ște s ă deseneze la o anumit ă pozi ție un obiect, sau atunci când
se dore ște desenarea unei lini pe ecran. În contextul pentr u comenzile „ zoom
in ” și „ zoom out ” se va scala imaginea la fiecare asem enea gest recunoscut.
Figura 3.39-gestul de recunoa ștere a valid ări desen ări unui obiect și scal ări
unei imagini.
Acest gest este detectat în urm ători pa și:
a) Preiau minimul și maximul de pe axa Y.
b) Dac ă coordonata „x” a punctului de minim este mai mic ă decât cea a
maximului, atunci se calculeaz ă dinstan ța dintre cele dou ă. Dac ă aceast ă
93 distan ță este mai mare decât jumatatea l ățimi celui mai mic dreptunghi
care
încadreaz ă aria mâini, atunci se valideaz ă gestul, figura 3.40. S-a ales ca și
valoare de comparare a distan ței dintre puncte, cea men ționat ă, datorit ă
faptului c ă l ătimea va indica întotdeauna dinstan ța dintre cele dou ă puncte și
se va modifica conform al ătur ări sau dep ărt ări acestora.
Figura 3.40-minimul și maxinul pe axa y, P1-punctul de maxim, P2 punctul de
minim.
Pentru a evita micile nepl ăceri de accesare prea rapid ă a comenzilor pe care
utilizatorul dore ște s ă le întreprind ă, prin gesturi, se utilizeaz ă ni ște flag-uri pentru
fiecare gest. Astfel activarea comenzilor se va fac e dup ă un anumit interval de timp, de
1 secund ă, în care utilizatorul trebuie s ă stea nemi șcat pentru ca gestul s ă-și seteze
propriul flag. Validare se va face doar în cazul în care doar flag-ul unei singure comenzi
este valid în intervalul de 1 secund ă, cu alte cuvinte acestea se exclud unele pe altele , nu
se pot activa 2 comenzi în acela și timp.
De asemenea se vor utiliza și în acest caz orient ările mâinilor, a ambelor, prin
verificarea valori pantei laturi celui mai mic drep tunghi care încadreaz ă conturul
fiec ărei mâini.
L. Vizualizare rezultat pe interfa ța cu utilizatorul.
Interfa ța de lucru cu utilizatorul este una destul de simpl ă care ofer ă toate
informa țile necesare despre ac țiunile utilizatorului, figura 3.41.
Pe aceast ă interfa ță se poate vizualiza num ărul degetelor ar ătate pe fiecare mân ă,
orientarea mâinilor: pentru stânga „Inclinatie STA NGA ”, pentru dreapta „Inclinatie
DREAPTA ”. Câmpul „Validare Recunoa ștere” va în știin ța utilizatorul dac ă se afl ă cu
94 mâna dreapt ă în zona de recunoa ștere. De asemenea se poate vizualiza datele de
ecalibrare: „Distanta Ecalibrare” – distan ța mâini drepte în momentul când s-a realizat
ecalibrarea, „Raza mare” – raza cercului circumscri s mâini drepte la ecalibrare, „Raza
mica” – raza cercului înscris mâini drepte la ecali brare. Se poate vizualiza și starea de
comunica ție a senzorului kinect cu sistemul de calcul, „Stat us kinect”, dac ă se reu șește
preluarea skeleton-ului, „Status skeleton” , si dis tan ța real ă a mâini fa ță de senzor,
„RealDepth”.
Se poate accesa modulul de ecalibrare a senzorului prin ap ăsarea butonului
„Ecalibrare Kinect” , iar pentru a accesa modulul i nteractiv de paint prin butonul
„Paint”.
Figura 3.41- interfa ța utilizatorului pentru modulul de control și detec ție a gesturilor.
4.5 Modulul Interactiv de Testare a gesturilor.
Acest modul este reprezentat de o aplica ție gen paint. Aceasta are mai multe
op țiuni pentru desenare cum ar fi: desenarea unui sing ur obiect, desenarea dup ă
mi șcarea
95 mouse-ului pe ecran, sau manipularea unor imagini s electate de utilizator din cadrul
unui fi șier.
Recunoa șterea gesturilor pentru activarea comenzilor, din c adrul acestuia, s-au
realizat în cadrul modulului anterior.
Dac ă se dore ște spre exemplu desenarea unei figuri mai întâi tre buie selectat ă
culoarea, apoi tipul figuri și în cele din urm ă se va mi șca cursorul și se va confirma
pozi ția pentru desenare. Culoarea pentru desenare se poa te schimba în orice moment.
De asemenea se poate șterge ceea ce am desenat și se pot ad ăuga și imagini de fundal.
Dac ă se dore ște spre exemplu s ă se manipuleze imagini, adic ă s ă se roteasc ă dup ă
axa X, axa Y sau axele X și Y, sau s ă se scaleze: „zoom in” și „zoom out” se va
selecta un set de imagini dintr-un fi șier, se va selecta o imagine, și se vor aplica oricare
sin cele 5 comenzi asupra acesteia. De asemenea mai exist ă și op țiuni de salvare a unei
imagini, și de vizualizarea restului de imagini aduse din fi șier, pentru c ă la un moment
dat doar 5 imagini pot fi vizualizate.
Interfa ța de lucru pentru desenare se poate vizualiza în ca drul figuri 3.42, iar cea
pentru manipularea pozelor în cadrul figuri 3.43.
Figura 3.42- interfa ța utilizatorului pentru op țiunea de desenare.
96 În cadrul acestor interfe țe, câmpurile: „COMENZI” –indic ă comanda care se va
activa, „POZITIE ” –avertizeaz ă utilizatorul dac ă mâinile se g ăsesc în pozi țile de
recunoa ștere a gesturilor, „STANGA” – semnific ă num ărul degetelor ar ătate cu mâna
stâng ă, „DREAPTA” – semnific ă num ărul degetelor ar ătate cu mâna dreapt ă.
Comenzile din cadrul acestei interfe țe pot fi activate atât prin intermediul gesturilor cât
și prin intermediul butoanelor.
Figura 3.43- interfa ța utilizatorului pentru op țiunea de manipulare a pozelor.
5. Capitolul IV
5.1 Rezultatele ob ținute.
În urma dezvolt ări acestui proiect s-a ob ținut o recunoa ștere a 18 tipuri de gesturi,
bazate pe utilizarea ambelor mâini. Aceste gesturi sunt bazate atât pe pozi țile mâini
relative la corpul utilizatorului, adic ă în func ție de pozi ția acestora fa ță de cele dou ă
sholduri, pe axa Y, cât și pe num ărul degetelor ar ătate de fiecare mân ă în parte. Astfel o
mân ă se afl ă „sus ” dac ă coordonata Y a acesteia este mai mare decât cea a sholdului,
de pe aceea ți parte a corpului, iar dac ă este mai mic ă, atunci aceasta este în „jos” .
97 Acestea sunt descrise pe scurt în urm ătorul tabel. (descrierea detaliat ă se g ăse ște
în capitolul 3.3).
În urma finaliz ări proiectului s-au realizat o serie de teste, pe c âteva tipuri de
mâini diferite. În urma acestora s-au putut observa urm ătoarele lucruri cum ar fi:
-algoritmul func ționeaz ă mai bine pe utilizatori cu mâini mai mari, și mai ales cu
degete mai lungi, deoarece imaginea provenit ă de la senzor va fi mult mai clar ă,
procesarea imagini merge mult mai bine.
-distan ța de recunoa ștere a gesturilor difer ă de la utilizator la utilizator, în cazul
celor care au degete mai scurte distan ța va fi mai mic ă, iar pentru cei cu degete mai
lungi aceasta va cre țte.
-este foarte important ca atunci când un utilizator acceseaz ă aplica ția s ă nu
intervin ă în cadru un alt utilizator și s ă se suprapun ă peste corpul acestuia, pentru c ă se
poate pierde controlul, fie prin faptul c ă: acesta se poate muta la noul utilizator, fie s ă
nu mai recunoasc ă nici un utilizator. Aceste probleme au fost discut ate în capitolul 1,
subcapitolele 1.6 și 1.8.
Categorie
Gest Func ția
Controlat ă Num ăr degete
mâna
Dreapta Num ăr
degete
mâna
Stânga Pozi ție mâna
Dreapt ă fa ță
de sholdul
drept pe axa
Y Pozi ție mâna
Stâng ă fa ță
de sholdul
stâng pe axa
Y
MOUSE Miscare
pe ecran 0 0 sus Jos
Click
stânga 1-degetul
ar ătător sau
degetul
ar ătător și
mijlociu lipite 0 sus Jos
Click
dreapta 3- primele trei
degete 0 sus Jos
Dublu
click 2-degetul
ar ătător și cel
mijlociu
0 sus Jos
98 Categorie
Gest Func ția
Controlat ă Num ăr degete
mâna
Dreapta Num ăr
degete
mâna
Stânga Pozi ție mâna
Dreapt ă fa ță
de sholdul
drept pe axa
Y Pozi ție mâna
Stâng ă fa ță
de sholdul
stâng pe axa
Y
Mozilla
Firefox Go-back 2 -degetul
ar ătător și cel
mic 0 sus Jos
Go-
forward 5 0 sus Jos
Paint Selectare
culoare
0 5 jos Sus
Desenare
dup ă
mi țcare
mouse 5 0 sus Sus
Desenare
cerc 0 4- fără
degetul mare jos sus
Desenare
dreptunghi
4-fără degetul
mare
0 sus Sus
Confirmar
e desenare 2-degetul
ar ătător și cel
mic 0 sus sus
Desenare
linie 4-fără degetul
mare 4-fără
degetul mare sus sus
Desenare
picatura 0 2 -degetul
ar ătător și
cel mijlociu jos Sus
Manipula
re
imagini Rota ție
fa ță de axa
X 0 3- primele
trei degete
fără cel mare Sus Sus
99 Categorie
Gest Func ția
Controlat ă Num ăr degete
mâna
Dreapta Num ăr
degete
mâna
Stânga Pozi ție mâna
Dreapt ă fa ță
de sholdul
drept pe axa
Y Pozi ție mâna
Stâng ă fa ță
de sholdul
stâng pe axa
Y
Rota ție
fa ță de axa
Y 3- primele trei
degete f ără cel
mare 0 sus Sus
Rotatie
fa ță de axa
X și Y
3- primele trei
degete f ără cel
mare 3-primele
trei degete
fără cel mare Sus Sus
„Zoom
In” 2-degetul
ar ătător și cel
mijlociu 2-degetul
ar ătător și
cel mijlociu Sus Sus
„Zoom
Out ” 0 2 -degetul
ar ătător și
cel mijlociu Sus Jos
5.2 Dificult ăți întâmpinate pe parcursul dezvolt ări proiectului.
Pe parcursul dezvolt ări proiectului au fost întâmpinate o serie întreag ă de
dificult ăți, poate de la cele mai simple pân ă la cele mai complicate. În principiu acestea
au fost legate de algoritmul din spatele detec ției gesturilor și controlului aplica ților.
La începutul dezvolt ări aplica ției acestea au fost de natura proces ări în paralel a
datelor, pentru a sc ădea timpul de segmentare a imagini furnizate de sen zor. A șadar au
fost probleme în ceea ce prive ște modul de lucru cu thread-urile, modul de accesa re a
datelor și de sincronizare a acestora. Legat de aceast ă problema s-a c ăutat o metod ă care
să u șureze în acela și timp și munca cu firele de execu ție, dar și cantitatea de informa ție
proesat ă pe core-urile disponibile ale sistemului. În princ ipiu se poate spune c ă s-a
încercat c ăutarea c ăi optime care s ă ruleze în timp real și s ă exploateze cât mai bine
resursele sitemului, mai ales cele ce țin de Unitatea Central ă de Procesare (CPU).
100 O alt ă problem ă a fost întâmpinat ă la partea de ecalibrare. Aici au fost
întâmpinate probleme cu alegerea m ărimi optime a celor dou ă cercuri. Ini țial s-a
încercat o aproximare a acestora în func ție de media normal ă a unei mâini, care s ă se
adapteze singur ă în func ție de mâna utilizatorului. Aceast ă abordare dura îns ă destul de
mult și nu se ajungea la un optim datorit ă faptului c ă utilizatorul chiar dac ă nu se mi șcă,
adâncimea tot difer ă pu țin de la cadru la cadru.
De asemenea au fost dificult ăți chiar și-n cazul prelu ări zonelor de interes.
La acest pas trebuiau calculate dimensiunile dreptu nghiului care s ă încadreze cât mai
bine mâna utilizatorului. Prin acest pas s-a urm ărit și mic șorarea dimensiuni imaginilor
asupra c ăruia se va face mai departe procesare.
La partea de detec ție a num ărului degetelor au fost întâmpinate dificult ăți
majore.
Aici au fost probleme la nivelul algoritmului pentr u detec ția unghiurilor, acesta trebuie
să ofere c ăt mai clar informa țile c ăutate. În acest sens s-au testat mai mul ți algoritmi
cum ar fi: K-curvature, acesta a e șuat din cauza c ă nu s-a g ăsit un k (ordin) optim în
func ție de mâna utlizatorului și de distan ța acestuia fa ța de senzor, diferite detectoare de
unghiuri, acestea ofereau de obicei mult prea multe informa ți, mai ales în situa ția unui
singur deget. Aceste informa ți nu se puteau diferen ția/ clasifica pentru c ă difereau în
func ție de pozi ția mâini în cadrul imagini. De asemenea și la algoritmul adoptat au fost
probleme, ofer ă la fel ca și în cazul celorlalte prea multe informa ți când în cadru se afl ă
un singur deget, în principiu acestea sunt la deget ul ar ătător și la degetul mic. Ini țial
detec ția degetelor a fost abordat ă pe baza ipotezei c ă degetele sunt acele unghiuri
ascu țitunghice dintre trei puncte, unghiuri, consecutive din cadrul imagini. Aceast ă
abordare a fost greu de aplicat în cazul când utili zatorul arat ă un singur deget, pentru c ă
num ărul și pozi ția punctelor g ăsite de algoritmul de detec ție a defectelor difer ă în
func ție de pozi ția mâini, în special de orientare acesteia.
Dificult ăți au fost și la partea de g ăsire, aproxim ări oarecum, a orient ări mâini în
cadrul imagini. Aceasta se datoreaz ă faptului c ă utilizatorul trebuie s ă țin ă mâna
orientat ă în sus, astfel algoritmul va da rezultatele cele m ai bune.
Alte dificult ăți au fost întâlnite și la crearea protocoalelor de interac țiune dintre
utilizator și sistemul de calcul. Ini țial algorimul a fost conceput f ără a activa și
comenzile mouse-ului. Ac țiunile recunoa șteri gesturilor erau afi șate pe interfa ța
modulului de control și detec ție a gesturilor. O dat ă ce s-au f ăcut leg ăturile dintre cele
trei module, create separat, ale aplica ției și au fost activate comenzile, au început s ă
101 apar ă probleme cum ar fi: activarea prea rapid ă a gesturilor, mi șcarea mouse-ului pe
ecran era afectat ă de orice mi șcare a mâinilor, recunoa șterea prea lent ă a gesturilor.
Acestea au fost rezolvate prin intermediul unor fla g-uri. Fiecare comand ă are propriul
flag care va fi setat dup ă 1 secund ă. Astfel în momentul când se va oboserva c ă flag-ul
unuia dintre gesturi a fost setat se va activa și comanda asociat ă acestuia. Activarea
comenzilor se va face doar în cazul în care doar un singur flag a fost setat, deci nu este
posibil ă activarea a dou ă comenzi în acela ți timp.
5.3 Domeniul de utilizare al proiectului, eventuale dezvolt ări ulterioare
și concluzi.
Acest proiect poate fi utilizat ă pentru controlul aplica ților interactive, care ofer ă
mobilitate utilizatorului. Fa ță de majoritatea sistemelor, care sunt controlate de
utilizatori prin diferite tipuri de periferice, de obicei pentru fiecare modul un alt tip de
periferic, aceast ă aplica ție ofer ă posibilitatea înlocuiri acestora, oferind un contr ol cât
mai natural. De obicei oameni se exprim ă prin gesturi, mai ales prin semne, în principiu
localizate la nivelul mâinilor, de aceea se ofer ă un acces cât mai apropiat celui normal
utilizat de noi.
De asemenea se ofer ă un alt tip de control, un control de la dista ță , interactiv.
Utilizatorul nu trebuie s ă mai stea la o anumit ă distan ță fa ță de sistemul pe care dore ște
să-l controleze. Spre exemplu la controlul Computerel or Personale ofer ă un mare
avantaj fiindc ă utilizatori nu trebuie s ă mai stea mereu în aceea și pozi ție obositoare, pe
scaun, ei pot s ă fac ă și mi șcare și s ă și controleze sistemul.
Proiectul poate fi foarte util și pentru persoanele cu dezabilit ăți locomotori,
acestea nu trebuie îneap ărat s ă se deplaseze spre sistemele de calcul, ci doar s ă-și mi ște
mâinile.
Ca și eventuale dezvolt ări sau îmbun ătățiri ar fi:
• Îmbun ătățirea algoritmului de num ărare a degetelor. Se pot c ăuta sau
dezvolta alte metode pentru detectarea acestora cum ar fi: un detector de
unghiuri cât mai exact, f ără s ă țin ă cont de pozi ția mâinilor în cadru sau o
clasificare mult mai bun ă a rezultatelor ob ținute de la acestea.
• Se poate de asemenea ad ăuga noi gesturi, sau noi comenzi. Spre exemplu
s-ar putea introduce mai multe comenzi pentr u controlul programului
102 „ Mozilla Firefox”, sau pentru controlul altor pro grame care sunt utilizate
frecvent.
• Îmbun ătățirea recunoa șteri gesturilor. Pot ca aceste gesturi se fie si ma i
bine descrise decât sunt acum. Spre exemplu se poat e creea un algoritm
care s ă identifice cât mai corect orientarea mâinilor sau care diferen țiaz ă
cât mai clar degetele unei mâini.
Se poate spune proiectul a ajutat la îmbog ățirea bibliotecilor special concepute pentru
procesarea imaginilor, cum ar fi și biblioteca Emgu, cu aplica ți de control bazate pe
gesturi. De asemenea acestea u șureaz ă extragearea și recunoa șterea formelor și o
în țelegere mai bun ă a func țion ări anumitor algoritmi.
103 6. Bibliografie
1. [1] http://en.wikipedia
2. [2] http://geekdad.daddyforever.com/primesense/
3.[3] http://www-research.cege.ucl.ac.uk/Posters/20 11PosterFair/88_Binney_Daniel.pdf
4.[4]http://www.isprs.org/proceedings/XXXVIII/5-
W12/Papers/ls2011_submission_40.pdf
5.[5]http://www.microsoft.com/en-us/kinectforwindow s/develop/developer-
downloads.aspx
6.[6] http://pr.cs.cornell.edu/humanactivities/data /NITE.pdf
7.[7] http://research.microsoft.com/pubs/145347/Bod yPartRecognition.pdf
8.[8] http://ir-so-tic.blogspot.ro/p/interfata-om-m asina.html
9.[9] http://users.utcluj.ro/~tmarita/IOC/C1/C1.pdf
10.[10]http://saravananthirumuruganathan.wordpress. com/2010/04/01/introduction-to-
mean-shift-algorithm/
11.[11]http://research.microsoft.com/en-
us/um/redmond/events/fs2010/presentations/Kudo_Fitz gibbons_Kinect_for_Xbox360_
071210_FacSummit.pdf
12.[12] Microsoft Visual Studio – http://en.w ikipedia.org/wiki/Microsoft_Visual_Studio
13.[13] http://research.microsoft.com/pubs/67 890/siggraph04-grabcut.pdf
14.[14] http://www.maths.lth.se/matematiklth/perso nal/petter/rapporter/grabcut.pdf
15.[15 http://homepages.inf.ed.ac.uk/rbf/CVonline/L OCAL_COPIES/RAJA/CV.html
16.[16] http://msdn.microsoft.com/en-us/library/dd4 60693
17.[17] http://www.lovethedot.net/2009/01/parallel -programming-in-net-40-and.html
18.[18]http://msdn.microsoft.com/en-
us/library/windows/desktop/ee684009%28v=vs.85%29.as px
19.[19] http://www.codeproject.com/Articles/33049 /WPF-UI-Automation
20.[20] http://cm-bloggers.blogspot.ro/2011/07/kine ct-sdk-smoothing-skeleton-
data.html
21.[21] https://www.scss.tcd.ie/Rozenn.Dahyot/ST700 5/4DES.pdf
22.[22] http://nashruddin.com/OpenCV_Region_of_Inte rest_%28ROI%29
23.[23] Oreilly Learning OpenCV-
24.[24] OpenCV Reference Manual-
25.[25]OpenCV-https://picoforge.int-
evry.fr/projects/svn/gpucv/opencv_doc/2.1/opencv.pd f
104 26.[26] Topological Structural Analysis of Digitize d Binary Images by Border
Following – SATOSHI SUZUKI and KEIICHI ABE
– https://docs.google.com/viewer?a=v&q=cache:O44VS 9e4FgwJ:tpf-
robotica.googlecode.com/svn/trunk/Vision/papers/SA-
CVGIP.PDF+S.+Suzuki+and+K.+Abe.+Topological+structu ral+analysis+of+digitized
+binary+images+by+border+following.+CVGIP,+30%281%2 9:32%E2%80%9346,+A
pril+1985.&hl=ro&gl=ro&pid=bl&srcid=ADGEESiyFZRr7Fw MUiBb24aLBulL_FxZv
mM_TZ2enO6xK1VkrivhBfereQPatw-lHXhfBpJVHZdL-qvsm-
w0Zkxm0PxYaSu9PuAFvwiABzYDs8a1U473-
i8RxPP33XYzqhc01HBY7G3g&sig=AHIEtbRnNkqT1FS7EACnas7 dShhSDMTLZg
27.[27] http://cgm.cs.mcgill.ca/~beezer/cs507/3coi ns.html
28.[28] http://kiwi.cs.dal.ca/~dparks/CornerDetec tion/harris.htm
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Conduc ător știin țific : Conf. Dr. Ing. Remus Brad [605285] (ID: 605285)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
