Sunteți pe pagina 1din 102

MINISTERUL APĂRĂRII NAŢIONALE

ACADEMIA TEHNICĂ MILITARĂ

FACULTATEA DE MECATRONICĂ ŞI SISTEME INTEGRATE DE


ARMAMENT

Departament: Sisteme Integrate de Aviaţie şi Mecanică

PROIECTAREA ŞI REALIZAREA UNUI


ECHIPAMENT AMBARCAT PENTRU
URMĂRIREA AUTOMATĂ A UNEI ŢINTE LA SOL

COORDONATOR ŞTIINŢIFIC: REALIZAT DE:


Lt.ing.Cristian VIDAN Sd.sg-maj. Gavril Alexandru

BUCUREŞTI
2018
NECLASIFICAT

Cuprins

CAPITOLUL 1 - Introducere............................................................................................................. 5
1.1 Componența unui UAS ............................................................................................................ 5
1.2 Sistem de urmărire ................................................................................................................... 6
1.3 Metode de reprezentare a țintelor dinamice si statice ................................................................ 8
CAPITOLUL 2 – Descrierea sistemului ........................................................................................... 12
2.1 Structura sistemului ............................................................................................................... 12
2.2 Camera stereo ZED................................................................................................................ 12
2.3 Modulul de procesare video Nvidia Jetson TX2 ..................................................................... 17
2.4 Interfață Carrier Orbitty ......................................................................................................... 18
2.5 Transmisie de date UART ...................................................................................................... 19
2.6 Biblioteca publică OpenCV.................................................................................................... 21
2.7 Limbaj de programare Python 3.5 .......................................................................................... 23
2.8 Sistemul de operare Linux...................................................................................................... 24
CAPITOLUL 3 – Sisteme de coordonate ......................................................................................... 25
3.1 Relații de legătura între sistemele de coordonate .................................................................... 25
3.2 Modelul matematic al unei camere ........................................................................................ 26
3.3 Sistem girostabilizat pentru controlul camerei ........................................................................ 27
CAPITOLUL 4 – Metode de urmărire studiate................................................................................. 30
4.1 Descrierea procesului de urmărire .......................................................................................... 30
4.2 Clasificarea metodelor de urmărire ......................................................................................... 30
4.3 Algoritmul BOOSTING ......................................................................................................... 32
4.4 Algoritmul bazat pe fluxul optic (Dense Optical Flow) ........................................................... 32
4.5 Metoda Lucas-Kanade ........................................................................................................... 34
4.6 Algoritmul TLD (Urmarire Invatare Detectare) ...................................................................... 37
4.7 Algoritmul MIL (Invatarea Instantelor Multiple) .................................................................... 39
4.8 Ipoteza GMIL ........................................................................................................................ 41
CAPITOLUL 5 – Comparație a tehnicilor de urmărire ..................................................................... 43
5.1 Urmărirea punctelor ............................................................................................................... 43
5.1.1 Metoda deterministă ........................................................................................................ 43
5.1.2 Metoda statistica ............................................................................................................. 44

NECLASIFICAT
din
NECLASIFICAT

5.2 Urmărirea nucleului .............................................................................................................. 44


5.2.1 Modele bazate pe șabloane .............................................................................................. 44
5.2.2 Modele cu aspecte multiple ............................................................................................. 45
5.3 Urmărirea siluetei .................................................................................................................. 45
5.3.1 Potrivirea formei ............................................................................................................. 45
CAPITOLUL 6 – Algoritmul de urmărire realizat ............................................................................ 48
6.1 Distribuția probabilităților de culoare ..................................................................................... 48
6.2 Algoritmul Mean Shift ........................................................................................................... 49
6.3 Algoritmul Camshift .............................................................................................................. 50
6.4 Măsurarea funcției de similaritate........................................................................................... 51
CAPITOLUL 7 – Rezultate obținute ................................................................................................ 53
CAPITOLUL 8 – Preocupări viitoare............................................................................................... 59
8.1 Aplicații bazate pe inteligență artificială ................................................................................. 59
8.2 Rețele neuronale .................................................................................................................... 60
8.2.1 Functia de transfer ........................................................................................................... 61
8.2.2 Formarea modelului rețelei neuronale .............................................................................. 62
8.2.3 Rețeaua de propagare back-forward ................................................................................. 62
CAPITOLUL 9 - Concluzii ............................................................................................................. 64
Bibliografie……………………………………………………………………………….….65
Anexe………………………………………………………………………………………...68

NECLASIFICAT
din
NECLASIFICAT

Listă figuri
Figura 1.1 Componența unui UAS ............................................ Error! Bookmark not defined.
Figura 1.2 Urmărire bazată pe procesare de imagine ............... Error! Bookmark not defined.
Figura 1.3 Tipuri de reprezentări a țintelor ............................... Error! Bookmark not defined.
Figura 2.1 Structura sistemului de urmărire automată ............. Error! Bookmark not defined.
Figura 2.2 Cameră stereo ZED .................................................. Error! Bookmark not defined.
Figura 2.3 Colectarea fluxului video ......................................... Error! Bookmark not defined.
Figura 2.4 Sistemul de coordonate al camerei ZED ................. Error! Bookmark not defined.
Figura 2.5 Modul de procesare video Nvidia Jetson TX2 ....... Error! Bookmark not defined.
Figura 2.6 Caracteristici tehnice ale modulului de procesare video Nvidia Jetson TX2 . Error!
Bookmark not defined.
Figura 2.7 Interfață Carrier Orbitty ........................................... Error! Bookmark not defined.
Figura 2.8 Secvență de biți în transmisia UART ...................... Error! Bookmark not defined.
Figura 2.9 Schema transmisiei UART....................................... Error! Bookmark not defined.
Figura 2.10 Logo OpenCV-Python ........................................... Error! Bookmark not defined.
Figura 2.11 Logo sistem de operare Linux ............................... Error! Bookmark not defined.
Figura 3.1 Modelul geometric al camerei video ....................... Error! Bookmark not defined.
Figura 4.1 Clasificare metode de urmărire ................................ Error! Bookmark not defined.
Figura 4.2 Diagrama de stări a algoritmului TLD .................... Error! Bookmark not defined.
Figura 4.3 Diagrama procesului de învățare P-N ..................... Error! Bookmark not defined.
Figura 6.1 Structura algoritmului realizat ................................. Error! Bookmark not defined.
Figura 7.1 Quadcopterul integrat pentru ambarcarea sistemului de urmărire realizat ..... Error!
Bookmark not defined.
Figura 7.2 Telecomanda utilizată în controlul platformei aeriene .......... Error! Bookmark not
defined.
Figura 7.3 Sistemul surprins în modul de funcționare ............. Error! Bookmark not defined.
Figura 7.4 Stația de control de la sol ......................................... Error! Bookmark not defined.
Figura 7.5 Cadrul selectat în momentul opririi transimiei video ............ Error! Bookmark not
defined.
Figura 7.6 Selecția țintei............................................................. Error! Bookmark not defined.
Figura 7.7 Urmărirea țintei de interes........................................ Error! Bookmark not defined.
Figura 7.8 Prezentarea sistemului în cadrul BSDA .................. Error! Bookmark not defined.
Figura 7.9 Prezentarea sistemului în cadrul BSDA .................. Error! Bookmark not defined.
Figura 8.1 Structura unei rețele neuronale ................................ Error! Bookmark not defined.
Figura 8.2 Funcționarea unui neuron tipic ................................ Error! Bookmark not defined.
Figura 8.3 Reprezentări ale funcțiilor de transfer ..................... Error! Bookmark not defined.
Figura 8.4 Algoritmul de antrenament al propagării înapoi....................................................68

NECLASIFICAT
din
NECLASIFICAT

Capitolul 1
Introducere

Aeronava fără pilot (Unmanned Aerial Vehicle - UAV) este un aparat


de zbor căruia îi lipsește pilotul uman, fiind ghidat fie de către un autopilot
computerizat aflat la bordul său sau în altă aeronavă pilotată, fie prin legătură
telecomandată cu o stație de comandă și control de la sol. Avioanele fără pilot
militare sunt folosite pentru recunoaștere, supraveghere, spionaj sau în scop
combativ. În funcție de scop ele au ca sarcină utilă aparatură de recunoaștere
sau/și arme.

1.1 Componența unui UAS

O descriere și mai simplă a unui avion fără pilot este că acesta reprezintă
o aeronavă la care personalul navigant a fost îndepărtat și înlocuit cu un sistem
informatic și o legătură radio. În realitate, este mult mai complex de atât
deoarece aeronava trebuie să fie concepută de la început, fără personal navigant
ceea ce implică o complexitate ridicată. Aeronava este doar o parte, deși este o
parte importantă, a unui întreg sistem. Acest sistem de avioane fără pilot este
conceput că un întreg și este compus din următoarele componente și sisteme
majore:

a) aeronava fără pilot (UAV) care transportă sarcină utilă și care poate
fi de mai multe tipuri;

b) stația terestră de control (GCS) din care se operează sistemul, în care


se află interfețele dintre operatori și restul sistemului;
c) sistemul de comunicațîi între GCS și UAV. Stația de control transmite
comenzile pentru controlul aeronavei, în timp ce avionul primește comenzile de
la GCS și transmite înapoi datele de la senzorii sarcinei utile și cei pentru
controlul zborului (acest lucru este realizat, de obicei, de o legătură radio).
Acest sistem este cunoscut și ca terminal de date (GDT) care poate fi atât ca
sistem de sine stătător sau poate fi inclus în compunerea stației terestre de
comandă și control.

NECLASIFICAT
din
NECLASIFICAT

d) echipamente de sprijin la sol (GSE) care pot include elemente de


întreținere și de transport al sistemului;
e) siteme de lansare și recuperare a UAV-ului;
f) software-ul folosit în vederea operării aeronavei

Figura 1.1 – Componența unui UAS

1.2 Sistem de urmărire

Odată cu avansul tehnologic tot mai accelerat,costul camerelor video și a


dispozitivelor de stocare digitale a devenit tot mai accesibil. În ultimii ani
observăm o creștere remarcabilă a cantitații de date video înregistrate și stocate
în lume. Pentru a putea procesa toate aceste informații video, a apărut nevoia
analizei automate și înțelegerii conținutului datelor video. Unul din procesele de
bază când vine vorba de analiză conținutului video îl reprezintă urmărirea țintei
de interes,fenomen ce constă în localizarea și determinarea configurației unuia
sau mai multor obiecte aflate în mișcare în fiecare frame. Supravegherea video
este una dintre cele mai importante. Sistemele de supraveghere nu numai că
înregistrează informațiile vizuale observate dar și extrag date cu privire la
mișcare și, mai recent analizează schimbările suspecte din cadru.
Tot mai multe structuri din cadrul Sistemului Național de Apărare și
Securitate au început să folosească platforme aeriene autonome pentru diferite
misiuni. Aceste UAV-uri sunt concepute pentru a putea transporta o multitudine
de senzori la bord, dar majoritatea utilizează senzori optici, în spectrul vizibil
sau IR și, mai rar, în spectrul UV. Acest lucru duce în mod inevitabil la
procesarea fluxului video pentru a extrage informațiile de interes pentru
operatorul de la sol. Pentru îndeplinirea misiunii ISR (Intelligence Surveillance
Reconnaissance), detectarea și urmărirea obiectelor sunt esențiale pentru
surprinderea elementelor esențiale dintr-un cadru.

NECLASIFICAT
din
NECLASIFICAT

Detectarea obiectelor și urmărirea țintelor sunt două domenii importante


ale “computer vision”, care, dacă sunt implementate cu ajutorul algoritmilor de
inteligență artificială, pot face sistemele autonome mai exacte și mai utile
omului.
Există o gama largă de aplicații când vine vorba de urmărirea diverselor
obiecte care interesează, de aici și motivația cercetătorilor la nivel mondial de a
își îndrepta atenția sprea acest domeniu. Supravegherea video este una dintre
cele mai importante. Sistemele de supraveghere nu numai că înregistrează
informațiile vizuale observate dar și extrag date cu privire la mișcare și,mai
recent analizează schimbările suspecte din cadru. Pot fi urmărite vizual
avioane, vehicule, animale, microorganisme sau alte obiecte care se mișcă dar
detectarea și urmărirea oamenilor este de mare interes. De exemplu, aplicațiil de
numărare a oamenilor, pot furniza informații importante despre transportul
public, congestia traficului, comerț și securitate.
Urmărirea unei ținte de interes într-un material video a devenit o zona de
cercetare de mare importanță în domenii ca procesarea de imagini sau
inteligența artificială.Urmărirea constă în determinarea traictoriei țintei în timp,
în secvențe video. Acest proces își găsește utilitatea în aplicații în diverse
domenii precum: securitatea, supravegherea,aplicațiile medicale, educația,
divertismentul, aplicațiile biomecanice, interacțiunea robot-om.

Figura 1.2 – Urmărire bazată pe procesare de imagine

În mod normal, un sistem de urmărire bazat pe procesarea video combină


următoarele trei etape de procesare a informațiilor: extragerea țintei, urmărirea
și deciziile privind acțiunile viitoare.
Există doi pași cheie în procesul de urmărire a obiectelor:
-detectarea țintelor: detectarea unui obiect într-un scenariu dat.
-urmărirea țintelor: urmărirea obiectului în fiecare imagine.

NECLASIFICAT
din
NECLASIFICAT

Prin urmare, utilizarea algoritmilor de urmărire este pertinentă în sarcini


ca:
- recunoașterea pe baza mișcării, adică identificarea umană bazată pe mers,
detectarea automată a obiectelor etc;
- supravegherea automată, adică monitorizarea unui cadru pentru a detecta
activități suspecte sau evenimente nedorite;
- indexarea automată a imaginilor, automatizarea și reținerea datelor din
bazele de date multimedia;
- monitorizarea traficului, acțiune ce presunpune colectarea în timp real a
informațiilor cu privire la trafic;
- navigarea vehiculelor, adică posibilitatea planificării traseelor video și
evitarea obstacolelor;
Urmărirea obiectelor este foarte complexă din cauza mai multor
probleme. Următoarele dificultăți apar în timpul în timpul urmăririi:
- pierderea de informații cauzate de proiecția obiectelor 3D pe o imagine 2D;
- formă și dimensiunea țintei poate varia de la imagine la imagine;
- ocluzia parțială sau completă a obiectului;
- cerințele de procesare în timp real;
- prezența zgomotului și a neclaritații video;
- modificări de lumina și de intensitate;
- mișcarea bruscă a obiectului;
Obiectivul urmării video este de a asocia obiectul-țintă în cadre video
consecutive. Asocierea poate fi deosebit de dificilă atunci când obiectele se
mișcă rapid în raport cu rată cadrelor. O altă situație care care crește
complexitatea problemei este atunci când obiectul urmărit își schimbă
orientarea în timp. În aceste situații, sistemele de urmărire video folosesc de
obicei un model de mișcare care descrie modul în care imaginea țintei s-ar putea
modifică pentru diferite posibile mișcări ale obiectului.
Urmărirea poate fi simplificată prin impunerea constrângerilor asupra
mișcării și/ sau aspectului obiectelor. De exemplu, aproape toți algoritmii de
urmărire presupun ca mișcarea obiectului este lină fără modificări bruște. O
constrângere în plus ar fi că mișcarea obiectului să aibă o viteză constantă sau o
accelerație constanta pe baza informațiilor anterioare. Cunoștințe despre
numărul și dimensiunea țintelor sau despre aspect și formă, pot fi, de asemenea,
utilizate pentru a simplifică problema.

1.3 Metode de reprezentare a țintelor dinamice si statice

Au fost propuse numeroase abordări pentru urmărirea obiectelor. Acestea


diferă în primul rând una față de cealaltă, pe baza modului în care abordează
următoarele întrebări: Care este modul cel mai potrivit de reprezentare a

NECLASIFICAT
din
NECLASIFICAT

obiectului ce urmează a fi urmărit? Care dintre caracteristicile imaginii ar trebui


folosite? Cum ar trebui să fie modelate mișcarea, aspectul și formă obiectului?
Răspunsurile la aceste întrebări depind de contextul / mediul în care se
efectuează urmărirea și utilizarea finală. În scopul obținerii unor soluții acestor
diverse scenarii, au fost propuse mai multe metode de urmărire.
Într-un scenariu de urmărire, un obiect poate fi definit ca orice care
prezintă interes pentru o analiză ulterioară. De exemplu, bărcile pe mare,
persoanele dintr-un aeroport, vehiculele pe un drum, avioanele din spațial
aerian, etc. Obiectele pot fi reprezentate de formă și carcteristicile lor. În
continuare vom descrie tipurile principale de reprezentări folosite pentru
urmărirea obiectelor:
Puncte. Obiectul este reprezentat de un punct, adică centrul țintei. În
general, reprezentarea prin puncte este folosită pentru urmărirea obiectelor care
ocupă regiuni mici dintr-o imagine.
Forme geometrice. Formă obiectului este reprezentată de un cerc,
dreptunghi, elipsă, etc. Mișcarea obiectelor pentru astfel de reprezentări este de
obicei modelată prin translație, sau transformare proiectivă. Deși formele
geometrice primitive sunt mai potrivite pentru reprezentarea obiectelor rigide
simple, ele sunt de asemenea folosite pentru urmărirea obiectelor neregulate.
Silueta obiect și contur. Reprezentarea conturului definește limita unui
obiect. Regiunea din interiorul conturului este denumită silueta obiectului.
Această metodă este recomandată pentru urmărirea formelor complexe și
flexibile.
Modele cu forme articulate. Obiectele articulate sunt formate din părți
care sunt ținute împreună cu articulații. De exemplu, corpul uman poate
reprezenta o țintă articulate cu trunch, picioare, mâini și cap. Relația dintre părți
este descrisă de modelele de mișcare cinematică, de exemplu, unghiul
articulației,etc. Pentru a reprezenta un obiect articulat, se pot modela părțile
componente utilizând cilindri sau elipse.
Modele scheletice. Scheletul poate fi obținut prin aplicarea
transformării axei mediane siluetei obiectului. Acest model este folosit pentru
recunoașterea obiectelor. Reprezentarea scheletului poate fi utilizată pentru a
modela atât obiectele articulate cât și pe cele rigide.
Există mai multe moduri de a reprezenta caracteristicile de aspect ale
obiectelor. Trebuie menționat că reprezentările de formă pot fi combinate cu
reprezentările de aspect.

NECLASIFICAT
din
NECLASIFICAT

Figura 1.3 – Tipuri de reprezentări a țintelor

Densitatea de probabilitate a apariției obiectului. Estimările


densității de probabilitate ale aspectului obiectului pot fi parametrice sau
neparametrice cum ar fi ferestrele Parzen și histogramele. Densitățile de
probabilitate ale caracteristicilor aspectului obiectului (culoare, textură) pot fi
calculate din regiunile specificate din imagine (regiunea interioară a unei elipse
sau a unui contur).
Șabloanele. Acestea sunt formate folosind forme geometrice simple sau
siluete. Avantajul unui șablon este că deține atât informații spațiale, cât și
informații despre aspect. Șabloanele codifică însă numai aspectul obiectului
generat dintr-o singură vizualizare. Astfel, acestea sunt potrivite doar pentru
urmărirea obiectelor ale căror poziții nu variază considerabil în timpul unei
urmăriri.
Modelele cu aspect activ. Sunt generate de modelarea simultană a
formei și aspectului obiectului. În general, forma obiectului este definită de un
set de repere. Similar cu reprezentarea bazată pe contur, reperele pot fi
poziționate pe limita obiectului sau în interiorul regiunii obiectului. Pentru
fiecare reper este stocat un vector de aspect care poate fi sub formă de culoare,
textură sau magnitudine de gradient. Modelele cu aspect active necesită o faza
de formare în care, atât forma, cât și aspectul asociat sunt “învățate” dintr-un set
de eșantioane utilizând, de exemplu, analiză principalului component.
Modele cu aspect multiplu. Aceste modele codifică vizualizări diferite
ale unui obiect. O abordare pentru a reprezenta diferitele vederi ale obiectului
este de a genera un subspatiu din vizualizările date. Abordările subspatiului, de
exemplu, Analiză Principala a Componentelor și Analiză Independența a
Componentelor, au fost utilizate atât pentru reprezentarea formei cât și a
aspectului. O altă abordare a “învățării” diferitelor vederi ale unui obiect este
formarea unui set de clasificatori, de exemplu mașinile de vector de suport sau
rețelele bayesiene. O limitare a acestei metode este reprezentată de faptul că
toate vederile obiectului sunt necesare înaintea începerii urmării.

NECLASIFICAT
din
NECLASIFICAT

În general, există o strânsă legătură între modul de reprezentare a


obiectului și algoritmii de urmărire. Reprezentările obiectelor sunt de obicei
alese în funcție de domeniul aplicației. Pentru urmărirea țintelor care apar foarte
mici într-o imagine, reprezentarea prin puncte este de obicei potrivită. De
exemplu, Veenman utilizează reprezentarea prin puncte pentru a urmări
semințele dintr-o farfurie aflată în mișcare. În mod similar, Shafique și Shah
utilizează aceeași metodă pentru a urmări la distanță păsări. Pentru obiectele ale
căror forme pot fi aproximate prin dreptunghiuri sau elipse, reprezentările
geometrice primitive sunt mai potrivite. Comaniciu utilizează o reprezentare
eliptică a formei și calculează histograma de culoare a regiunii eliptice pentru
modelarea aspectului. Black și Jepson au folosit vectori proprii pentru a
reprezenta aspectul țintei. Vectorii proprii au fost generați din șabloane
dreptunghice ale obiectului.
Pentru urmărirea țintelor cu forme complexe, de exemplu oamenii,
conturul sau reprezentarea bazată pe silueta sunt adecvate. Haritaoglu utilizează
siluete pentru urmărirea în aplicații de supraveghere.
Selectarea caracteristicilor potrivite joacă un rol esențial în urmărire. În
general, cea mai dorită proprietate a unei trăsături vizuale este unicitatea
acesteia, astfel încât obiectele să poată fi ușor de remarcat în spațiul fizic.
Funcțiile de selecție se referă la descrierea obiectelor. De exemplu, culoarea este
utilizată că o caracteristică pentru reprezentările de aspect ale histogramei, în
timp ce pentru reprezentarea bazată pe contur, marginile obiectului sunt de
obicei utilizate că elemente. În general, mulți algoritmi de urmărire utilizează o
combinație a acestor caracteristici. Detaliile caracteristicilor vizuale comune
sunt următoarele:
Culoarea. Este influențată în principal de doi factori fizici: a)
Distribuția spectrală a puterii iluminatului b) Proprietățile de reflexie a
suprafeței obiectului. În procesarea imaginilor, pentru reprezentarea culorilor
este folosit spațiul RGB (roșu, verde, albastru). Spațiul RGB nu este un spațiu
de culoare perceptual uniform, adică diferențele dintre culorile din spațiul RGB
nu corespund diferențelor de culoare percepute de om fapt ce impune trecerea în
spațiul HSV (Hue, Saturation, Value) care este aproximativ uniform.
Marginile. Limitele obiectului generează de obicei schimbări puternice
în intensitatea imaginii. Detecția marginilor este utilizată pentru a identifica
aceste modificări. O proprietate interesantă a marginilor este că acestea sunt mai
puțin sensibile la modificările de iluminare comparativ caraceristicile de
culoare. Algoritmii care urmăresc limitele obiectelor folosesc marginile drept
caracteristică reprezentativă. Datorită simplității și preciziei sale, cea mai
populară metodă de detectare a marginilor este detectorul Canny Edge. O
evaluare a algoritmilor de detectare a marginilor este furnizată de Bowyer.
Fluxul optic. Este un câmp dens de vectori de deplasare care definește
translația fiecărui pixel dintr-o anumită regiune. Se calculează utilizând

NECLASIFICAT
din
NECLASIFICAT

constrângeri de luminozitate, care presupun constanța luminozității pixelilor în


cadre consecutive. Fluxul optic este frecvent utilizat că o caracteristică în
aplicațiile de segmentare și urmărire pe baza de mișcare. Cele mai utilizate
tehnici pentru calculul fluxului optic dens includ metodele Horn și Schunck,
Lucas și Kanade, Black și Anandan, Szelinski și Couglan.
Textura. Reprezintă o măsură a variației intensității unei suprafețe care
cuantifica proprietăți precum netezimea sau regularitatea. Comparativ cu
culoarea, textura necesită un pas de procesare pentru a genera descriptorii.
Similar cu caracteristicile de contur, caracteristicile de textura sunt mai puțin
sensibile la modificările de iluminare.

Capitolul 2
Descrierea sistemului

2.1 Structura sistemului

Obiectivul urmăririi video este de a asocial obiecte-țintă în cadre video


consecutive. Asocierea poate fi deosebit de dificilă atunci când obiectele se
mișcă rapid în raport cu rata cadrelor. O altă situație care crește complexitatea
problemei este atunci când obiectul urmărit își schimbă orientarea în timp. În
aceste situații, sistemele de urmărire video folosesc de obicei un model de
mișcare care descrie modul în care imaginea țintei s-ar putea modifică pentru
diferite posibile mișcări ale obiectului.
Diagrama sistemului de urmărire a unei ținte terestre care a fost proiectat
este prezentată în figura următoare.

NECLASIFICAT
din
NECLASIFICAT

Figura 2.1 – Structura sistemului de urmărire automată

2.2 Camera stereo ZED

Senzorul optic este reprezentat de camera stereo Zed. O cameră stereo


este un tip de cameră cu două sau mai multe obiective, cu un senzor de imagine
separat sau un cadru de film pentru fiecare obiectiv. Acest fapt permite camerei
să simuleze vederea binoculară umană și, prin urmare, îi oferă capacitatea de a
capta imagini tridimensionale, proces cunoscut sub numele de fotografie stereo.
Camerele stereo pot fi utilizate pentru realizarea de imagini stereofonice și
imagini 3D pentru filme sau pentru imaginile în rază de acțiune. Distanța dintre
lentilele dintr-o cameră stereo tipică (distanța intra-axială) este de aproximativ
distanța dintre ochi (cunoscută sub numele de distanța intra-oculară) și este de
aproximativ 6,35 cm, deși o linie de bază mai lungă (o distanță mai mare între
camere ) produce o dimensiune 3D mai mare.
ZED este o cameră care reproduce modul în care funcționează vederea
umană. Ochii umani sunt separați orizontal cu aproximativ 65 mm în medie.
Astfel, fiecare ochi are o viziune ușor diferită a mediului înconjurător. Prin
compararea acestor două vederi, creierul nostru poate deduce nu numai
mișcarea în adâncime, ci și mișcarea 3D în spațiu. De asemenea, ZED are doua
camere despărțite de 12 cm care captează un film 3D de înaltă rezoluție și
estimează adâncimea și mișcarea prin compararea deplasării pixelilor între
imaginile din stânga și din dreapta.

NECLASIFICAT
din
NECLASIFICAT

Folosind cele două camere și triangularea, ZED oferă o înțelegere


tridimensională a scenei pe care o observă, permițând aplicației utilizate să
devină “conștienta” de spațiu și mișcare. ZED este o cameră stereo 2K cu
senzori RGB , 4MP, un câmp vizual de 110 ° și diafragmă ƒ / 2,0. Poate percepe
adâncimi între 50 cm și 20 de m. Are posibilitatea să detecteze obiecte la o
distanță mai mică de 30 de cm dar va apărea zgomotul. Camera ZED, spre
deosebire de senzorii tradiționali de adâncime, captează adâncimea de la
imaginile stereo RGB (roșu, verde, albastru) în loc de IR. Lentilele au un filtru
încorporat care blochează lumina IR care poate ajunge la senzor. În concluzie,
camera nu este sensibil la IR și nu va funcționa corect în întuneric complet,
chiar și cu un iluminator IR.
Cadrele video din stânga și din dreapta sunt sincronizate și redate în flux
că un singur cadru video necomprimat. ZED afișează imagini în diferite
formate. Se poate selecta între imaginile rectificate, nerectificate și în tonuri de
gri:
· Vedere stânga
· Vedere dreapta
· Vedere laterală
· Stânga sau Dreapta în nuanțe de gri

Figura 2.2 – Cameră stereo ZED

API-ul ( Interfata de Programare a Aplicatiei) ZED oferă acces „low


level” la controlul și configurarea camerei. Pentru a utiliza ZED în aplicația

NECLASIFICAT
din
NECLASIFICAT

dezvoltata, a fost necesara crearea si deschiderea unui obiect Camera . API-ul


poate fi utilizat cu două intrări video diferite: video live ZED (modul Live) sau
fișiere video înregistrate în format SVO cu API ZED (modul Redare). Dupa
crearea obiectului Camera, au fost specificati parametrii initiali. Parametrii
initiali permit reglarea rezolutiei, FPS-ului, parametrilor de detectare, a
adancimii, etc. Acești parametri pot fi setați numai înainte de a deschide camera
și nu pot fi modificați în timp ce camera este în uz.

Figura 2.3 – Colectarea fluxului video

Camera ZED dispune de un ISP (Procesor de Semnal de Imagine) care


efectuează diverși algoritmi de procesare a imaginii pe imaginea primă
capturată de senzorii de imagine duali. Mai mulți parametri ai ISP pot fi ajustați
direct din aplicația Explorer ZED sau din SDK-ul(Kit de Dezvoltare Software)
ZED:
 Rezoluţie
 FPS
 Luminozitate
 Contrast
 Nuanță - Controlează culoarea imaginii.
 Saturație - Controlează intensitatea culorii imaginii.
 Gamma - Controlează corecția gama.
 Expunere - Controlează viteza obturatorului. Setarea unei perioade lungi
de expunere duce la o creștere a neclarității.
 Câștigul - Controlează amplificarea digitală a semnalului de la senzorul
camerei.
Când camera este în modul "Auto", parametrii cum ar fi expunerea și
câștigul sunt ajustați automat în funcție de scenă.

NECLASIFICAT
din
NECLASIFICAT

Hârtile de adâncime captate de ZED nu pot fi afișate direct deoarece


sunt codate pe 32 de biți. Pentru a afișa harta de adâncime, este necesară o
reprezentare monocromă (în nuanțe de gri) de 8 biți cu valori între [0, 255],
unde 255 reprezintă cea mai apropiată valoare de adâncime posibilă și 0 cea mai
îndepărtată valoare a adâncimii posibile.
Urmarirea pozițională este capacitatea unui dispozitiv de a-și estima
poziția în raport cu mediul inconjurator. De asemenea, se numește urmărirea
mișcării sau potrivire în industria cinematografică, aceasta fiind utilizată pentru
a urmări mișcarea unei camere sau a unui utilizator în spațiul 3D cu șase grade
de libertate (6DoF). ZED utilizează urmărirea vizuală a împrejurimilor pentru a
înțelege mișcarea utilizatorului sau a sistemului care îl ține. Pe măsură ce
camera se mișcă în lumea reală, raportează noua poziție și orientarea.
Memoria spațială se referă la memoria umană pentru informații spațiale,
cum ar fi aspectul geografic al unui oraș sau în interiorul unei case. Pe măsură
ce omul intră în contact cu diverse medii, sunt stocate informații despre
împrejurimi care formează o reprezentare spațială coerentă a mediului în
memorie. În mod similar, ZED construiește și actualizează o reprezentare
spațială a împrejurimilor sale atunci când descoperă un mediu. Această
reprezentare este stocată sub forma unei hărți euristice numite fișier zonă.
Fișierele zonă reprezintă reprezentări compacte și eficiente ale unui mediu care
nu sunt destinate vizualizării. Ele sunt utile pentru a crea o experiență
consistentă și repetabilă într-o anumită zonă. Ele pot fi, de asemenea, folosite
pentru a localiza mai multe dispozitive din aceeași zonă. Memoria spațială este
utilizată când urmatoarele trei condiții au fost indeplinite:
 Camera a avut o experiență consistentă intr-o anumită zona.
 A fost imbunatățită urmărirea pozitională prin corectarea deviațiilor.
 Au fost localizate mai multe dispozitive ZED în același spațiu.
Mișcarea este relativă față de o poziție de observare. De exemplu dacă
un utilizator va ține un ZED si se va deplasa, camera nu se va mișca în raport cu
utilizatorul, dar va fi în mișcare în raport cu podeaua. In acelasi mod, ZED
trebuie să își exprime informațiile cu privire la mișcare în raport cu un cadru de
referință. Acest cadru de referință poate fi ” World Frame” sau „Camera
Frame”.

NECLASIFICAT
din
NECLASIFICAT

Figura 2.4 – Sistemul de coordonate al camerei ZED

Vehiculele inteligente, dronele și roboții trebuie să perceapă și să


înțeleagă mediul ce îi înconjoară. Acestea trebuie să funcționeze în medii
necunoscute și nestructurate anterior, unde metodele externe de localizare, cum
ar fi GPS-ul, nu ar putea fi întotdeauna disponibile. Prin urmare este nevoie atât
de o maparea locală care să efectueze o evitare rapidă a obstacolelor, cât și o
mapare globală pentru planificarea traseului și navigație.
Urmărirea mișcării este esențială pentru crearea acestor hărți locale și
globale. Aceasta este folosită ca o intrare în modulul Mapare Spațială al ZED,
care creează o rețea 3D a mediului în timp real. Această rețea poate fi utilizată
direct pentru evitarea obstacolelor sau poate fi transformată într-o altă
reprezentare a hărții, cum ar fi o rețea de navigație pentru planificarea traseului.
Camera ZED este compatibilă UVC (Universal Video Class), astfel
încât fluxurile video din stânga și dreapta ale ZED pot fi captate pe Windows,
Linux și chiar OSX fără SDK (Kit de Dezvoltare Software) ZED.

2.3 Modulul de procesare video Nvidia Jetson TX2


Componenta principală si „creierul” sistemului este modulul de
procesare video Nvidia Jetson TX2. Jetson TX2 este un supercomputer complet.
Este cel mai rapid dispozitiv de calcul inteligent artificial încorporat la
momentul actual. Acest modul oferă soluții pentru a satisface nevoile de calcul
în domeniul inteligenței artificiale folosite în dezvoltarea mașinilor inteligente,
drone autonome si roboți inteligenți. Este construit în jurul unui GPU (Unitate
de Procesare Grafica) NVIDIA Pascal cu memorie de 8 GB și o lățime de
bandă de memorie de 59,7 GB / s. Dispune de o varietate de interfețe hardware
standard fapt ce îi faciliteaza integrarea într-o gamă largă de produse.

NECLASIFICAT
din
NECLASIFICAT

Figura 2.5 – Modul de procesare video Nvidia Jetson TX2

In continuare vor fi prezentate câteva din specificațiile tehnice ale modulului de


procesare video:

GPU (Unitatea de NVIDIA Pascal™, 256 CUDA cores


Procesare Video)
CPU (Unitatea HMP Dual Denver 2/2 MB L2 + Quad ARM® A57/2
Centrala de MB L2
Procesare)
Video 4K x 2K 60 Hz Encode (HEVC) 4K x 2K 60 Hz Decode
(12-Bit Support)
Memorie 8 GB 128 bit LPDDR4 59.7 GB/s
Display 2x DSI, 2x DP 1.2 / HDMI 2.0 / eDP 1.4

NECLASIFICAT
din
NECLASIFICAT

CSI Pana la 6 camere (2 Lane) CSI2 D-PHY 1.2 (2.5


Gbps/Lane)
PCIE Gen 2 | 1x4 + 1x1 OR 2x1 + 1x2
USB USB 3.0 + USB 2.0
Spatiu de stocare 32 GB eMMC, SDIO, SATA
Conectivitate 1 Gigabit Ethernet, 802.11ac WLAN, Bluetooth
Dimensiuni 50 mm x 87 mm

Figura 2.6 – Caracteristici tehnice ale modulului de procesare video Nvidia


Jetson TX2

2.4 Interfață Carrier Orbitty

Modulul de procesare video Nvidia Jetson TX2 a fost amplasat pe o


placă de transport Orbitty. Placa de transport este utilizată împreuna cu un
computer pe modul (CoM) / sistem pe modul (SoM). Placa de transport conține
conectivitatea specifică aplicației și interfețele multimedia, cum ar fi USB,
Ethernet, UART, HDMI etc. Placa transportoare se conectează cu SoM prin
conectori standard.

Figura 2.7 – Interfață Carrier Orbitty

2.5 Transmisie de date UART

Transmisia deviațiilor rezultate în urma procesării video către platforma


giro-stabilizată se face folosind comunicația UART (Transmitator-Receptor
Asincron Universal). Un transmițător-receptor universal asincron (UART) este
un dispozitiv hardware pentru comunicații seriale asincrone în care formatul de
date și vitezele de transmisie sunt configurabile. Un UART este, de obicei, un
circuit integrat (sau o parte a unui) integrat (IC) folosit pentru comunicații
seriale pe un port serial al unui computer sau dispozitiv periferic. Unul sau mai
multe periferice UART sunt integrate în cipurile microcontrolerului. Un
dispozitiv asemănător, transmițătorul receptor universal-sincron și asincron

NECLASIFICAT
din
NECLASIFICAT

(USART) susține de asemenea funcționarea sincronă. Receptorul-transmițător


universal asincron (UART) ia octeți de date și transmite biții individuali într-un
mod secvențial. La destinație, un al doilea UART „asamblează” biții în octeți
compleți. Fiecare UART conține un registru de deplasare, care este metoda
fundamentală de conversie între formele seriale și cele paralele. Transmisia
serială a informațiilor digitale (biți) printr-un singur fir sau alt mediu este mai
puțin costisitoare decât transmisia paralelă prin fire multiple.
De obicei, UART nu generează sau recepționează direct semnalele
externe utilizate între diferitele echipamente. Dispozitivele separate de interfață
sunt utilizate pentru a converti semnalele de nivel logic ale UART la și de la
nivelurile de semnalizare externă, care pot fi niveluri de tensiune standard,
nivele de curent sau alte semnale. Comunicarea poate fi simplă (numai într-o
singură direcție, fără a prevedea ca dispozitivul de recepție să trimită informații
înapoi la dispozitivul de transmisie), duplex complet (ambele dispozitive trimit
și recepționează în același timp) sau jumătate duplex.
Starea inactivă, lipsită de date este de înaltă tensiune. Aceasta este o
moștenire din telegrafie, în care linia este menținută la înălțime pentru a arăta
că linia și emițătorul nu sunt deteriorate. Fiecare caracter este încadrat ca un bit
logic de pornire redus, biți de date, opțional un bit de paritate și unul sau mai
mulți biți de stop. În majoritatea aplicațiilor, cel mai puțin semnificativ bit de
date este transmis primul.

Figura 2.8 – Secvență de biți în transmisia UART

Bitul de pornire semnalează receptorului că vine un caracter nou.


Următorii cinci până la nouă biți, în funcție de setul de coduri folosit, reprezintă
caracterul. Dacă se folosește un bit de paritate, acesta va fi plasat după toți biți
de date. Următorii unul sau doi biți sunt întotdeauna în starea marcată (logică
ridicată, adică "1") și numiți biții de oprire.
Ei semnalează receptorului că informația transmisă este completă.
Deoarece bitul de pornire este logic scăzut (0) și bitul de stop este logic ridicat
(1), există întotdeauna cel puțin două schimbări de semnal garantate între
caractere.
Toate operațiile hardware-ului UART sunt controlate de un semnal de
ceas, care rulează la o viteză mai mare, de obicei de 8 ori mai mare decât rata
biților. Receptorul testează starea semnalului de intrare pe fiecare impuls de
ceas, căutând începutul bitului de pornire. Dacă bitul de pornire durează cel

NECLASIFICAT
din
NECLASIFICAT

puțin jumătate din timpul biților, acesta este valabil și semnalează începutul
unui nou caracter.
Comunicația UART nu are de obicei niciun sistem de sincronizare
partajat în afară de semnalul de comunicare. În mod obișnuit, UART-urile își
resincronizează ceasurile interne la fiecare schimbare a liniei de date care nu
este considerată un impuls fals. Obținând informații de sincronizare în acest
mod, acestea află în mod fiabil când transmițătorul trimite o viteză ușor diferită
decât ar trebui. UART-urile simplificate nu fac acest lucru, în schimb
resincronizează pe marginea descendentă a bitului inițial și apoi citesc centrul
fiecărui bit de date așteptat iar acest sistem funcționează dacă rată de transmisie
este suficient de precisă pentru a permite biților de stop să fie eșantionați în mod
fiabil.
Operația de transmisie este mai simplă, deoarece nu trebuie determinată
temporizarea de la starea liniei, nici nu este legată de intervale fixe de timp. De
îndată ce sistemul de expediere depune un caracter în registrul de deplasare
(după completarea caracterului anterior), UART generează un bit de pornire,
schimbă numărul de biți de date pe linie, generează și trimite bitul de paritate
(dacă este folosit ) și trimite biții de stop.
Transmisia și recepționarea UART-urilor trebuie să fie setate pentru
aceeași viteză de biți, lungime de caractere, paritate și biți de oprire pentru o
funcționare corectă. UART-ul de recepție poate detecta unele setări
necorespunzătoare și poate seta un bit de flag "eroare de încadrare" pentru
sistemul gazdă; în cazuri excepționale, UART-ul de recepție va produce un flux
neregulat de caractere și le va transfera în sistemul gazdă.

Figura 2.9 – Schema transmisiei UART

2.6 Biblioteca publică OpenCV

Pentru realizarea proiectului a fost folosită o biblioteca publică ce


conține peste 2500 de algoritmi dedicați procesării de imagini OpenCV.

NECLASIFICAT
din
NECLASIFICAT

Lansat oficial în 1999, proiectul OpenCV a fost inițial o tentativă a Intel


Research pentru avansarea aplicațiilor intensive ale CPU, parte a unei serii de
proiecte, inclusiv urmărirea în timp real a radiațiilor. Principalii contribuabili la
proiect au inclus un număr de experți de optimizare ai Intel Rusia, precum și
echipa de la Intel Performance Library. În primele zile ale programului
OpenCV, obiectivele proiectului au fost descrise ca fiind următoarele:
 Cercetarea avansată în domeniul CV oferind nu numai cod deschis, dar și
optimizat, pentru infrastructura de viziune de bază.
 Diseminarea cunoștințelor despre CV prin furnizarea unei infrastructuri
comune pe care dezvoltatorii ar putea să o valorifice, astfel încât codul să
fie mai ușor de citit și transferat.
 Aplicații comerciale bazate pe CV avansate, oferind gratuit un cod
portabil, optimizat pentru performanță - cu o licență care nu necesită un
cod deschis sau gratuit.

Figura 2.10 – Logo OpenCV-Python

Prima versiune alfa OpenCV a fost lansată publicului la Conferința


IEEE privind Computer Vision și Recognition Pattern în 2000 și cinci beta-uri
au fost lansate între 2001 și 2005. Prima versiune 1.0 a fost lansată în 2006. O
versiune 1.1 "pre-release "a fost lansat în octombrie 2008. Cea de-a doua
lansare majoră a programului OpenCV a fost în octombrie 2009. OpenCV 2
include schimbări majore în interfața C ++, având ca scop modele mai ușoare,
mai sigure, noi funcții și implementări mai bune pentru cele existente în termeni
de performanță. Comunicatele oficiale au loc acum o dată la șase luni, iar
dezvoltarea este făcută acum de o echipă rusă independentă, susținută de
corporații comerciale. În august 2012, sprijinul pentru OpenCV a fost preluat de
o fundație non-profit OpenCV.org.
OpenCV (Open Source Computer Vision Library) este o sursă publică
pentru aplicații în domeniul CV și o bibliotecă software pentru învățarea
mașinilor. A fost construit pentru a oferi o infrastructură comună pentru
aplicatiile CV si pentru a accelera utilizarea percepției mașinilor în produsele
comerciale. OpenCV permite modificarea codului de către utilizatori. Biblioteca

NECLASIFICAT
din
NECLASIFICAT

are peste 2500 de algoritmi optimizați, care includ un set complet de algoritmi
de CV precum și algoritmi de ML. Acești algoritmi pot fi utilizați pentru a
detecta și a recunoaște fețele, a identifica obiecte, a clasifica acțiunile umane în
videoclipuri, a urmări mișcările camerei, a urmări obiectele în mișcare, a
extrage modele 3D ale obiectelor, găsirea unor imagini similare dintr-o bază de
date a imaginilor, urmărirea mișcărilor ochilor, recunoașterea peisajelor etc.
OpenCV are mai mult de 47 mii de utilizatori și numărul estimat de descărcări
depășește 14 milioane. Biblioteca este utilizată extensiv în companii, grupuri de
cercetare și organisme guvernamentale. Pe lângă companii celebre precum:
Google, Yahoo, Microsoft, Intel, există multe companii mai puțin cunoscute:
Applied Minds, VideoSurf etc, care folosec această sursă publică. OpenCV
acopera o gamă largă de aplicații, de la detectarea intruziunilor într-un video în
Israel, monitorizarea echipamentelor miniere în China, navigația roboților în
SUA, detectarea accidentelor de înec in Spania, până la verificarea pistelor în
Turcia și analiza facială in Japonia. Această biblioteca software are interfețe
C++, Python, Java, MATLAB și suportă drept sisteme de operare, Windows,
Linux, Android și Mac OS. OpenCV se bazează în principal pe aplicațiile
vizuale în timp real și beneficiază de instrucțiunile MMX și SSE atunci când
sunt disponibile. Există peste 500 de algoritmi și aproximativ de 10 ori mai
multe funcții care compun sau susțin acești algoritmi. OpenCV este scris în C
++ și are o interfață template care funcționează fără probleme cu containerele
STL. Toate noile dezvoltări și algoritmi din OpenCV sunt acum dezvoltate în
interfața C++. OpenCV 3 vine cu un nou API de urmărire care conține
implementări ale mai multor algoritmi de urmărire. Exista șase algoritmi de
urmărire diferiți disponibili: BOOSTING, MIL, KCF, TLD, MEDIANFLOW si
GOTURN.
2.7 Limbaj de programare Python 3.5

Implementarea algoritmului de urmărire a fost facută in Python 3.5.


Acest limbaj de programare este unul interactiv, interpretat, modular și orientat
pe obiect.
Python este un limbaj de programare folosit la nivel înalt pentru
programare generală. Creat de Guido van Rossum și lansat pentru prima dată în
1991, Python are o filozofie de design care accentuează lizibilitatea codului,
folosind în special spațiu alb. Oferă construcții care permit o programare clară
atât pe scări mici cât și pe scări mari. Dispune de un sistem de tip dinamic și de
gestionare automată a memoriei. Acesta susține mai multe paradigme de
programare, inclusiv obiect-orientate, imperativ, funcțional și procedural, și are
o bibliotecă standard și vastă. Python a fost conceput la sfârșitul anilor 1980, iar
implementarea acestuia a început în decembrie 1989 de Guido van Rossum la
Centrum Wiskunde & Informatica (CWI) din Olanda ca succesor al limbajului

NECLASIFICAT
din
NECLASIFICAT

ABC capabil să gestioneze excepțiile și să interfereze cu sistemul de operare


Amoeba. Python 2.0 a fost lansat la 16 octombrie 2000 și a avut numeroase noi
caracteristici, inclusiv un colector de gunoi pentru detectarea ciclului și un
suport pentru Unicode. Prin această versiune, procesul de dezvoltare a devenit
mai transparent și mai bine susținut de comunitate. Python 3.0 (inițial numit
Python 3000 sau py3k) a fost lansat la 3 decembrie 2008 după o perioadă lungă
de testare. Este o revizuire majoră a limbajului care nu este complet compatibilă
cu versiunile anterioare. Cu toate acestea, multe dintre caracteristicile sale
majore au fost returnate la seria de versiuni Python 2.6.x și 2.7.x, iar versiunile
de Python 3 includ utilitarul 2to3, care automatizează traducerea codului Python
2 în Python 3.
Python este un limbaj de programare cu mai multe paradigme.
Programarea orientată pe obiecte și programarea structurată sunt pe deplin
susținute și multe dintre caracteristicile sale susțin programarea funcțională și
programarea orientată spre aspect (inclusiv prin metaprogramare și metaobiecte
(metode magice)). Multe alte paradigme sunt susținute prin extensii, inclusiv
prin contract și programare logică. Python utilizează tastarea dinamică și o
combinație de numărare de referință și un colector de gunoi pentru detectarea
ciclurilor în vederea gestionării memoriei. De asemenea, oferă o rezoluție
dinamică a numelui (legare târzie), care leagă numele metodelor și variabilelor
în timpul execuției programului. Proiectul lui Python oferă un sprijin pentru
programarea funcțională în tradiția Lisp. Are funcții filtru (), map () și reduce ();
lista de înțelegeri, dicționare și seturi. Biblioteca standard are două module
(itertools și functools) care implementează instrumentele funcționale
împrumutate de la Haskell și Standard ML.
Filosofia de bază a limbajului este rezumată în documentul Zenul
Python, care include aforisme precum:
 Frumosul este mai bun decât urâtul
 Explicit e mai bine decât implicit
 Simplu e mai bun decât complex
 Complex e mai bun decât complicat
 Divizarea contează

2.8 Sistemul de operare Linux

Inițial a fost necesar ca modulul Nvidia Jetson TX2 sa fie supus unei
„flash-uiri” cu un computer care să ruleze drept sistem de operare Linux.

NECLASIFICAT
din
NECLASIFICAT

Figura 2.11 – Logo sistem de operare Linux

Linux este o familie de sisteme de operare de tip Unix care


folosesc Nucleul Linux. Linux poate fi instalat pe o varietate largă de hardware,
începând cu telefoane mobile, tablete, console video, continuând cu calculatoare
personale până la supercomputere. Este cel mai cunoscut exemplu de colaborare
și dezvoltare Software libersub licență GPL. A fost inițial dezvoltat pentru
computerele personale bazate pe arhitectura Intel x86, dar de atunci a fost portat
pe mai multe platforme decât orice alt sistem de operare. Unele dintre cele mai
populare distribuții Linux sunt Arch Linux, CentOS, Debian, Fedora, Gentoo
Linux, Linux Mint, Mageia, openSUSE și Ubuntu. Linux este un proiect
complet “open source”. Suportă aproape toate limbajele de programare majore
(Python, C / C ++, Java, Perl, Ruby etc.). În plus, oferă o gamă largă de aplicații
de programare. Terminalul Linux este superior folosirii liniei de comandă
Window pentru dezvoltatori. Pot fi găsite biblioteci dezvoltate nativ pentru
Linux. De asemenea, o mulțime de programatori arată că managerul de pachete
pe Linux ușureaza îndeplinirea sarcinilor.

Capitolul 3
Sisteme de coordonate

3.1 Relații de legătura între sistemele de coordonate

Urmărirea țintei în planul imaginii este influențată, atât de mișcarea țintei


cât și de miscarea translațională și rotațională a aeronavei.
Se presupune că sistemele de coordonate ale aeronavei și ale gimbal-ului se află
în centrul de masă al UAV-ului.

NECLASIFICAT
din
NECLASIFICAT

Relațiile de trecere de la sistemul de coordonate legat de UAV la sistemul de


coordonate legat de payload(sarcină utilă):
Sunt 3 sisteme de interes:
 Gimbal 1: F  (i , j , k ) -in jurul axei z cu R -ul  z
g1 g1 g1 g1

 Gimbal: F  (i , j , k )
g g g g

 Camera: F  (i , j , k )
c c c c

 az - R de azimut al gimbalului
 cos  az sin  az 0
R ( az )    sin  az
g1
b cos  az 0  (3.1)
 0 0 1 
el  R de elevație al gimbal-ului

Un R de elevație negativ îndreapta camera spre pământ.


b c
d  Rg * Rc * l d
l% b g % (3.2)
Trecerea de la sistemul de coordonate legat de avion la sistemul de coordonate
legat de gimbal se face astfel:
cos  el cos az cos el sin az  sin el 
Rbg  Rbg1 * Rgg1    sin  az cos az 0  (3.3)
 sin  el sin  el sin el sin az cos el 

Literatura de specialitate în procesarea de imagine și urmărirea țintelor


notează axa din dreapta imaginii cu i c ,axa care merge în josul imaginii este
c
notată cu j ,iar axa care se îndreapta în lungul axei optice este notată cu k c .
Așadar trecerea de la un sistem de coordonate legat de gimbal la sistemul
de coordonate legat de cameră se realizeaza cu ajutorul următoarei matrici:
0 1 0 
Rgc  0 0 1  (3.4)
1 0 0 

3.2 Modelul matematic al unei camere

Modelul geometric al unei camere este următorul:

NECLASIFICAT
din
NECLASIFICAT

Figura 3.1 – Modelul geometric al camerei video

Unde:
 f=lungimea focală în pixeli
 p=convertește pixelii în metri
 PF=lungimea focală în metri
 M=nr. de pixeli pe o latură a imaginii
 v=câmpul de vedere al camerei
Pentru a simplifica modelul, vom presupune că imaginea este patrată (adică
avem același număr de pixeli atât pe lungime cât și pe lățime).
Lungimea focală în pixeli este următoarea:
M
f  (3.5)
v
2tg  
2
M=256×256 pixeli

Locația proiecției obiectului urmărit este exprimată în sistemul de


coordonate al camerei:
 Pex , Pey , Pf  unde ex si ey -locația pixelilor care definesc obiectul urmărit.
Distanța dintre originea sistemului de coordonate al camerei și locația pixelilor
 ex, ey  este dată de parametrul F,unde:
F f 2  ex 2  ey 2 (3.6)
Folosind teorema triunghiurilor asemenea rezultă:
c
lxc Pex ex l y ey lzc f
    si  (3.7)
L PF F L F L F
Rezultă:

NECLASIFICAT
din
NECLASIFICAT

 ex 
L 
l   ey 
c
(3.8)
F 
 f 
l -este vectorul obiectului de interes
L l
Trebuie precizat faptul că l c nu poate fi determinat direct din datele furnizate
de cameră atâta timp cât L este necunoscut.
Astfel se poate determina direcția vectorului la țintă:
 ex   ex 
lc 1   1  
  ey    ey  ① (3.9)
L F  ex  ey  f  
2 2 2

 f   f 
L -distanța până la țintă;
l c -ținta în sistemul de coordonate al camerei;
lc
Vectorul unitate: joacă un rol major și se notează cu:
L
 lx' 
l  
l '    l y'  , l devine normat (3.10)
L  '
 lz 

3.3 Sistem girostabilizat pentru controlul camerei

Sistemele UAV de dimensiuni mici sunt folosite, cel mai frecvent pentru
îndeplinirea misiunilor de tip ISR(Intelligence Surveillance Reconaissance).
Dacă UAV-ul este echipat cu gimbal, acest lucru implică control asupra camerei
astfel incât să focuseze asupra țintelor.
Presupunând că avem un gimbal pe 2 axe(azimut si elevație) atunci ecuațiile de
mișcare pentru ansamblul gimbal sunt:
Rbi  Rbi (3.11)
Unde uaz si uel sunt variabilele de control ale unghiurilor de azimut și elevație
ale gimbal-ului.
1. Obiectivul primului scenariu este acela de a directiona gimbalul către
ținta pe baza coordonatelor geografice date.
2. Obiectivul celui de-al doilea scenariu este acela de a directiona gimbalul
astfel încât axele optice să se alinieze cu un punct dat în planul imaginii.
Pentru acest scenariu se poate imagina ca utilizatorul în timp ce primește
fluxul de date video de la camera,poate selecta o locație în planul
imaginii, iar gimbal-ul trebuie să aducă acea locație în centrul imaginii.

NECLASIFICAT
din
NECLASIFICAT

i
1. Pentru primul scenariu,vom nota pobj ca fiind locația unui obiect în
sistemul de coordonate inerțial.
Obiectivul este alinierea axelor optice ale camerei cu vectorul de poziție
dorit:
ldi  pobj
i
 pMAV
i
(3.12)
Unde pMAVi
 ( pn , pe , pd )T .
Vectorul unitate în sistemul de coordonate legat de UAV, îndreptat în
direcția dorită, are următoarea ecuație:
b 1
l%d  i Rib * ldi (3.13)
ld
2. În cel de-al doilea scenariu, se presupune că se dorește manevrarea
gimbal-ului astfel încât locația pixelului să fie adusă în centrul imaginii.
Folosind ecuația ①, se poate determina direcția dorită a axelor optice în
sistemul de coordonate legat de cameră astfel:
 ex 
c 1  
l%d  ey  (3.14)
2 
f  ex  ey  
2 2

 f 
Astfel că în sistemul de coordonate legat de UAV, directia dorită a
axelor optice este următoarea:
b c
d  Rg * Rc * l d
l% b g % (3.15)
Următoarea etapă este determinarea unghiurilor de azimut și de elevație
astfel încât axa optică dată de vectorul  0, 0,1 .Astfel că, obiectivul
c

principal este alegerea unghiurilor de azimut și elevație comandate


 azc ,  elc  .
Rezultă:

NECLASIFICAT
din
NECLASIFICAT

 l%b

 
xd
0
 
l%d   l%yd   Rgb ( gc ,  elc ) * Rcg  0  
b b

  1
 l%b
  
 
zd

 cos  elc coscaz  sin  elc  sin  elc cos  azc   0 0 1  0 


 c   
 cos  c
el sin  c
az cos  c
az  sin  c
el sin  az   1 0 0  0  
 sin  elc cos  elc   0 1 0  1 
 0   
 cos  elc cos  azc 
 c 
 cos  c
el sin  az 
 sin  el c 
 

Prin determinarea unghiurilor de azimut și elevație comandate elc si  azc


se pot determina unghiurile de azimut și elevație dorite:
 l%b

  tg  b 
1
c yd
(3.16)
az
 l%xd 
 
  sin l zd
c
el
1 % b
  (3.17)
În concluzie, comenzile servomecanismelor care acționează gimbal-ul
pot fi definite astfel:

uaz  kaz ( azc   az )


(3.18)
uel  kel ( elc   el )
Unde kaz si kel sunt valorile câștigului sistemului de control al
gimbalului.

NECLASIFICAT
din
NECLASIFICAT

Capitolul 4
Metode de urmărire studiate

4.1 Descrierea procesului de urmărire

Scopul unui algoritm de urmărire este de a genera traiectoria unei ținte în


timp, prin determinarea poziției sale în fiecare cadru al videoclipului.
Algoritmul poate determina deasemenea regiunea completă ocupată de către
țintă în cadrul imaginii. Detectarea țintei și stabilirea relațiilor de corespondență
între instanțele țintei în cadrul fluxului video, pot fi realizate separat sau
simultan. În primul caz, posibile regiuni ale țintei sunt determinate prin
intermediul unui algoritm de detectare pentru că mai apoi, algoritmul de
urmărire să realizeze corespondențe între cadre. În cel de-al doilea caz, regiunea
obiectului și corespondență sunt estimate în comun prin actualizarea iterativă a
localizării țintei și a informațiilor despre regiunea ocupată de țintă în imagine,
obținute în cadrele anterioare. În cadrul fiecărei abordări de urmărire, obiectele
sunt reprezentate folosind modelele de formă sau aspect.

4.2 Clasificarea metodelor de urmărire

Modelul selectat pentru a reprezenta obiectul, limitează tipul de mișcare


sau deformare la care poate fi supus. De exemplu, dacă un obiect este
reprezentat ca un punct, atunci poate fi utilizat doar un model de translație.În
cazul în care pentru un obiect este utilizată o reprezentare a formei geometrice
ca o elipsă, sunt recomandate modelele de mișcare parametrica, cum ar fi
transformările afine sau proiective. Aceste reprezentări pot aproxima mișcarea
obiectelor rigide. Pentru un obiect nonrigid, silueta sau conturul reprezintă
metodă cea mai descriptivă și pot fi folosite atât modele parametrice, cât și
neparametrice în scopul descrierii mișcării acestora.

Dense Optical Flow: Se bazează pe estimarea vectorului de mișcare al


fiecărui pixel.
Sparse Optical Flow: Acești algoritmi, urmăresc poziția unor pixeli de
interes. Algoritmul Kanade-Lucas-Tomashi (KLT) face parte din aceasta
categorie.
Kalman Filtering: Determină coordonatele unui obiect aflat în mișcare
pe baza informațiilor de mișcare anterioare. Acest algoritm a fost folosit pentru
ghidarea rachetelor. De menționat faptul că modulul lunar Apollo 11 avea
calculatorul de bord cu un filtru Kaman.

NECLASIFICAT
din
NECLASIFICAT

Meanshift&Camshift: sunt folosiți pentru determinarea maximelor


unor funcții de densitate.

Figura 4.1 – Clasificare metode de urmărire

De obicei algoritmii de urmărire sunt mai rapizi decât algoritmii de


detectare. În momentul urmăririi unei ținte detectate în cadrul anterior, sunt
obținute multe informații despre aspectul țintei. Totodată este cunoscută locația
anterioară, direcția și viteză. Toate aceste informații ajută la prezicerea locației
obiectului în cadrul următor și se efectuează doar o scurtă căutare a țintei în
jurul locației așteptate. Un algoritm bun de urmărire va folosi toate aceste
informații în timp ce algoritmii de detecție sunt nevoiți să înceapă de la zero. Cu
toate că urmărirea beneficiază de informații suplimentare, are dezavantajul că
poate pierde țintă în momentul în care această este ocluzionata pentru o
perioada mai lungă de timp, dacă se mișcă mai repede decât timpul de reacție al
algoritmului sau dacă se acumulează erori. Pentru rezolvarea acestor probleme,
cei doi algoritmi rulează în paralel, algoritmul de urmărire în fiecare cadru iar
algoritmul de detecție, de regulă o dată la șase cadre. Detectoarele algoritmice
sunt instruite să recunoască un număr mare de înfățișări ale obiectului. Prin
urmare, au mai multe cunoștințe despre clasa generală a obiectului. Pe de altă
parte, algoritmii de urmărire dețin mai multe informații despre instanța specifică
clasei pe care o urmăresc.
Modelul de mișcare prezice locația aproximativă a obiectului. Modelul
de aspect apreciază această estimare pentru a furniza o estimare mai precisă pe

NECLASIFICAT
din
NECLASIFICAT

baza aspectului. Dacă obiectul a fost simplu și nu și-a schimbat mult aspectul,
se poate folosi un șablon simplu ca model de aspect. Acesta este însă cazul
ideal. Înfățișarea unui obiect se poate schimbă radical. Pentru a aborda această
problemă, la mulți algoritmi moderni, acest model de aspect este un clasificator
care este instruit într-o manieră online.
Funcția clasificatorului este de a clasifică o regiune dreptunghiulară a
unei imagini ca obiect sau fundal. Clasificatorul ia un „patch de imagine că
intrare și returnează un scor între 0 și 1 pentru a indică probabilitatea că patch-ul
de imagine să conțînă obiectul. Scorul este 0 atunci când este absolut sigur că
patch-ul de imagine este fundalul și 1 când este absolut sigur că patch-ul este
obiectul.
Un clasificator este „instruit” prin furnizarea de exemple pozitive (obiect) și
negative (de fundal). Pentru construirea unui clasificator care să detecteze

vehiculele militare, clasificatorul va trebui instruit cu mii de imagini care conțin


vehicule militare. În acest fel, clasificatorul învață cum este reprezentat un
vehicul militar.
4.3 Algoritmul BOOSTING

Clasificatorul acestui algoritm trebuie instruit în timpul rulării cu


exemple pozitive și negative. Fereastra inițială de căutare furnizată de utilizator
sau de către un alt algoritm de detectare, este considerată un exemplu pozitiv și
multe alte patch-uri din imaginea de pe lângă sunt considerate exemple
negative. În momentul în care un nou cadru este disponibil, clasificatorul este
rulat pe fiecare pixel din vecinătatea locației anterioare și scorul este înregistrat.
Noua locație a țintei este considerat unde a fost înregistrat scorul cel mai mare.
Cu toate acestea, performanțele algoritmului sunt mediocre. Principalul
dezavantaj îl reprezintă faptul că nu poate detecta în mod eficient momentul în
care a pierdut ținta.

4.4 Algoritmul bazat pe fluxul optic (Dense Optical Flow)

Fluxul optic reprezintă modelul mișcării aparente a obiectelor,


suprafețelor și marginilor într-o scenă vizuală cauzată de mișcarea relativă
dintre un observator și o scenă. Conceptul fluxului optic a fost introdus de
psihologul american James J. Gibson în anii 1940 pentru a descrie stimulul
vizual al animalelor. Gibson a subliniat importanta fluxului optic in vederea
posibilitatii de actiune in mediul inconjurator. Acesta a demonstrat rolul
stimulului fluxului optic pentru perceptia miscarii observatorului, perceptia
formei, distantei si controlul locomotiei.

NECLASIFICAT
din
NECLASIFICAT

Termenul de flux optic este de asemenea folosit în domeniul roboticii,


cuprinzând tehnici legate de prelucrarea imaginilor și controlul navigației,
inclusiv detectarea mișcării, segmentarea obiectelor, focalizarea calculelor de
expansiune, luminozitatea, codarea compensată la mișcare și măsurarea
disparităților stereo.
Metodele fluxului optic încearca să calculeze mișcarea dintre doua
cadre de imagine care sunt luate la momentele t si t  t . Aceste metode se
numesc diferențiale deoarece se bazează pe aproximările locale ale seriei Taylor
ale semnalului de imagine; adică folosesc derivatele parțiale în ceea ce privește
coordonatele spațiale și temporale.
Pentru un caz dimensional 2D+t, un pixel cu locatia ( x, y, t ) și
intensitatea I ( x, y, t ) va avea deviațiile x, y, t între doua cadre succesive și
următoarea constrângere de luminozitate poate fi aplicată:

I ( x, y, t )  I ( x  x, y  y, t  t ) (4.1)

Presupunând că deplasarea este mică, constrâgerea imaginii la I ( x, y , t )


prin dezvoltarea în serie Taylor se obține:

I I I
I ( x  x, y  y, t  t )  I ( x, y, t )  x  y  t (4.2)
x y t
Rezultă:

I I I
x  y  t  0 (4.3)
x y t
Sau:

I I I
Vx  Vy   0 (4.4)
x y t

Unde: Vx ,Vy sunt componentele pe x și y ale vitezei sau fluxul optic al I ( x, y , t ) și


I I I
, , sunt derivatele imaginii la ( x, y, t ) în direcțiile corespunzatoare.
x y t
Prin urmare:
I xVx  I yVy   It (4.5)
Sau:
ur
I T V   I t (4.6)

NECLASIFICAT
din
NECLASIFICAT

Aceasta este o ecuație în două necunoscute și nu poate fi rezolvată ca


atare. Este cunoscută sub denumirea de apertura problemă a algoritmilor de flux
optic. Pentru a găsi fluxul optic este nevoie de un alt set de ecuații, dar și de
unele constrângeri suplimentare. Toate metodele de flux optic introduc condiții
suplimentare pentru estimarea debitului efectiv.
Estimarea mișcării și compresia video s-au dezvoltat ca un aspect
major al cercetării fluxului optic. În timp ce câmpul de curgere optică este
superficial similar cu un câmp de mișcare densă derivat din tehnicile de
estimare a mișcării, fluxul optic este studiul nu numai al determinării câmpului
de flux optic în sine, ci și a utilizării sale în estimarea naturii tridimensionale și
structurii scenei, precum și mișcarea 3D a obiectelor și a observatorului față de
scenă, majoritatea folosind imaginea Jacobian.
Fluxul optic este utilizat de cercetătorii de robotică în multe domenii,
cum ar fi: detectarea și urmărirea obiectelor, extracția planului dominant al
imaginii, detectarea mișcărilor, navigația robotului,etc. Aplicarea fluxului optic
include nu numai problema deducerii mișcării observatorului și a obiectelor din
scenă, ci și a structurii obiectelor și a mediului. Deoarece conștientizarea
mișcării și generarea de hărți mentale ale structurii mediului inconjurator sunt
componente critice ale viziunii umane, transformarea acestei capacități
înnăscute într-o capacitate a calculatorului este la fel de importantă în domeniul
viziunii mecanice. Un senzor de debit optic este un senzor capabil să măsoare
debitul optic sau mișcarea vizuală și să furnizeze o măsurătoare bazată pe fluxul
optic. Senzorii de curgere optică sunt, utilizați în aplicații de robotică, în special
acolo unde este necesară măsurarea mișcării vizuale sau mișcării relative între
robot și alte obiecte din vecinătatea robotului. Utilizarea senzorilor de flux optic
în vehicule aeriene fără pilot (UAV), pentru stabilitatea și evitarea obstacolelor,
este, de asemenea, o zonă de cercetare actuală.

4.5 Metoda Lucas-Kanade

În domeniul CV (Computer Vision), metoda Lucas-Kanade este o


metodă diferențială pe scară largă pentru estimarea fluxului optic dezvoltata de
Bruce D. Lucas și Takeo Kanade. Se presupune că fluxul este, în esență,
constant într-o vecinătate locală a pixelului examinat și rezolvă ecuațiile de bază
optice ale fluxului pentru toți pixelii din vecinătatea respectivă, prin criteriul
celor mai mici pătrate. Prin combinarea informațiilor mai multor pixeli din
apropiere, metoda Lucas-Kanade poate deseori rezolva ambiguitatea inerentă a
ecuației de curgere optică. Este, de asemenea, mai puțin sensibila la zgomotul
imaginii decât metodele punctuale. Pe de altă parte, deoarece este o metodă pur
locală, ea nu poate furniza informații despre flux în interiorul regiunilor
uniforme ale imaginii.

NECLASIFICAT
din
NECLASIFICAT

Metoda Lucas-Kanade presupune ca deplasarea conținutului imaginii


între două situații apropiate (cadre) este mică și aproximativ constantă într-o
vecinătate a punctului p considerat. Astfel, se poate presupune că ecuația
fluxului optic se menține pentru toți pixelii dintr-o fereastră centrată la p.
Vectorul (viteza) fluxului local de imagine (Vx ,Vy ) trebuie să satisfacă:

I x (q1 )Vx  I y (q1 )Vy   I t (q1 )


I x (q2 )Vx  I y (q2 )Vy   I t (q2 )
.
(4.7)
.
.
I x (qn )Vx  I y (qn )Vy   I t (qn )
Unde q1 , q2 ,..., qn sunt pixelii din interiorul ferestrei de cautare, și
I x ( qi ), I y (qi ), It (qi ) sunt derivatele parțiale ale imaginii I raportate la coordonatele
x,y și timpul t.
Aceste ecuații pot fi scrise sub forma de matrici Av  b , unde:

 I x (q1 ) I y (q1 ) 
 I (q ) I y (q2 ) 
A
x 2
(4.8)
 M M 
 
 I x (qn ) I y (qn ) 

Vx 
v  (4.9)
Vy 

  I t (q1 ) 
  I (q ) 
b t 2  (4.10)
 M 
 
  I t (qn ) 

Acest sistem are mai multe ecuații decât necunoscute și, prin urmare,
este supra-determinat. Metoda Lucas-Kanade obține o soluție de compromis
prin principiul celor mai mici pătrate. Rezultă sistemul de 2  2 :

AT Av  AT b
(4.11)
v  ( AT A) 1 AT b

Unde AT este transpusa matricei A . În continuare se calculează:

NECLASIFICAT
din
NECLASIFICAT

1
Vx    i I x (qi )  I (q ) I (q )    i I x (qi ) I t (qi ) 
2

V   
x i y i
i
  (4.12)
 y    i I x (qi ) I y (qi )  I (q )    i I y (qi ) I t (qi )
2
i y i 

Matricea centrală din ecuație este o matrice inversă. Matricea AT A este


denumită tensorul structurii imaginii în punctul p.
Soluția minimă de pătrate de mai sus dă aceeași importanță tuturor n
pixelilor din fereastră. În practică, este mai bine să se puna mai mult accent pe
pixelii care sunt mai aproape de pixelul central p. Pentru aceasta, se folosește
versiunea ponderată a ecuației celor mai mici pătrate:

ATWAv  ATWb
(4.13)
v  ( ATWA)1 ATWb

Unde W este o matrice n  n diagonalizabilă:


1
Vx    i wi I x (qi )  w I (q ) I (q )    i wi I x (qi ) I t (qi ) 
2

V   
i x i y i
i
   (4.14)
 y    i wi I x (qi ) I y (qi )  w I (q )   i wi I y (qi ) I t (qi )
2
i i y i  

Unde wi este de obicei setat ca o functie Gauss-iană a distanței dintre qi si p .


Pentru ca ecuația AT Av  AT b să poată fi rezolvată, matricea AT A trebuie
să fie inversabilă sau valorile proprii ale AT A să satisfacă relația 1  2  0 .
Pentru a evita problemele cauzate de zgomot se recomandă ca 2 să nu fie prea
mic.
Deasemenea, daca 1 / 2 este prea mare asta înseamnă că punctul p este
la limită, și metoda va suferi probleme de apertură. În scopul unei funcționări
corecte, se recomandă ca 1 si 2 să fie suficient de mari și să aibă o
magnitudine similară. O presupunere principală pentru această metodă este ca
mișcarea sa fie mică (mai puțin de 1 pixel între două imagini, de exemplu).
Dacă mișcarea este mare și încalcă această ipoteză, se reduce mai întâi rezoluția
imaginilor și apoi se aplica metoda Lucas-Kanade.
Metoda Lucas-Kanade poate fi utilizată numai atunci când vectorul
fluxului de imagine Vx , Vy între două cadre este suficient de mic pentru ca
ecuația diferențială a fluxului optic să aibă soluție.

NECLASIFICAT
din
NECLASIFICAT

4.6 Algoritmul TLD (Urmarire Invatare Detectare)

TLD este un algoritm conceput pentru urmărirea pe termen lung a unui


obiect necunoscut într-un flux video. Schema bloc este prezentată în figura 4.2.

Figura 4.2 – Diagrama de stări a algoritmului TLD

Componentele algoritmului sunt caracterizate dupa cum urmează:


Modulul de urmărire estimează mișcarea țintei între cadre consecutive
,presupunând că mișcarea cadru-cadru este limitată iar ținta este vizibilă.
Urmărirea va esua și nu va recupera ținta doar în eventualitatea în care obiectul
iese din câmpul vizual al camerei. Detectorul tratează fiecare cadru
independent, efectuează scanarea completă a imaginii și localizează toate
înfățișările care au fost observate și învățate în trecut. Detectorul poate face
doua tipuri de erori, și anume: false pozitive și false negative. Modulul de
învățare observă performanțele estimărilor celorlalte doua module și generează
exemple de instruire pentru a evita erorile în viitor. Totodata, acesta învață
detectorul să discrimineze mai multe înfățișări ale țintei. Scopul componentei
este de a îmbunătăți performanța unui detector de obiecte prin procesarea online
a unui flux video. În fiecare cadru al fluxului, se dorește evaluarea detectorului
curent, identificarea erorile și actualizarea pentru a evita aceste erori în viitor.

NECLASIFICAT
din
NECLASIFICAT

Ideea cheie a învățării este că erorile detectorului pot fi identificate de


două tipuri de "experți". Expertul P identifică numai false-negative, iar expertul
N identifică numai false-pozitive. Ambii experți fac erori, totuși independența
lor permite compensarea reciprocă a erorilor.

Figura 4.3 – Diagrama procesului de învățare P-N

Fie x un exemplu dintr-un spațiu caracteristic X și y fiind o etichetă


dintr-un spațiu de etichete y={-1,1}. Un set de exemple X este numit
neetichetat, Y se numește set de etichete si L={(x,y)} se numește set etichetat.
Intrările la invățarea P-N sunt setul etichetat Ll și setul neetichetat X u , cu l = u
Rolul învățării P-N este de a învăța un clasificator f: X → Y din setul etichetat
Ll . Clasificatorul f este o funcție din famila F parametrizată de  . Familia F este
supusă implementării și este considerată ca fiind fixată în formare, formarea
corespunde, prin urmare, estimării parametrilor  . Invățarea P-N este alcătuită
din patru blocuri: (i) un clasificator care trebuie invățat, (ii) un set de instruire -
o colecție de exemple de instruire etichetată, (iii) formare supravegheată - o
metodă care pregătește un clasificator din setul de pregătire și (iv) experți PN -
funcții care generează exemple de formare pozitive și negative în timpul
învățării. Procesul de antrenare este inițializat prin introducerea setului L în
setul de antrenare. Setul de antrenament este apoi transferat la invățarea
supravegheată care antrenează un clasificator, adică evaluează parametrii inițiali
 0 . Procesul de invățare se continuă apoi în mod iterativ. La iterația k,

NECLASIFICAT
din
NECLASIFICAT

clasificatorul instruit în iterația anterioară clasifică întregul set nemarcat pentru


xu  X u :
yuk  f ( xu |  k 1 ) (4.15)

Clasificarea este apoi analizată de experții P-N care estimează


exemplele care au fost clasificate incorect. Aceste exemple sunt adăugate cu
etichetele modificate la setul de antrenament. Iterația se finalizează prin
recalificarea clasificatorului, adică estimarea lui  k . Procesul se repetă până la
convergență sau până la apariția altui criteriu de oprire. Elementul crucial al
învățării P-N este estimarea erorilor de clasificare. Soluția este de a separa
estimarea falselor pozitive de estimarea falselor negative. Din acest motiv, setul
neetichetat este împărțit în două părți pe baza clasificării curente și fiecare parte
este analizată de un expert independent. Expertul P analizează exemplele
clasificate ca negative, estimează falsele negative și le adaugă setului de
antrenament cu etichetă pozitivă. În iterația k, expertul P emite exemple

pozitive n (k ) . Expertul N analizează exemplele clasificate ca pozitive,
evaluează fals-pozitive si le adaugă cu eticheta negativă setului de antrenament.

In iterația k, expertul N emite exemple negative n (k ) . Expertul P mărește
generalitatea clasificatorului. Expertul N crește gradul de discriminare al
clasificatorului.

4.7 Algoritmul MIL (Invatarea Instantelor Multiple)

Acest algoritm este similar cu algoritmul descris mai sus. Diferența


majoră o reprezintă faptul că, în loc să considere doar locația curentă drept
exemplu pozitiv, algoritmul face o analiză a spațiului din imediata apropiere a
țintei și generează mai multe potențiale exemple pozitive. La prima vedere
poate părea o idee greșită pentru că în majoritatea acestor exemple “pozitive”
ținta nu este centrată. A fost gasită însă și soluția. În MIL, nu sunt specificate
exemple positive și negative. Sunt însă specificate grupuri de exemple. Într-un
grup pozitiv, nu sunt doar exemple pozitive. Un grup pozitiv conține atât
„patch-ul” centrat pe locația actuala a țintei cât și din imediata vecinatate a
țintei. Astfel, chiar dacă locația curentă a țintei urmărite nu este exactă, atunci
cand eșantioanele din vecinatatea țintei sunt puse în grupul cu exemple pozitive,
sunt mari șanse ca grupul să conțină cel puțin o imagine în care obiectul este
bine centrat.

Daca spațiul instanțelor este X , atunci setul de grupuri este setul de


funcții:

NECLASIFICAT
din
NECLASIFICAT

Ą X  B : X  Ą care este izomorf la mulțimea de multi-subseturi ale lui X .


Pentru fiecare grup B  Ą X și fiecare instanță x  X , B( x) este privită ca numărul
de ori în care x are loc în B . Fie y spațiul etichetelor, atunci un „concept de
mai multe instanțe” este o hartă c : Ą  y ,unde y  0,1 . Scopul algoritmului
X

MIL este de a invăța un astfel de concept.


Cele mai multe dintre lucrările de invățare ale instanțelor multiple, fac
atribuiri între instanța dintr-un grup și eticheta de clasă a grupului. Datorită
importanței sale, această ipoteza este adesea denumită atribuire standard a
instanțelor multiple.
Atribuirea standard face legatura între fiecare instanță x  X și o valoare
y  (0,1) . Perechea (x,y) se numește “concept la nivel de instanță”. Un grup
poate fi privit ca o multime de concepte la nivel de instanță și este etichetat
pozitiv dacă cel puțin una din instanțele sale este considerată pozitivă și
negativă daca toate instanțele acesteia au etichete negative. Considerăm
B   x1 , y1  ,...,( xn , yn  ca fiind un grup. Eticheta lui B este în cazul acesta
n
c( B)  1  C (1  yi ) . Ipoteza standard a instanțelor multiple este asimetrică, ceea
i 1

ce inseamnă că dacă etichetele sunt inversate, ipoteza are o semnificație diferită.


Din acest motiv, când folosim această ipoteză trebuie să fim foarte clari care
este eticheta pozitiva.
Presupunerea standard ar putea fi considerată prea strictă și, prin
urmare, în ultimii ani, cercetătorii au încercat să-și relaxeze abordarea, ceea ce a
condus la alte ipoteze mai vagi. Motivul acestor abordari, este convingerea că
presupunerea standard a instanțelor multiple este adecvată pentru setul de date
Musk, dar deoarece metoda invățării prin instanțe multiple poate fi aplicată în
numeroase alte situații, unele ipoteze diferite ar putea fi mai potrivite. Pornind
de la această idee, Weidmann a formulat o ierarhizare a ipotezelor generalizate
de instanța pentru invațărea prin instanțe multiple. Ierarhizarea are trei tipuri de
presupuneri ale instanțelor multiple generalizate standard  bazată pe prezența
 bazată pe prag  bazată pe calcul, cu ipoteza bazată pe calcul ca fiind cea
mai generală. Ipoteza bazată pe prezență este o generalizare a ipotezei standard,
în care un grup trebuie să conțină una sau mai multe instanțe care să aparțină
unui set de concepte la nivel de instanță pentru a putea fi etichetată ca fiind
pozitivă. Considerăm CR  x  y ca fiind setul de instanțe conceptuale cerut, iar
#( B, ci ) arată de câte ori apare conceptul la nivel de instanță ci in grupul B.
Astfel c( B)  1  #( B, ci )  1 pentru ci  CR . De menționat că dacă CR conține o
singură instanță la nivel de concept, ipoteza bazată pe prezență se reduce la
ipoteza standard. Ipoteza bazată pe prag consideră necesar ca fiecare instanță
conceptuala nu trebuie să apară o singura dată într-un grup , ci un numar minim

NECLASIFICAT
din
NECLASIFICAT

de ori pentru ca grupul să fie etichetat pozitiv. Păstrând notațiile de mai sus,
fiecarei instanțe conceptuale ci  CR îi este asociat un prag li Ą . Pentru un grup
B , c  B   1  #( B, ci )  li , ci  CR . Ipoteza bazată pe calcul este generalizarea
finală care impune atât limitele înferioare cât și pe cele superioare pentru
numărul de momente în care o instanță conceptuală poate apărea într-un grup
marcat ca fiind pozitiv. Fiecare instanță conceptuală ci  CR are un prag minim
li Ą si un prag maxim ui Ą cu li  ui . Un grup B este etichetat conform
c  B   1  li  #( B, ci )  ui , ci  CR .

4.8 Ipoteza GMIL

Scott, Zhang, și Brown descriu o altă generalizare a modelului standard,


numită de aceștia „învățare generalizată a instanțelor multiple”(GMIL). Această
ipoteză menționează un set de instanțe necesare Q  X . Un grup X este
etichetat pozitiv dacă acesta conține instanțe care sunt suficient de apropiate de
instanțele necesare Q. Doar îndeplinind această condiție , ipoteza GMIL este
echivalentă ipotezei bazată pe prezență. Aceștia descriu o generalizare ulterioară
în care există un set de puncte de atracție Q  X și un set de puncte de repulsie
Q  X . Un grup este considerat pozitiv dacă are în componență instanțe care
sunt suficient de apropiate de punctele de atracție și suficient de departe de
punctele de repulsie. Această condiție este strict mai generală decât cea bazată
pe prezență, deși nu se incadrează în ierarhia de mai sus.

Ipoteza colectiva:

Comparativ cu ipotezele anterioare, unde grupurile erau considerate


fixe, această ipoteză consideră grupul B drept o distributie p( x B) ale
instanțelor X ,și similar, etichetele drept distribuții p( y x) ale instanțelor. Scopul
unui algoritm care funcționează cu ipoteza colectivă este să modeleze
distribuția:

p( y | B)   p( y x) p( x B)dx (4.16)
x

Din moment ce p( x | B) este considerată fixă dar necunoscută,


algoritmii calculează versiunea empirică:
^ nB
1
p( y | B )  nB
 p( y | x )
i 1
i (4.17)

NECLASIFICAT
din
NECLASIFICAT

unde nB este numărul instanțelor din grupul B.


Performanțele acestui algoritm sunt considerate satisfăcătoare, reușind să fie util
chiar și în condiții de ocluzie parțială. Nu este recomandat a fi folosit cu
versiuni mai noi de OpenCV. În cazul unei ocluzii totale, ținta nu este
recuperată.

NECLASIFICAT
din
NECLASIFICAT

Capitolul 5
Comparație a tehnicilor de urmărire
Scopul urmăririi este de a crea traseul unei ținte în timp prin găsirea
poziției sale în secvențe video. Detectarea țintei și crearea unei corespondențe
între aparițiile obiectului prin cadre pot fi realizate separat sau în comun. În
prima etapă, regiunea de interes în fiecare cadru este realizată printr-un algoritm
de detectare a obiectelor, iar urmărirea face corespondențe între cadre. În etapa
finală, regiunea obiectului este proiectată prin actualizarea iterativă a locației
obiectului obținută din cadrele anterioare. Urmărirea obiectelor poate fi
clasificată ca urmărirea punctelor, urmărirea bazată pe nucleu și urmărirea
bazată pe siluetă.

5.1 Urmărirea punctelor

Urmărirea poate fi formulată ca o corespondență a obiectelor detectate


reprezentate de puncte de la un capăt la celălalt al cadrelor. Corespondența
punctului este o problemă complicată - în special în existența ocluziilor,
detectărilor greșite, intrărilor și ieșirilor de obiecte. În general, metodele de
corespondență a punctelor pot fi împărțite în două categorii largi, și anume,
deterministe și statistice. Metodele deterministe utilizează euristica mișcării
calitative pentru a constrânge problema corespondenței. Pe de altă parte,
metodele probabiliste iau explicit măsurarea obiectului și iau in considerare
incertitudinile pentru a stabili corespondența.

5.1.1 Metoda deterministă

În urmărirea punctului, această metodă funcționează la conectarea


fiecărui obiect din cadrul anterior cu un obiect unic în cadrul curent. Acest lucru
se face cu ajutorul setului de constrângeri de mișcare. Metodele deterministe
pentru corespondența punctului definesc evaluarea asocierii fiecărui obiect în
cadrul t - 1 cu un singur obiect din cadrul t folosind un set de constrângeri de
mișcare. Minimizarea evaluarii corespondenței este formulată ca o problemă de
optimizare combinatorică. Aceste abordări sunt făcute pentru aplicații diferite
pentru scopuri diferite. Primul algoritm de urmărire a fost propus de Veenman
în secvența farfuriei rotative, pentru a detecta puncte negre pe o farfurie albă.
Un alt algoritm de urmărire a fost propus de Shafique și Shah, care au
demonstrat că păsările pot fi detectate utilizând scăderea fundalului.

NECLASIFICAT
din
NECLASIFICAT

5.1.2 Metoda statistică

Metoda statistică sau probabilistică funcționează pe baza măsurării


poziției obiectului în cadrul cu mecanism de detectare. Această metodă
utilizeaza modelul proprietăților obiectului, cum ar fi viteza și poziția. Există
două categorii de urmărire: urmărirea unui obiect unic și a unui obiect multiplu.
Măsurătorile obținute de la senzorii video conțin în mod invariabil zgomot. Mai
mult, mișcările obiectului pot suferi perturbări aleatorii, de exemplu, vehicule
de manevră. Metodele de corespondență statistică rezolvă aceste probleme de
urmărire prin luarea în considerare a măsurătorilor și a incertitudinilor de model
în timpul estimării stării obiectului. Abordarea spațială a stărilor este utilizată de
metodele de corespondență statistică pentru a modela proprietățile obiectului,
cum ar fi poziția, viteza și accelerația. Măsurătorile constau, de obicei, în poziția
obiectului din imagine, obținută de un mecanism de detectare. Astfel, metoda
statistică extinde efortul metodei deterministe prin utilizarea diferitelor tipuri de
filtre. Aceste filtre sunt utilizate și în alte metode, cum ar fi metoda
deterministă, metodele de urmărire a kernelului și metoda conturului. Unele
filtre utilizate în mod obișnuit sunt filtrul de Kalman, filtrul de particule, filtrul
de asociere a datelor pentru probabilitatea comună și filtrele de ipoteze multiple.

5.2 Urmărirea nucleului

Urmărirea nucleului se bazează pe mișcarea obiectului. Aceasta se


realizează de obicei prin calcularea mișcării obiectului, reprezentat de o regiune
obiect primitivă, de la un cadru la altul. Acești algoritmi diferă în ceea ce
privește reprezentarea aspectului utilizat, numărul de obiecte urmărite și metoda
utilizată pentru estimarea mișcării obiectului.

5.2.1 Modele bazate pe șabloane

Baza de șabloane este metoda de căutare a imaginii, pentru care


șablonul țintei se definește în cadrul anterior. Datorită simplității relative și a
costului scăzut al calculului, au fost utilizate în mod obișnuit sabloane de aspect
bazate pe densitate. Această categorie este impărțită în două subcategorii, pe
baza faptului că obiectele sunt urmărite individual sau în comun. Există două
tipuri de metode bazate pe șabloane: urmărirea unui obiect unic și urmărirea
unui obiect multiplu.

NECLASIFICAT
din
NECLASIFICAT

5.2.2. Modele cu aspecte multiple

Modelele cu aspecte multiple este o abordare folosită pentru țintele care


pot avea vederi diferite în diferite cadre. În astfel de situații celelalte metode
întampină dificultăți. Modelele de aspect în metodele de urmărire prezentate
anterior sunt de obicei generate online (de exemplu, histograme, șabloane etc.).
Astfel, aceste modele reprezintă informațiile colectate prin cele mai recente
observații ale obiectului. Țintele pot avea infățișări diferite și dacă afișarea
obiectului se modifică dramatic în timpul urmăririi, modelul de aspect nu mai
este valabil iar ținta poate fi pierdută. Vederi diferite ale tintei pot fi „învățate”
offline și folosite pentru urmărire pentru a depăși această dificultate.

5.3 Urmărirea siluetei

Urmărirea siluetei este utilizată atunci când este necesară o regiune


completă a unei ținte. Obiectele complexe, cum ar fi mâinile, capul, corpul
uman, pot fi descrise cu exactitate prin metoda bazată pe siluetă. Obiectivul
acestor metode de urmărire este de a găsi regiunea obiectului în fiecare cadru cu
ajutorul unui model de obiect generat utilizând cadrele anterioare. Acest model
poate fi sub forma unei margini a obiectului sau a conturului obiectului și a
histogramei de culoare. Există în principal două categorii de urmărire a siluetei,
și anume potrivirea formei și urmărirea conturului.

5.3.1 Potrivirea formei

În această abordare, căutarea se realizează prin calcularea asemănării


obiectului cu modelul generat de silueta obiectului presupus pe baza cadrului
anterior.
1) Urmărirea conturului
Comparativ cu metoda de potrivire a formei, metoda de urmărire a
conturului dezvoltă în mod iterativ un contur inițial în cadrul precedent până la
noua locație din cadrul prezent. Această dezvoltare a conturului necesită ca o
parte a obiectului din cadrul actual să se suprapună cu aria obiectului din cadrul
anterior. Urmărirea prin dezvoltarea unui contur poate fi efectuată utilizând
două abordări diferite. Prima abordare utilizează modele din spațiul stărilor
pentru a modela forma conturului și mișcarea acestuia. A doua abordare
dezvoltă în mod direct conturul prin minimizarea energiei conturului folosind
tehnici de minimizare directă, cum ar fi coborârea gradientului. Algoritmul de

NECLASIFICAT
din
NECLASIFICAT

urmărire bazat pe contur implică o clasificare suplimentară, și anume modelul


din spațiul stărilor și minimizarea directă a funcției de energie a conturului.
Analiza video este în principal bazată pe detectarea țintei, urmărirea și
recunoașterea obiectelor. Analiza comparativă se face pe baza algoritmilor de
urmărire a obiectului de bază: algoritmi de urmărire în puncte, nucleu și siluetă.
Urmărirea punctului implică detectarea în fiecare cadru, în timp ce urmărirea
bazată pe nucleu sau urmărirea conturului necesită detectare atunci când
obiectul apare pentru prima dată în cadru.
O comparație a tehnicilor de urmărire este prezentată în tabelul de mai
jos:

Tipul urmaririi Metoda Avantaje Limitari


Nu este afectat de Se presupune că nu
Algoritmul de ocluzie și detectări sunt obiecte care apar
urmărire GOA defectuoase sau dispar din cadru
Urmărește ținte
Filtru Kalman chiar și în condiții Starea este distribuită
de zgomot gaussian
Nu este influențat
Urmărirea de apariția sau Timp de calcul și
ipotezelor multiple dispariția unor memorie necesară
Urmarirea punctelor obiecte din cadru ridicate.
Rezolvă
Filtru de particule problemele pe care Este estimată doar
le are filtrul starea unei ținte.
Kalman
Informațiile spațiale ale
țintei sunt pierdute, nu
pot da rezultate bune
Stabil in condțtii atunci când un obiect și
Histograma de de ocluzie sau fundalul său au o
Urmărirea nucleului culoare distrageri culoare similară

Urmărirea Forma obiectului


conturului este modelată Sensibil la mișcări
implicit bruste ale țintei
Urmărirea siluetei
Potrivirea formei Insensibil la Este necesară o
variațiile de aspect procesare anterioară

NECLASIFICAT
din
NECLASIFICAT

Metodele de urmărire a punctului sunt potrivite pentru urmărirea


obiectelor foarte mici care pot fi reprezentate printr-o reprezentare cu un singur
punct. În abordarea de urmărire a nucleului, diferite metode de estimare sunt
folosite pentru a găsi regiunea rezultantă a obiectului-țintă.
Tehnologia histogramei de culoare are o eficiență bună în ceea ce
privește detectarea cadrelor, dar informațiile spațiale sunt pierdute, iar dacă sunt
incluse caracteristici precum textură, etc, atunci urmărirea nucleului va da
rezultate mai bune. Urmărirea siluetelor formează bazele tipurilor de
reprezentare care pot fi modele de mișcare sau modele de aspect.

NECLASIFICAT
din
NECLASIFICAT

Capitolul 6
Algoritmul de urmărire realizat

Principiul Camshift presupune parcurgerea următoarelor etape. În


primul rând, transformăm imaginea în distribuții de probabilități de culoare în
funcție de histograma de culoare a obiectului. În al doilea rând, inițializăm
mărimea și poziția ferestrei de căutare. În al treilea rând, fereastra este ajustată
cu rezultatul obținut din cadrul anterior. În final, este determinat centrul
obiectului în imaginea curentă.

6.1 Distribuția probabilităților de culoare

In prima instanță este calculata histograma de culoare a obiectului.


Spațiul de culoare RGB (red, green, blue) are o slăbiciune în ceea ce privește
reprezentarea efectelor de umbrire sau schimbarea rapidă a iluminării. Pentru a
rezolva această problemă, algoritmul Camshift adoptă spațiul de culoare HSV
(Hue Saturation Value) pentru a descrie obiectul. Numai canalul H din modelul
HSV poate exprima informațiile despre culoare, așa că il extragem pentru a
face histograma. Pentru fiecare cadru, histograma crominanței se calculează
după cum urmează: Să presupunem că numărul de pixeli totali din cadru este n,
gradul de crominanță al histogramei este m, iar indicele de crominanță
corespunzător pixelului xi este c  xi i 1,...,n , atunci elementul histogramei
qu u 1,...,m acestui cadru este:

n
qu    c  xi   u , u  1, 2,..., m (6.1)
i 1

Unde  este funcția impulsului unității. Formula de normalizare a


histogramei este dupa cum urmează:

  255  
 pu  min  qu , 255   (6.2)
  max  q   u 1,...,m

NECLASIFICAT
din
NECLASIFICAT

Putem normaliza intervalul de valori al histogramei corespunzătoare fiecărui


grad de crominanță la intervalul [0, 255] astfel încât proiecția valorii fiecărui
pixel din imagine să fie legată de valoarea corespunzătoare fiecărui grad de
crominanță din histograma. Se obține astfel graficul de distribuție al
probabilității obiect-culoare.

6.2 Algoritmul Mean Shift

Algoritmul Mean Shift este o metodă de estimare non-parametrică


bazată pe gradientul funcției de densitate, propusă de Fukunaga și aplicată
pentru recunoașterea modelelor.
Pentru a localiza obiectul, utilizează căutarea iterativă pentru a găsi
valoarea extremă a distribuției de probabilitate. Procesul de urmărire a
algoritmului MS este următorul:
1. Se selectează o fereastră de căutare în distribuția probabilităților. Poziția
pixelilor din fereastra de căutare este punctul (x,y) si I(x,y) este valoarea
punctului (x,y).

2. Calcularea momentelor zero M 00 , primul moment M 01 al X, și primul


moment M10 al Y cu urmatoarea formulă:

M 00   I ( x, y) , (6.3)
x y

M 01   yI ( x, y) , (6.4)
x y

M10   xI ( x, y) (6.5)
x y

3. Calcularea centrului de masă  xc , yc  pentru fereastra de căutare:


 xc , yc    M10 / M 00 , M 01 / M 00  (6.6)

4. Resetarea dimensiunilor ferestrei de căutare:


s  2 M 00 / 256 (6.7)

Din (4) se obține dimensiunea ferestrei de căutare. Centrul ferestrei va fi


mutat în centrul de masă. Dacă distanța în mișcare este mai mare decât pragul
presetat, va fi recalculat centrul de masă al ferestrei de căutare. Poziția și
dimensiunea ferestrei de cautare vor fi reglate până când distanța obținută în
urma deplasării va fi mai mică decât pragul presetat.

NECLASIFICAT
din
NECLASIFICAT

6.3 Algoritmul Camshift

Extinderea algoritmului Mean Shift la o secvență video continuă, duce la


obținerea algoritmului Camshift. Acest algoritm constă în aplicarea algoritmului
Mean Shift tuturor cadrelor dintr-o secvență video ți să se considere centrul și
dimensiunea ferestrei obținute din cadrul anterior ca valoare inițială pentru
fereastra de căutare din cadrul urmator. Prin iterarea acestui proces se poate
reuși urmărirea țintei. Etapele sunt după cum urmează:
a) Inițializarea ferestrei de căutare
b) Calcularea distribuției probabilităților de culoare a ferestrei de căutare.
c) Rularea algoritmului Mean Shift pentru a obține dimensiunile și poziția
următoarei ferestre de căutare.
d) În următorul cadru al videoclipului este reinițializată dimensiunea și
poziția ferestrei de căutare cu valoarea de la (c).
e) Calcularea axelor și orientării obiectului.
Prin calcularea momentelor de ordinul 2 folosind formulele:
M 20   x 2 I ( x, y) (6.8)
x y

M 02   y 2 I ( x, y) (6.9)
x y

M11   xyI ( x, y ) (6.10)


x y

Putem obține lungimea celor două axe ale ferestrei de căutare a țintei:

( A  C )  B 2  ( A  C )2
L (6.11)
2
( A  C )  B 2  ( A  C )2
S (6.12)
2
Unde:
A  M 20 / M 00  xc (6.13)
B  M 20 / M 00  xc yc (6.14)
C  M 02 / M 00  yc2 (6.15)
Totodata putem obține unghiul de directie  al țintei:

1  2( M11 / M 00  xc yc 
  arctan  2 
(6.16)
 ( M 20 / M 00  xc )  ( M 02 / M 00  yc 
2
2

NECLASIFICAT
din
NECLASIFICAT

Figura 6.1 – Structura algoritmului realizat

Folosirea metodei Camshift are drept avantaj faptul că este necesar


doar calculul distribuției probabilităților de culoare a pixelilor din
fereastra de căutare. Deoarece nu este nevoie să se calculeze distribuția
probabilităților tuturor pixelilor din fiecare cadru, acest fapt reduce
calculul și scurtează timpul de procesare.

6.4 Măsurarea funcției de similaritate

Coeficientul Bhattacharyya este ales pentru a măsura similitudinea


modelului țintei q  qu u 1,...,m și a modelului candidat p( y)  {Pu ( y)}u 1,...,m și este
definit astfel:
m
 ( y)  [ P( y), q]   pu ( y0 )qu (6.17)
u 1

NECLASIFICAT
din
NECLASIFICAT

Criteriul ocluziei

Similitudinea modelului obiect și a modelului candidat poate fi descrisă


de coeficientul Bhattacharyya a cărui valoare va scădea rapid atunci când
obiectul este acoperit. Deci, putem să analizam dacă ocluzia are loc în funcție de
gradul în schimbare al coeficientului Bhattacharyya.
Avand un prag Th ,criteriul ocluziei este:

1, normala
f  yk   
0, ocluzionata
Metoda aleasă are avantajul unei urmăriri în timp real mai bună decât
ceilați algoritmi dar va întampina dificultăți atunci când ținta va fi puternic
ocluzionată. O soluție pentru optimizarea algoritmului ar fi introducerea unui
filtru Kalman pentru rezolvarea problemei ocluziei. Cu toate acestea, filtrarea
Kalman presupune un model spațial de stare Gauss, care poate să nu fie în
concordanță cu mișcarea țintei în lumea reala.

NECLASIFICAT
din
NECLASIFICAT

Capitolul 7
Rezultate obținute
Sistemul de urmărire realizat a fost testat atât în condiții de laborator cât
și în condiții reale pe aerodromul Clinceni. În urma numeroaselor teste la care a
fost supus, a obținut rezultate bune. Sistemul a fost ambarcat pe o platformă
aeriană autonomă și anume un quadcopter.

Figura 7.1 – Quadcopterul integrat pentru ambarcarea sistemului de urmărire


realizat
Platforma aeriană a fost controlată de la sol cu o telecomandă FrSky
Taranis X9D FPV. Este un dispozitiv cu rază de acțiune de până la 10
kilometri. Are un ecran LCD și poate face inregistrarea în timp real a datelor.

NECLASIFICAT
din
NECLASIFICAT

Figura 7.2 – Telecomanda utilizată în controlul platformei aeriene

NECLASIFICAT
din
NECLASIFICAT

Semnalul video este transmis stației de control de la sol pe canalul de


frecvență de 5.8 Ghz.

Figura 7.3 – Sistemul surprins în modul de funcționare

Figura 7.4 – Stația de control de la sol

NECLASIFICAT
din
NECLASIFICAT

Operatorul de la sol comandă oprirea transmisiei video de la monitorul


stației de control și incadrează ținta statică sau dinamică ce prezintă interes.

Figura 7.5 – Cadrul selectat în momentul opririi transimiei video

Selectia țintei de interes poate fi realizată prin intermediul unor puncte


sau a unei forme geometrice, pătrat, elipsă,etc.

Figura 7.6 – Selecția țintei

In cazul de fata, ținta este reprezentată de o mașină neagră care se află


în deplasare. Deși în imediata apropiere a acesteia se află și alte autovehicule

NECLASIFICAT
din
NECLASIFICAT

care ar putea introduce dificultăți în urmărire, sistemul a avut rezultate


satisfăcătoare.
După ce a fost realizată selecția, ținta este încadrată într-un pătrat roșu
iar transmisia video este reluată. Modulul Nvidia Jetson TX2 începe procesarea
video, iar deviațiile față de centrul imaginii sunt transmise platformei
girostabilizate care susține camera, în vederea compensării acestora.
Dacă operatorul de la sol decide schimbarea țintei, poate comanda
încetarea procesului aflat în desfășurare și reia etapele prezentate mai sus.
Sistemul realizat a fost validat cu succes în secvențe de zgomot, ocluziuni
complete, transformări și modificări ale mediului. Sistemul continuă să fie
eficient atât timp cât ținta rămâne în câmpul vizual.

Figura 7.7 – Urmărirea țintei de interes

Deoarece algoritmul de urmărire realizat folosește doar nuanța din


spațiul de culoare HSV (Hue Saturation Value) și ignoră pixelii cu luminozitate
ridicată sau scazută, sistemul oferă o toleranță ridicată la iluminare. Atât timp

NECLASIFICAT
din
NECLASIFICAT

cât ocluzia țintei nu este 100%, va fi urmărit ce a rămas din distribuția


probabilităților țintei. Fereastra de căutare iși va modifica dimensiunile în
funcție de dimensiunile țintei, gestionând automat neregularitățile induse de
mișcarea țintei.
Sistemul ignoră obiectele aflate în imediata apropiere a ferestrei de
căutare, astfel că mașinile de pe marginea drumului nu afectează urmărirea.

Figura 7.8 – Prezentarea sistemului în cadrul BSDA(1)

Sistemul de urmărire a fost prezentat și apreciat la expoziția


internațională BSDA (Black Sea Defense and Aerospace) 2018, la Conferința
Internațională AFASES 2018 Brașov și la Conferința Studențească
Internațională CERC 2018.

Figura 7.9 - Prezentarea sistemului în cadrul BSDA(2)

NECLASIFICAT
din
NECLASIFICAT

Capitolul 8
Preocupări viitoare

Eforturile viitoare se vor canaliza pe imbunatațirea performanțelor


sistemului prin implementarea mai multor filtre printre care si unul Kalman.
Totodată, prezintă interes dezvoltarea unor structuri de tip clasificator, iar aceste
structuri vor fi antrenate online.
Dezvoltarea accelerată a inteligenței artificiale oferă oportunități de
implementare a algoritmilor de învățare profundă și a rețelelor neuronale.
Inteligența artificială este foarte folosită în robotică. Brațele robotice avansate și
alte roboți industriali, pot învăța din experiențele cum să se deplaseze eficient,
în ciuda prezenței fricțiunii și alunecării angrenajelor. Un robot mobil modern,
atunci când este amplasat intr-un mediu, static și vizibil, își poate determina cu
ușurință locația și își poate mapa mediul.

8.1 Aplicații bazate pe inteligență artificială

Aplicațiile de inteligenta artificiala, care includ agenți inteligenți, oferă


noi domenii de cercetare. In ultimii ani, de o atenție deosebită s-a bucurat
aplicarea acestor metode de inteligența artificială conceptelor de zbor pentru
UAV. UAV-ul poate fi descris ca orice platformă operată fără prezența umană
la bord. Sistemele existente astăzi includ elicoptere, avioane, baloane, și chiar
sateliți. Autonomia lor variază de la interacțiunea umană de la o consolă la
distanță până la decolarea și aterizarea complet autonomă. Cercetările
anterioare, efectuate de Handelman și Stengel, au aplicat metode de inteligența
artificială, cum ar fi sistemele expert și planificatorii, care au introdus sisteme
bazate pe reguli. Aceste sisteme au încercat să modeleze zborul unei aeronave
în sarcini logice care trec printr-o serie de evenimente pentru a menține
controlul asupra funcțiilor specifice ale aeronavei. Una dintre probleme este
reprezentată de faptul că procesul de luare a deciziilor de către un expert al
expertului este dificil de imitat de către calculatoare. Mediul dinamic și
condițiile care afectează aeronavele sunt condiții care trebuie adaptate unui
astfel de sistem de experți.
Un domeniu important al inteligenței artificiale, cunoscut sub numele
de învățare automată, este folosit pentru scenariul de orientare UAV. “Learning
machine” se ocupă de algoritmi de auto-învățare care lucrează pe date din
experimentele anterioare și vin cu o acțiune adecvată pentru situația actuală. De
obicei, se dezvoltă un model de simulare pentru problema dată în care agentul
inteligent poate fi instruit pe baza datelor din simulare. Modelul de simulare

NECLASIFICAT
din
NECLASIFICAT

trebuie să fie cât mai aproape posibil de scenariul lumii reale. Simulările
complexe sunt totuși costisitoare atât în timpul de dezvoltare, cât și în timpii de
execuție. Prin urmare, un model al lumii reale abstractizarea informațiilor non-
vitale, asigurându-se în același timp că aspectele majore sunt captate.
Performanța algoritmului de inteligenta artificiala depinde de calitatea
modelului de simulare.

8.2 Rețele neuronale

Rețeaua neuronală artificială, inspirată din functionarea creierului


uman, este o adaptare biologică a minții și a inteligenței. Similar cu neuronii din
creier, aceasta reprezinta o rețea paralelă de calcul extrem de neliniar și foarte
complex, capabilă să se antreneze și să se adapteze diferitelor intrări și ieșiri;
oferind un avantaj extraordinar în ceea ce privește predicția comportamentului
neliniar. Într-o rețea neurală, ieșirea este determinată în mare măsură de
conexiunile dintre elementele sale. Aplicațiile tipice ale retelelor neuronale
includ modelarea datelor neliniare, inteligența artificială, generarea de suprafețe,
identificarea modelului, gruparea de date, recunoașterea vocii, sistemele de
procesare a imaginilor și de control etc.
O rețea neuronală are o arhitectură stratificată, care este compusa, în
mod normal, din trei straturi; stratul de intrare, stratul (straturile) ascuns și
stratul de ieșire. Structura unei rețele neuronale tipice este prezentată în figura
8.1.

Figura 8.1 – Structura unei rețele neuronale

NECLASIFICAT
din
NECLASIFICAT

Într-o rețea neuronală, stratul de intrare X i primește intrări de la alti


neuroni sau din mediul înconjurător. În stratul ascuns, care poate fi mai mult de
unul, această intrare este înmulțită cu ponderea W ji și este adunata cu  j pentru
ajustarea erorii reziduale. O funcție de activare sau de transfer f calculează
ieșirea Yj , utilizând o anumită logică predefinită. Ieșirea funcției de transfer se
adresează altor neuroni sau mediului prin stratul de ieșire. Functionarea unui
neuron tipic într-o rețea este prezentată în figura 8.2. Matematic poate fi scrisă
ca:

I j  W ji X i   j
(8.1)
Y j  f ( I j )  f (W ji X i   j )

Figura 8.2 – Funcționarea unui neuron tipic

8.2.1 Functia de transfer

O funcție de transfer, numită și funcție de activare, convertește intrarea


evaluata la ieșire cu o anumită formulă predefinită. Diferite tipuri de funcții de
transfer sunt disponibile pentru a fi utilizate în retelele neuronale artificiale.
Câteva funcții de transfer utilizate în mod obișnuit sunt prezentate în Tabelul .
Figura 8.3 prezintă câteva din aceste funcții de transfer.

Numele functiei de Valoare Intervalul de iesire


transfer
Log-sigmoidală f ( x)  1/ (1  e x ) [0,1]

Log-tangențială f ( x)  (e x  e x ) / (e x  e x ) [−1,1]

Hard-limit 0, x  0 [0 or 1]
f ( x)  
1, x  1

NECLASIFICAT
din
NECLASIFICAT

Figura 8.3 – Reprezentări ale funcțiilor de transfer

8.2.2 Formarea modelului rețelei neuronale

Formarea unei rețele neuronale implică ajustarea ponderilor în cadrul


diferitelor straturi de rețea pentru a obține o intrare precisă la potrivirea
rezultatelor. Aceasta se face prin compararea rezultatului calculat cu ieșirea
dorita. O regulă de învățare este utilizată pentru a îmbunătăți și a supraveghea
procesul de reducere a erorilor, până când rezultatul rețelei se potrivește cu
iesirea dorita, cunoscuta sub numele de metodă de învățare supravegheată. Cu
toate acestea, formarea unei rețele necesită un set suficient de mare de perechi
de intrări-ieșiri. Există, de asemenea, metode de formare bazate pe învățarea
nesupravegheată .

8.2.3 Rețeaua de propagare back-forward

În aceast tip de rețea, rezultatul este calculat printr-un mecanism de


avans, în timp ce ponderile se calculează prin propagarea înapoi a erorii. În
calea feed-forward, ieșirea fiecărui strat (sau stratul ascuns) este alimentată
direct în intrarea următorului strat. Nu există conexiuni în interiorul unui strat și
nici conexiuni înapoi. În propagarea înapoi, învățarea se face în două etape.
Formarea rețelei neuronale începe cu un set de ponderi specificat aleator sau de
utilizator. Mai întâi, setul de intrare X se propagă înainte prin rețea, iar ieșirea
Yd este calculată. La fiecare pas, rezultatul calculat este comparat cu rezultatul
dorit și se calculează eroarea  . În etapa următoare, erorile calculate sunt
propagate înapoi pentru a calcula ponderile corectate pentru rețea. Valorile
optime ale ponderilor, care generează o eroare minimă, se calculează prin

NECLASIFICAT
din
NECLASIFICAT

algoritmul modificat cu cea mai abruptă coborâre. Acest proces se repetă până
când eroarea globală este minimă.

Figura 8.4 – Algoritmul de antrenament al propagării înapoi

Algoritmul de propagare înapoi decide cum să repartizeze eroarea între


toate ponderile și ajustează greutățile în consecință. Figura 5 prezintă algoritmul
de antrenament al propagării înapoi.

NECLASIFICAT
din
NECLASIFICAT

Capitolul 9
Concluzii

În decursul ultimului deceniu, detectarea și urmărirea tintelor în


mișcare sau statice a continuat să fie o zonă în plină expansiune a cercetării.
Cerințele potențialelor aplicații ale pieței în domeniul supravegherii,
interacțiunii cu computer-om și procesarea video fac ca acest domeniu să fie
favorizat printre cercetători. Activitatea sporită în acest domeniu a fost condusă
atât de mediul academic, cât și de industrie.
Dacă la început această zona de cercetare iși găsea aplicabilitate doar în
armată cum ar fi detectarea și estimarea pozițiilor, vitezelor și direcțiilor
aeronavelor inamice, între timp metodele de urmărire s-au răspândit în bio-
medicina, finanțe, siguranța automobilelor și controlul traficului aerian.
Fundamentul urmăririi este de a estima recursiv o cantitate necunoscută în timp,
fie că este vorba de o temperature într-o cameră, valoarea unei acțiuni pe piața
bursieră, pozițiile aeronavelor care circulă în jurul unui aeroport sau mișcarea
unei celule într-un vas de sânge. În cazul nostru, aspectele de interes sunt
pozițiile și vitezele țintelor.
Pe lângă prezentarea modului de realizare a sistemului ambarcat pentru
urmărirea automata a unei ținte la sol, lucrarea a dorit să prezinte și metodele de
urmărire a țintelor și o trecere în revistă a domeniilor conexe. Metodele de
urmărire au fost împărțite în trei categorii bazate pe utilizarea reprezentărilor
obiectului, și anume metodele care stabilesc corespondența punctului, metodele
care utilizează modelele geometrice primitive și metodele care utilizează
evoluția conturului.
Toate aceste metode necesită detectarea țintei la un moment dat. Totodată
a fost descris contextul de utilizare, gradul de aplicabilitate, criteriile de
evaluare și comparațiile calitative ale algoritmilor de urmărire.
Algoritmul realizat este simplu și eficient din punct de vedere al puterii
de calcul. Este robust împotriva ocluziilor tranzitorii, deoarece fereastra de
căutare va tinde să absoarbă mai întâi ocluzia și apoi să rămână în modul de
distribuție dominant când ocluzia trece.

NECLASIFICAT
din
NECLASIFICAT

Bibliografie

[1]Agarwa, V. K., Sivakumaran, N., & S., V. P. Six Object Tracking Algorithms: A
Comparative Study . Tiruchirappalli: Department of Instrumentation and Control
Engineering.
[2]Baker, S., & Matthews, I. (2004). Lucas-kanade 20 years on: A unifying framework. IJCV,
Vol.56(No.3):221–255.
[3]Bharati, S. P., Wu, Y., Sui, Y., Padgett, C., & Wang, G. Real-time Obstacle Detection and
Tracking for Sense-and-Avoid Mechanism in UAVs . IEEE.
[4]Bradski, G. R. . Computer Vision Face Tracking For Use in a Perceptual User Interface.
Santa Clara, CA: Intel Corporation.
[5]Comaniciu, D., & Meer, P.. “Robust Analysis of Feature Spaces: Color Image
Segmentation”. CVPR’97, pp. 750-755.
[6]Danelljan, M., Khan, F., Felsberg, M., & Weijer, J. v.. Adaptive color attributes for real-
time visual tracking. 2014.
[7]Dufrene, W. R., & Nova, J. [1]AI Techniques in Uninhabited Aerial Vehicle Flight.
Southeastern University.
[8]Eck, L., & Marchand, E. Chasing a moving target from a flying UAV C´eline Teuli`ere.
[9]Fukunaga, K. (1990). “Introduction to Statistical Pattern Recognition” . Boston:
Academic Press.
[10]G´omez, J. J., Giner, J. d., & Cruz, A. B. Multi-uav coordination and control interface.
2016.
[11]Godbehere, A. B., Matsukawa, A., & Goldberg, K. Visual Tracking of Human Visitors
under Variable-Lighting Conditions for a Responsive Audio Art Installation.
[12]https://en.wikipedia.org/wiki/Artificial_intelligence.
[13]https://en.wikipedia.org/wiki/Optical_flow.
[14]https://en.wikipedia.org/wiki/Track_algorithm.
[15]https://www.learnopencv.com/object-tracking-using-opencv-cpp-python/.
[16]https://www.python.org/.
[17]Isard, M., & Blake, A. “Contour tracking by stochastic propagation of conditional
density”. Proc. 4th European Conf. On Computer Vision, Cambridge, UK.
[18]J, Z., W, Q., & G, M. (2009 Jul 4). An approach based on mean shift and Kalman Filter
for target tracking under occlusion. Baoding: Proceedings of the Eighth International
Conference on Machine Learning and Cybernetics.
[19]Jackson, S. P. Controlling Small Fixed Wing UAVs to Optimize Image Quality from On-
Board Cameras .
[20]Jalal, A. S. "The State-of-the-Art in Visual Object Tracking". Department of Computer
Engineering & Applications.
[21]Javed, O. Object Tracking: A Survey Alper Yilmaz Ohio State University. ObjectVideo,
Inc.
[22]Jie, L., Jian, C., & Lei, a. W. Design of Multi-Mode UAV Human-Computer Interaction
System.
[23]L, T.-J., & Z., Z.-T. ( IJACT. 2013 Mar). Adaptive double Kalman Filter and mean shift
for robust fast object tracking.
[24]M. Andriluka, S. R. (2008). “People-tracking-by-detection and people-detection-by-
tracking”. CVPR 2008. IEEE Conference on. IEEE, 2008, pp. 1–8.
[25]McLain, R. W. Small Unmanned Aircraft Theory and Practice.
[26]Patel, M. J., & Bhatt, B. A Comparative Study of Object Tracking Techniques .

NECLASIFICAT
din
NECLASIFICAT

[27]Patel, S. K. Moving Object Tracking Techniques: A Critical Review. Department of


Electronics and Communication Engineering, Jabalpur Engineering College, Jabalpur.
[28]Swain, M., & Ballard, D. (1991). “Color indexing”. 7(1) pp. 11-32: Intl. J. of Computer
Vision.
[29]TANG, M., & FENG, J. (fără an). Multi-kernel Correlation Filter for Visual Tracking .
Beijing: National Lab of Pattern Recognition, Institute of Automation.
[30]Wang, Z. Object Tracking Algorithm Based on Camshift and Grey Prediction Model in
Occlusions. College of Computer Science and Information Guizhou University
Guizhou, China.
[31]Yang, F., Lu, H., & Yang, M. Robust visual tracking via multiple kernel boosting with
afnity constraints. IEEE TCSVT, 24:242–254, 2014.

NECLASIFICAT
din
NECLASIFICAT

Anexa 1

1. Urmărire forme geometrice


# USAGE
# python ball_tracking.py --video ball_tracking_example.mp4
# python ball_tracking.py
# import the necessary packages
from collections import deque
import numpy as np
import argparse
import imutils
import cv2
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=64,
help="max buffer size")
args = vars(ap.parse_args())
# define the lower and upper boundaries of the "green"
# ball in the HSV color space, then initialize the
# list of tracked points
greenLower = (29, 86, 6)
greenUpper = (64, 255, 255)
pts = deque(maxlen=args["buffer"])
# if a video path was not supplied, grab the reference
# to the webcam
if not args.get("video", False):
camera = cv2.VideoCapture(0)
# otherwise, grab a reference to the video file
else:
camera = cv2.VideoCapture(args["video"])
# keep looping
while True:
# grab the current frame
(grabbed, frame) = camera.read()
# if we are viewing a video and we did not grab a frame,
# then we have reached the end of the video
if args.get("video") and not grabbed:
break

NECLASIFICAT
din
NECLASIFICAT

# resize the frame, blur it, and convert it to the HSV


# color space
frame = imutils.resize(frame, width=600)
# blurred = cv2.GaussianBlur(frame, (11, 11), 0)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# construct a mask for the color "green", then perform
# a series of dilations and erosions to remove any small
# blobs left in the mask
mask = cv2.inRange(hsv, greenLower, greenUpper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
# find contours in the mask and initialize the current
# (x, y) center of the ball
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)[-2]
center = None
# only proceed if at least one contour was found
if len(cnts) > 0:
# find the largest contour in the mask, then use
# it to compute the minimum enclosing circle and
# centroid
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
# only proceed if the radius meets a minimum size
if radius > 10:
# draw the circle and centroid on the frame,
# then update the list of tracked points
cv2.circle(frame, (int(x), int(y)), int(radius),
(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
# update the points queue
pts.appendleft(center)
# loop over the set of tracked points
for i in xrange(1, len(pts)):
# if either of the tracked points are None, ignore
# them
if pts[i - 1] is None or pts[i] is None:
continue
# otherwise, compute the thickness of the line and
# draw the connecting lines

NECLASIFICAT
din
NECLASIFICAT

thickness = int(np.sqrt(args["buffer"] / float(i + 1)) * 2.5)


#cv2.line(frame, pts[i - 1], pts[i], (0, 0, 255), thickness)
# show the frame to our screen
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# if the 'q' key is pressed, stop the loop
if key == ord("q"):
break
# cleanup the camera and close any open windows
camera.release()
cv2.destroyAllWindows()

2. Generare imagini
from __future__ import print_function
import numpy as np
import os
import argparse
LABEL_ACTION_MAP = {
0 : "Background",
1 : "Walking",
2 : "Sitting",
3 : "Standing",
4 : "Running",
5 : "Lying",
6 : "Carrying",
7 : "Pushing/Pulling",
8 : "Reading",
9 : "Drinking",
10 : "Calling",
11 : "Hand Shaking",
12 : "Hugging"
}
def generate(sequence_path, model_type, frame_interval,
confidence_threshold):
from PIL import Image, ImageDraw, ImageFont
path_until_sequence, sequence_name = os.path.split(sequence_path)
tracking_file_path =
"../data/results/{}/{}/{}.txt".format(path_until_sequence, model_type,
sequence_name)
image_dir_path = "../data/{}/images".format(sequence_path)

NECLASIFICAT
din
NECLASIFICAT

output_dir_path = "output/{}".format(sequence_name)
if not os.path.exists(output_dir_path):
print("Creating output directory {}".format(output_dir_path))
os.makedirs(output_dir_path)
detections = np.loadtxt(os.path.abspath(tracking_file_path),
delimiter=",")
colours = np.random.randint(0, 255, (32, 3))
for frame in range(0, int(detections[:,0].max()), frame_interval):
image_name = str(frame).rjust(4, '0') + ".jpg"
image_path = "{}/{}".format(image_dir_path, image_name)
with Image.open(image_path) as image:
draw = ImageDraw.Draw(image, 'RGBA')
# Format: [frame, ID, x1, y1, width, height, confidence, _, _,
_, (label)]
dets = detections[detections[:,0]==frame, 1:7]
labels = None
if model_type == "action-detection":
labels = detections[detections[:,0]==frame, 1]
dets[:, 3:5] += dets[:, 1:3] # Convert from [x1, y1, width,
height] to [x1, y1, x2, y2]
for i, d in enumerate(dets):
if d[5] < CONFIDENCE_THRESHOLD:
continue
d = d.astype(np.int32)
c = tuple(colours[d[0]%32, :])
draw.rectangle([d[1], d[2], d[3], d[4]], fill=(c + (100,)),
outline=c)
if model_type == "action-detection":
draw.text((d[1], d[2] + 4),
LABEL_ACTION_MAP[labels[i]], fill=(255,255,255))
image.save("{}/{}".format(output_dir_path, image_name))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--sequenceMap', metavar='sequenceMap',
required=True,
help='a textfile specifying paths to
sequences')
parser.add_argument('-m', '--modelType', metavar='modelType',
required=True,
help='name of the type of model')
parser.add_argument('-i', '--frameInterval', metavar='frameInterval',
required=False, type=int, default=1,

NECLASIFICAT
din
NECLASIFICAT

help='number of frames to skip to skip


between each produced frame')
parser.add_argument('-c', '--confidenceThreshold',
metavar='confidenceThreshold', required=False, type=float, default=0.5,
help='don\'t display detections with
confidence below this value')
args = parser.parse_args()
with open("../data/seqmaps/{}".format(args.sequenceMap)) as f:
for sequence_path in f:
generate(sequence_path, args.modelType,
args.frameInterval, args.confidenceThreshold)

Anexa 2

3.Algortimul CAMshift
# import the required packages
from imutils.video import WebcamVideoStream
from imutils.video import FPS
import numpy as np
import argparse
import imutils
import time
import cv2
import dlib
from trackers.camshifttracker import CAMShiftTracker
if __name__ == '__main__':
print("[info] starting to read a webcam ...")
capWebCam = WebcamVideoStream(0).start()
time.sleep(1.0)
# initialize dlib face detector
frontFaceDetector = dlib.get_frontal_face_detector()
# meanShift tracker
camShifTracker = None
curWindow = None
# start the frame per second (FPS) counter
#fps = FPS2().start()
boolDetectFaceinfirsFrameOnly = True
# loop over the frames obtained from the webcam

NECLASIFICAT
din
NECLASIFICAT

while True:
# grab each frame from the threaded stream,
# resize
# it, and convert it to grayscale (while still retaining 3
# channels)
frame1 = capWebCam.read()
frame = cv2.flip(frame1,1)
#frame = imutils.resize(frame, width=450)
#frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#frame = np.dstack([frame, frame, frame])
# display the size of the queue on the frame
#cv2.putText(frame, "Queue Size: {}".format(fvs.Q.qsize()),
# (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
if boolDetectFaceinfirsFrameOnly:
faceRect = frontFaceDetector(frame, 0)
if(not len(faceRect) ):
print("[info] Face not found")
continue
# start the frame per second (FPS) counter
fps = FPS2().start()
bbox = faceRect[0]
# convert dlib rect to opencv rect
curWindow = (int(bbox.left()), int(bbox.top()), int(bbox.right() -
bbox.left()),
int(bbox.bottom() - bbox.top()) )
# intialize the CAMShift Tracker
camShifTracker = CAMShiftTracker(curWindow, frame)
boolDetectFaceinfirsFrameOnly = False
continue
camShifTracker.computeNewWindow(frame)
x,y, w, h = camShifTracker.getCurWindow()
bkprojectImage = camShifTracker.getBackProjectedImage(frame)
cv2.imshow("CAMShift Face in Back Project Image", bkprojectImage)
# display the current window
cv2.rectangle(frame, (x,y), (x+w, y+h), (255, 0, 0), 2, cv2.LINE_AA)
rotatedWindow = camShifTracker.getRotatedWindow()
#display rotated window
cv2.polylines(frame, [rotatedWindow], True, (0,255,0), 2, cv2.LINE_AA)
fps.update()
cv2.putText(frame, "FPS: {:.2f}".format(fps.fps()),
(10, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

NECLASIFICAT
din
NECLASIFICAT

# show the frame and update the FPS counter


cv2.imshow("CAMShift Face Tracking", frame)
k = cv2.waitKey(10) & 0xff
if k == 27:
break
# stop the timer and display FPS information
fps.stop()
print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
# do a bit of cleanup
cv2.destroyAllWindows()
capWebCam.stop()

Anexa 3

4.Algoritmul Mean shift


# import the required packages
from imutils.video import WebcamVideoStream
#from imutils.video import FPS
import numpy as np
import argparse
import imutils
import time
import cv2
from utils.fps2 import FPS2
import dlib
from trackers.meanshifttracker import MeanShiftTracker
if __name__ == '__main__':
print("[info] starting to read a webcam ...")
capWebCam = WebcamVideoStream(0).start()
time.sleep(1.0)
# initialize dlib face detector
frontFaceDetector = dlib.get_frontal_face_detector()
# meanShift tracker
meanShifTracker = None
curWindow = None
# start the frame per second (FPS) counter
#fps = FPS2().start()
boolDetectFaceinfirsFrameOnly = True

NECLASIFICAT
din
NECLASIFICAT

# loop over the frames obtained from the webcam


while True:
# grab each frame from the threaded stream,
# resize
# it, and convert it to grayscale (while still retaining 3
# channels)
frame1 = capWebCam.read()
frame = cv2.flip(frame1,1)
#frame = imutils.resize(frame, width=450)
#frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#frame = np.dstack([frame, frame, frame])
# display the size of the queue on the frame
#cv2.putText(frame, "Queue Size: {}".format(fvs.Q.qsize()),
# (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
if boolDetectFaceinfirsFrameOnly:
faceRect = frontFaceDetector(frame, 0)
if(len(faceRect) == 0):
continue
# start the frame per second (FPS) counter
fps = FPS2().start()
bbox = faceRect[0]
# convert dlib rect to opencv rect
curWindow = (int(bbox.left()), int(bbox.top()), int(bbox.right() -
bbox.left()),
int(bbox.bottom() - bbox.top()) )

# intialize the meanShift Tracker


meanShifTracker = MeanShiftTracker(curWindow, frame)
boolDetectFaceinfirsFrameOnly = False
continue
meanShifTracker.computeNewWindow(frame)
x,y, w, h = meanShifTracker.getCurWindow()
bkprojectImage = meanShifTracker.getBackProjectedImage(frame)
cv2.imshow("MeanShift Face in Back Project Image", bkprojectImage)
cv2.rectangle(frame, (x,y), (x+w, y+h), (255, 0, 0), 2, cv2.LINE_AA)
fps.update()
cv2.putText(frame, "FPS: {:.2f}".format(fps.fps()),
(10, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
# show the frame and update the FPS counter
cv2.imshow("MeanShift Face Tracking", frame)
k = cv2.waitKey(10) & 0xff
if k == 27:

NECLASIFICAT
din
NECLASIFICAT

break
# stop the timer and display FPS information
fps.stop()
print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
# do a bit of cleanup
cv2.destroyAllWindows()
capWebCam.stop()

Anexa 4

5. Algoritmul realizat
# USAGE
# python track.py --video video/sample.mov

# import the necessary packages


import numpy as np
import argparse
import cv2
import pyzed.camera as zcam
import pyzed.defines as sl
import pyzed.types as tp
import pyzed.core as core
# initialize the current frame of the video, along with the list of
# ROI points along with whether or not this is input mode
frame = None
roiPts = []
inputMode = False
(dX, dY) = (0, 0)

def selectROI(event, x, y, flags, param):


# grab the reference to the current frame, list of ROI
# points and whether or not it is ROI selection mode
global frame, roiPts, inputMode

# if we are in ROI selection mode, the mouse was clicked,


# and we do not already have four points, then update the
# list of ROI points with the (x, y) location of the click
# and draw the circle

NECLASIFICAT
din
NECLASIFICAT

if inputMode and event == cv2.EVENT_LBUTTONDOWN and len(roiPts) <


4:
roiPts.append((x, y))
cv2.circle(frame, (x, y), 4, (0, 255, 0), 2)
cv2.imshow("frame", frame)

def main():
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help="path to the (optional) video file")

args = vars(ap.parse_args())

# grab the reference to the current frame, list of ROI


# points and whether or not it is ROI selection mode
global frame, roiPts, inputMode

# if the video path was not supplied, grab the reference to the
#camera
if not args.get("video", False):
# camera = cv2.VideoCapture(0)
zed = zcam.PyZEDCamera()
# Create a PyInitParameters object and set configuration parameters
init_params = zcam.PyInitParameters()
init_params.camera_resolution =
sl.PyRESOLUTION.PyRESOLUTION_HD720 # Use HD1080 video mode
init_params.camera_fps = 30 # Set fps at 30

# Open the camera


err = zed.open(init_params)
if err != tp.PyERROR_CODE.PySUCCESS:
exit(1)
image = core.PyMat()
runtime_parameters = zcam.PyRuntimeParameters()

# otherwise, load the video


else:

NECLASIFICAT
din
NECLASIFICAT

camera = cv2.VideoCapture(args["video"])

# setup the mouse callback


cv2.namedWindow("frame")
cv2.setMouseCallback("frame", selectROI)

# initialize the termination criteria for cam shift, indicating


# a maximum of ten iterations or movement by a least 10 pixels
# along with the bounding box of the ROI
termination = (cv2.TERM_CRITERIA_EPS |
cv2.TERM_CRITERIA_COUNT, 10, 10)
roiBox = None

# keep looping over the frames


while True:
# grab the current frame
# (grabbed, frame) = camera.read()
# Grab an image, a PyRuntimeParameters object must be given to grab()
if zed.grab(runtime_parameters) == tp.PyERROR_CODE.PySUCCESS:
# A new image is available if grab() returns PySUCCESS
zed.retrieve_image(image, sl.PyVIEW.PyVIEW_LEFT)
timestamp =
zed.get_timestamp(sl.PyTIME_REFERENCE.PyTIME_REFERENCE_CURR
ENT) # Get the timestamp at the time the image was captured
print("Image resolution: {0} x {1} || Image timestamp:
{2}\n".format(image.get_width(), image.get_height(),
timestamp))
frame = image.get_data()
height, width, layers = frame.shape
#new_h = int(height / 2)
#new_w = int(width / 2)
#frame = cv2.resize(frame, (new_w, new_h))

# check to see if we have reached the end of the


# video
'''if not grabbed:
break
else:
height, width, layers = frame.shape
new_h = int(height / 2)
new_w = int(width / 2)
frame = cv2.resize(frame, (new_w, new_h))'''

NECLASIFICAT
din
NECLASIFICAT

# if the see if the ROI has been computed


if roiBox is not None:
# convert the current frame to the HSV color space
# and perform mean shift
# Calculates a histogram of a set of arrays
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
blurred = cv2.GaussianBlur(hsv, (5, 5), 0)
thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]

backProj = cv2.calcBackProject([hsv], [0], roiHist, [0, 180], 1)

# apply cam shift to the back projection, convert the


# points to a bounding box, and then draw them
(r, roiBox) = cv2.CamShift(backProj, roiBox, termination)
# pts sunt cele patru coordonate
pts = np.int0(cv2.boxPoints(r))
ptsx = [x[0] for x in pts]
ptsy = [y[1] for y in pts]

point1 = pts[0]
point2 = pts[1]
point3 = pts[2]

point4 = pts[3]
minx = np.min(ptsx)
maxx = np.max(ptsx)
miny = np.min(ptsy)
maxy = np.max(ptsy)
cx = ((maxx-minx)/2+minx)
cy = ((maxy-miny)/2+miny)
center = (cx,cy)
dx = (320-cx)
dy = (180-cy)
deviation = (dx,dy)
print(deviation)
print(center)
cv2.polylines(frame, [pts], True, (0, 0, 255), 2)
#cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
#cv2.CHAIN_APPROX_SIMPLE)

# show the frame and record if the user presses a key

NECLASIFICAT
din
NECLASIFICAT

cv2.imshow("frame", frame)
key = cv2.waitKey(1) & 0xFF

# handle if the 'i' key is pressed, then go into ROI


# selection mode
if key == ord("i") and len(roiPts) < 4:
# indicate that we are in input mode and clone the
# frame
inputMode = True
orig = frame.copy()

# keep looping until 4 reference ROI points have


# been selected; press any key to exit ROI selction
# mode once 4 points have been selected
while len(roiPts) < 4:
cv2.imshow("frame", frame)
cv2.waitKey(0)

# determine the top-left and bottom-right points


# vectorul roiPts = vector din 4 coordonate alese de mine
roiPts = np.array(roiPts)
# s=un vector cu sumele x+y pentru fiecare dintre cele 4 coordonate
definite ca o pereche (x,y).
s = roiPts.sum(axis=1)
# tl este valoarea cea mai mica din vectorul s
tl = roiPts[np.argmin(s)]
# br este valoarea cea mai mare din vectorul s
br = roiPts[np.argmax(s)]

# grab the ROI for the bounding box and convert it


# to the HSV color space conversie din RGB in HSV color space
roi = orig[tl[1]:br[1], tl[0]:br[0]]
roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
# roi = cv2.cvtColor(roi, cv2.COLOR_BGR2LAB)

# compute a HSV histogram for the ROI and store the


# bounding box
roiHist = cv2.calcHist([roi], [0], None, [16], [0, 180])
roiHist = cv2.normalize(roiHist, roiHist, 0, 255, cv2.NORM_MINMAX)
roiBox = (tl[0], tl[1], br[0], br[1])

# if the 'q' key is pressed, stop the loop

NECLASIFICAT
din
NECLASIFICAT

elif key == ord("q"):


break

# cleanup the camera and close any open windows


# Close the camera
zed.close()
cv2.destroyAllWindows()

if __name__ == "__main__":
main()

Anexa 5

6. Algoritmul MIL
import numpy as np
import cv2
import fhog
# ffttools
def fftd(img, backwards=False):
# shape of img can be (m,n), (m,n,1) or (m,n,2)
# in my test, fft provided by numpy and scipy are slower than cv2.dft
return cv2.dft(np.float32(img), flags = ((cv2.DFT_INVERSE |
cv2.DFT_SCALE) if backwards else cv2.DFT_COMPLEX_OUTPUT)) #
'flags =' is necessary!

def real(img):
return img[:,:,0]
def imag(img):
return img[:,:,1]
def complexMultiplication(a, b):
res = np.zeros(a.shape, a.dtype)

res[:,:,0] = a[:,:,0]*b[:,:,0] - a[:,:,1]*b[:,:,1]


res[:,:,1] = a[:,:,0]*b[:,:,1] + a[:,:,1]*b[:,:,0]
return res
def complexDivision(a, b):
res = np.zeros(a.shape, a.dtype)
divisor = 1. / (b[:,:,0]**2 + b[:,:,1]**2)

NECLASIFICAT
din
NECLASIFICAT

res[:,:,0] = (a[:,:,0]*b[:,:,0] + a[:,:,1]*b[:,:,1]) * divisor


res[:,:,1] = (a[:,:,1]*b[:,:,0] + a[:,:,0]*b[:,:,1]) * divisor
return res
def rearrange(img):
#return np.fft.fftshift(img, axes=(0,1))
assert(img.ndim==2)
img_ = np.zeros(img.shape, img.dtype)
xh, yh = img.shape[1]/2, img.shape[0]/2
img_[0:yh,0:xh], img_[yh:img.shape[0],xh:img.shape[1]] =
img[yh:img.shape[0],xh:img.shape[1]], img[0:yh,0:xh]
img_[0:yh,xh:img.shape[1]], img_[yh:img.shape[0],0:xh] =
img[yh:img.shape[0],0:xh], img[0:yh,xh:img.shape[1]]
return img_

def x2(rect):
return rect[0] + rect[2]

def y2(rect):
return rect[1] + rect[3]

def limit(rect, limit):


if(rect[0]+rect[2] > limit[0]+limit[2]):
rect[2] = limit[0]+limit[2]-rect[0]
if(rect[1]+rect[3] > limit[1]+limit[3]):
rect[3] = limit[1]+limit[3]-rect[1]
if(rect[0] < limit[0]):
rect[2] -= (limit[0]-rect[0])
rect[0] = limit[0]
if(rect[1] < limit[1]):
rect[3] -= (limit[1]-rect[1])
rect[1] = limit[1]
if(rect[2] < 0):
rect[2] = 0
if(rect[3] < 0):
rect[3] = 0
return rect

def getBorder(original, limited):


res = [0,0,0,0]
res[0] = limited[0] - original[0]
res[1] = limited[1] - original[1]
res[2] = x2(original) - x2(limited)

NECLASIFICAT
din
NECLASIFICAT

res[3] = y2(original) - y2(limited)


assert(np.all(np.array(res) >= 0))
return res

def subwindow(img, window, borderType=cv2.BORDER_CONSTANT):


cutWindow = [x for x in window]
limit(cutWindow, [0,0,img.shape[1],img.shape[0]]) # modify
cutWindow
assert(cutWindow[2]>0 and cutWindow[3]>0)
border = getBorder(window, cutWindow)
res = img[cutWindow[1]:cutWindow[1]+cutWindow[3],
cutWindow[0]:cutWindow[0]+cutWindow[2]]

if(border != [0,0,0,0]):
res = cv2.copyMakeBorder(res, border[1], border[3], border[0],
border[2], borderType)
return res
# KCF tracker
class KCFTracker:
def __init__(self, hog=False, fixed_window=True, multiscale=False):
self.lambdar = 0.0001 # regularization
self.padding = 2.5 # extra area surrounding the target
self.output_sigma_factor = 0.125 # bandwidth of gaussian target

if(hog): # HOG feature


# VOT
self.interp_factor = 0.012 # linear interpolation factor for
adaptation
self.sigma = 0.6 # gaussian kernel bandwidth
# TPAMI #interp_factor = 0.02 #sigma = 0.5
self.cell_size = 4 # HOG cell size
self._hogfeatures = True
else: # raw gray-scale image # aka CSK tracker
self.interp_factor = 0.075
self.sigma = 0.2
self.cell_size = 1
self._hogfeatures = False

if(multiscale):
self.template_size = 96 # template size
self.scale_step = 1.05 # scale step for multi-scale estimation

NECLASIFICAT
din
NECLASIFICAT

self.scale_weight = 0.96 # to downweight detection scores


of other scales for added stability
elif(fixed_window):
self.template_size = 96
self.scale_step = 1
else:
self.template_size = 1
self.scale_step = 1

self._tmpl_sz = [0,0] # cv::Size, [width,height] #[int,int]


self._roi = [0.,0.,0.,0.] # cv::Rect2f, [x,y,width,height]
#[float,float,float,float]
self.size_patch = [0,0,0] #[int,int,int]
self._scale = 1. # float
self._alphaf = None # numpy.ndarray (size_patch[0],
size_patch[1], 2)
self._prob = None # numpy.ndarray (size_patch[0],
size_patch[1], 2)
self._tmpl = None # numpy.ndarray raw: (size_patch[0],
size_patch[1]) hog: (size_patch[2], size_patch[0]*size_patch[1])
self.hann = None # numpy.ndarray raw: (size_patch[0],
size_patch[1]) hog: (size_patch[2], size_patch[0]*size_patch[1])

def subPixelPeak(self, left, center, right):


divisor = 2*center - right - left #float
return (0 if abs(divisor)<1e-3 else 0.5*(right-left)/divisor)

def createHanningMats(self):
hann2t, hann1t = np.ogrid[0:self.size_patch[0],
0:self.size_patch[1]]

hann1t = 0.5 * (1 - np.cos(2*np.pi*hann1t/(self.size_patch[1]-1)))


hann2t = 0.5 * (1 - np.cos(2*np.pi*hann2t/(self.size_patch[0]-1)))
hann2d = hann2t * hann1t

if(self._hogfeatures):
hann1d =
hann2d.reshape(self.size_patch[0]*self.size_patch[1])
self.hann = np.zeros((self.size_patch[2], 1), np.float32) +
hann1d
else:
self.hann = hann2d

NECLASIFICAT
din
NECLASIFICAT

self.hann = self.hann.astype(np.float32)

def createGaussianPeak(self, sizey, sizex):


syh, sxh = sizey/2, sizex/2
output_sigma = np.sqrt(sizex*sizey) / self.padding *
self.output_sigma_factor
mult = -0.5 / (output_sigma*output_sigma)
y, x = np.ogrid[0:sizey, 0:sizex]
y, x = (y-syh)**2, (x-sxh)**2
res = np.exp(mult * (y+x))
return fftd(res)

def gaussianCorrelation(self, x1, x2):


if(self._hogfeatures):
c = np.zeros((self.size_patch[0], self.size_patch[1]),
np.float32)
for i in xrange(self.size_patch[2]):
x1aux = x1[i, :].reshape((self.size_patch[0],
self.size_patch[1]))
x2aux = x2[i, :].reshape((self.size_patch[0],
self.size_patch[1]))
caux = cv2.mulSpectrums(fftd(x1aux), fftd(x2aux), 0,
conjB = True)
caux = real(fftd(caux, True))
#caux = rearrange(caux)
c += caux
c = rearrange(c)
else:
c = cv2.mulSpectrums(fftd(x1), fftd(x2), 0, conjB = True) #
'conjB=' is necessary!
c = fftd(c, True)
c = real(c)
c = rearrange(c)

if(x1.ndim==3 and x2.ndim==3):


d = (np.sum(x1[:,:,0]*x1[:,:,0]) + np.sum(x2[:,:,0]*x2[:,:,0]) -
2.0*c) / (self.size_patch[0]*self.size_patch[1]*self.size_patch[2])
elif(x1.ndim==2 and x2.ndim==2):
d = (np.sum(x1*x1) + np.sum(x2*x2) - 2.0*c) /
(self.size_patch[0]*self.size_patch[1]*self.size_patch[2])

d = d * (d>=0)

NECLASIFICAT
din
NECLASIFICAT

d = np.exp(-d / (self.sigma*self.sigma))

return d

def getFeatures(self, image, inithann, scale_adjust=1.0):


extracted_roi = [0,0,0,0] #[int,int,int,int]
cx = self._roi[0] + self._roi[2]/2 #float
cy = self._roi[1] + self._roi[3]/2 #float

if(inithann):
padded_w = self._roi[2] * self.padding
padded_h = self._roi[3] * self.padding

if(self.template_size > 1):


if(padded_w >= padded_h):
self._scale = padded_w /
float(self.template_size)
else:
self._scale = padded_h /
float(self.template_size)
self._tmpl_sz[0] = int(padded_w / self._scale)
self._tmpl_sz[1] = int(padded_h / self._scale)
else:
self._tmpl_sz[0] = int(padded_w)
self._tmpl_sz[1] = int(padded_h)
self._scale = 1.

if(self._hogfeatures):
self._tmpl_sz[0] = int(self._tmpl_sz[0]) /
(2*self.cell_size) * 2*self.cell_size + 2*self.cell_size
self._tmpl_sz[1] = int(self._tmpl_sz[1]) /
(2*self.cell_size) * 2*self.cell_size + 2*self.cell_size
else:
self._tmpl_sz[0] = int(self._tmpl_sz[0]) / 2 * 2
self._tmpl_sz[1] = int(self._tmpl_sz[1]) / 2 * 2

extracted_roi[2] = int(scale_adjust * self._scale * self._tmpl_sz[0])


extracted_roi[3] = int(scale_adjust * self._scale * self._tmpl_sz[1])
extracted_roi[0] = int(cx - extracted_roi[2]/2)
extracted_roi[1] = int(cy - extracted_roi[3]/2)

z = subwindow(image, extracted_roi, cv2.BORDER_REPLICATE)

NECLASIFICAT
din
NECLASIFICAT

if(z.shape[1]!=self._tmpl_sz[0] or z.shape[0]!=self._tmpl_sz[1]):
z = cv2.resize(z, tuple(self._tmpl_sz))

if(self._hogfeatures):
mapp = {'sizeX':0, 'sizeY':0, 'numFeatures':0, 'map':0}
mapp = fhog.getFeatureMaps(z, self.cell_size, mapp)
mapp = fhog.normalizeAndTruncate(mapp, 0.2)
mapp = fhog.PCAFeatureMaps(mapp)
self.size_patch = map(int, [mapp['sizeY'], mapp['sizeX'],
mapp['numFeatures']])
FeaturesMap =
mapp['map'].reshape((self.size_patch[0]*self.size_patch[1],
self.size_patch[2])).T # (size_patch[2], size_patch[0]*size_patch[1])
else:
if(z.ndim==3 and z.shape[2]==3):
FeaturesMap = cv2.cvtColor(z,
cv2.COLOR_BGR2GRAY) # z:(size_patch[0], size_patch[1], 3)
FeaturesMap:(size_patch[0], size_patch[1]) #np.int8 #0~255
elif(z.ndim==2):
FeaturesMap = z #(size_patch[0], size_patch[1])
#np.int8 #0~255
FeaturesMap = FeaturesMap.astype(np.float32) / 255.0 - 0.5
self.size_patch = [z.shape[0], z.shape[1], 1]

if(inithann):
self.createHanningMats() # createHanningMats need
size_patch

FeaturesMap = self.hann * FeaturesMap


return FeaturesMap

def detect(self, z, x):


k = self.gaussianCorrelation(x, z)
res = real(fftd(complexMultiplication(self._alphaf, fftd(k)), True))

_, pv, _, pi = cv2.minMaxLoc(res) # pv:float pi:tuple of int


p = [float(pi[0]), float(pi[1])] # cv::Point2f, [x,y] #[float,float]

if(pi[0]>0 and pi[0]<res.shape[1]-1):


p[0] += self.subPixelPeak(res[pi[1],pi[0]-1], pv,
res[pi[1],pi[0]+1])
if(pi[1]>0 and pi[1]<res.shape[0]-1):

NECLASIFICAT
din
NECLASIFICAT

p[1] += self.subPixelPeak(res[pi[1]-1,pi[0]], pv,


res[pi[1]+1,pi[0]])

p[0] -= res.shape[1] / 2.
p[1] -= res.shape[0] / 2.

return p, pv

def train(self, x, train_interp_factor):


k = self.gaussianCorrelation(x, x)
alphaf = complexDivision(self._prob, fftd(k)+self.lambdar)

self._tmpl = (1-train_interp_factor)*self._tmpl +
train_interp_factor*x
self._alphaf = (1-train_interp_factor)*self._alphaf +
train_interp_factor*alphaf

def init(self, roi, image):


self._roi = map(float, roi)
assert(roi[2]>0 and roi[3]>0)
self._tmpl = self.getFeatures(image, 1)
self._prob = self.createGaussianPeak(self.size_patch[0],
self.size_patch[1])
self._alphaf = np.zeros((self.size_patch[0], self.size_patch[1], 2),
np.float32)
self.train(self._tmpl, 1.0)

def update(self, image):


if(self._roi[0]+self._roi[2] <= 0): self._roi[0] = -self._roi[2] + 1
if(self._roi[1]+self._roi[3] <= 0): self._roi[1] = -self._roi[2] + 1
if(self._roi[0] >= image.shape[1]-1): self._roi[0] = image.shape[1]
-2
if(self._roi[1] >= image.shape[0]-1): self._roi[1] = image.shape[0]
-2

cx = self._roi[0] + self._roi[2]/2.
cy = self._roi[1] + self._roi[3]/2.

loc, peak_value = self.detect(self._tmpl, self.getFeatures(image, 0,


1.0))

NECLASIFICAT
din
NECLASIFICAT

if(self.scale_step != 1):
# Test at a smaller _scale
new_loc1, new_peak_value1 = self.detect(self._tmpl,
self.getFeatures(image, 0, 1.0/self.scale_step))
# Test at a bigger _scale
new_loc2, new_peak_value2 = self.detect(self._tmpl,
self.getFeatures(image, 0, self.scale_step))

if(self.scale_weight*new_peak_value1 > peak_value and


new_peak_value1>new_peak_value2):
loc = new_loc1
peak_value = new_peak_value1
self._scale /= self.scale_step
self._roi[2] /= self.scale_step
self._roi[3] /= self.scale_step
elif(self.scale_weight*new_peak_value2 > peak_value):
loc = new_loc2
peak_value = new_peak_value2
self._scale *= self.scale_step
self._roi[2] *= self.scale_step
self._roi[3] *= self.scale_step

self._roi[0] = cx - self._roi[2]/2.0 + loc[0]*self.cell_size*self._scale


self._roi[1] = cy - self._roi[3]/2.0 + loc[1]*self.cell_size*self._scale

if(self._roi[0] >= image.shape[1]-1): self._roi[0] = image.shape[1]


-1
if(self._roi[1] >= image.shape[0]-1): self._roi[1] = image.shape[0]
-1
if(self._roi[0]+self._roi[2] <= 0): self._roi[0] = -self._roi[2] + 2
if(self._roi[1]+self._roi[3] <= 0): self._roi[1] = -self._roi[3] + 2
assert(self._roi[2]>0 and self._roi[3]>0)

x = self.getFeatures(image, 0, 1.0)
self.train(x, self.interp_factor)
return self._roi

7. Algoritmul BOOSTING
#from fbtrack import *
#from bb import getBB, getRectFromBB

NECLASIFICAT
din
NECLASIFICAT

import cv2
class mftrack:
def __init__(self, source=None, bb=None):
self.mouse_p1 = None
self.mouse_p2 = None
self.mouse_drag = False
self.bb = None
self.img = None
self.mouseFlag = True
if source:
self.cam = cv2.VideoCapture(source)
else:
self.cam = cv2.VideoCapture(0)
if not bb:
self.start()
else:
self.bb = bb
_, self.img = self.cam.read()
self.track()

def start(self):
_, self.img = self.cam.read()
cv2.imshow("img", self.img)
cv.SetMouseCallback("img", self.__mouseHandler, None)
if not self.bb:
_, self.img = self.cam.read()
cv2.imshow("img", self.img)
cv2.waitKey(30)
cv2.waitKey(0)

def __mouseHandler(self, event, x, y, flags, params):


if self.mouseFlag == False:
return
_, self.img = self.cam.read()
if event == cv.CV_EVENT_LBUTTONDOWN and not self.mouse_drag:
self.mouse_p1 = (x, y)
self.mouse_drag = True
elif event == cv.CV_EVENT_MOUSEMOVE and self.mouse_drag:
cv2.rectangle(self.img, self.mouse_p1, (x, y), (255, 0, 0), 1, 8, 0)
elif event == cv.CV_EVENT_LBUTTONUP and self.mouse_drag:
self.mouse_p2 = (x, y)
self.mouse_drag=False

NECLASIFICAT
din
NECLASIFICAT

cv2.imshow("img",self.img)
cv2.waitKey(30)
if self.mouse_p1 and self.mouse_p2:
cv2.destroyWindow("img")
print self.mouse_p1
print self.mouse_p2
xmax = max(self.mouse_p1[0],self.mouse_p2[0])
xmin = min(self.mouse_p1[0],self.mouse_p2[0])
ymax = max(self.mouse_p1[1],self.mouse_p2[1])
ymin = min(self.mouse_p1[1],self.mouse_p2[1])
self.bb = [xmin,ymin,xmax-xmin,ymax-ymin]
self.track()
def track(self):
self.mouseFlag = False
oldg = cv2.cvtColor(self.img, cv2.cv.CV_BGR2GRAY)
bb = self.bb
bb = [bb[0], bb[1], bb[0]+bb[3], bb[1]+bb[3]]
while True:
t = time.time()
_, img = self.cam.read()
newg = cv2.cvtColor(img, cv2.cv.CV_BGR2GRAY)
newbb, shift = fbtrack(oldg, newg, bb, 12, 12, 3, 12)
#print newbb, "newbb", shift, "shift"
oldg = newg
bb = newbb
cv2.rectangle(img, (bb[0], bb[1]), (bb[2], bb[3]), (255, 0, 0))
cv2.imshow("Media Flow Tracker", img)
print (time.time() - t)*1000,"msec"
k = cv2.waitKey(1)
if k == 27:
self.mouseFlag = False
cv2.destroyAllWindows()
break
return None

8. Urmărire țintă singulară


# USAGE
# python track.py --video video/sample.mov
# import the necessary packages
import numpy as np

NECLASIFICAT
din
NECLASIFICAT

import argparse
import cv2
# initialize the current frame of the video, along with the list of
# ROI points along with whether or not this is input mode
frame = None
roiPts = []
inputMode = False
def selectROI(event, x, y, flags, param):
# grab the reference to the current frame, list of ROI
# points and whether or not it is ROI selection mode
global frame, roiPts, inputMode

# if we are in ROI selection mode, the mouse was clicked,


# and we do not already have four points, then update the
# list of ROI points with the (x, y) location of the click
# and draw the circle
if inputMode and event == cv2.EVENT_LBUTTONDOWN and len(roiPts) <
4:
roiPts.append((x, y))
cv2.circle(frame, (x, y), 4, (0, 255, 0), 2)
cv2.imshow("frame", frame)
def main():
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help="path to the (optional) video file")

args = vars(ap.parse_args())
# grab the reference to the current frame, list of ROI
# points and whether or not it is ROI selection mode
global frame, roiPts, inputMode
# if the video path was not supplied, grab the reference to the
#camera
if not args.get("video", False):
camera = cv2.VideoCapture(0)

# otherwise, load the video


else:
camera = cv2.VideoCapture(args["video"])

NECLASIFICAT
din
NECLASIFICAT

# setup the mouse callback


cv2.namedWindow("frame")
cv2.setMouseCallback("frame", selectROI)

# initialize the termination criteria for cam shift, indicating


# a maximum of ten iterations or movement by a least one pixel
# along with the bounding box of the ROI
termination = (cv2.TERM_CRITERIA_EPS |
cv2.TERM_CRITERIA_COUNT, 10, 1)
roiBox = None

# keep looping over the frames


while True:
# grab the current frame
(grabbed, frame) = camera.read()

# check to see if we have reached the end of the


# video
if not grabbed:
break
else:
height, width, layers = frame.shape
new_h = int(height / 2)
new_w = int(width / 2)
frame = cv2.resize(frame, (new_w, new_h))

# if the see if the ROI has been computed


if roiBox is not None:
# convert the current frame to the HSV color space
# and perform mean shift
# Calculates a histogram of a set of arrays
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
backProj = cv2.calcBackProject([hsv], [0], roiHist, [0, 180], 1)

# apply cam shift to the back projection, convert the


# points to a bounding box, and then draw them
(r, roiBox) = cv2.CamShift(backProj, roiBox, termination)
# pts sunt cele patru coordonate
pts = np.int0(cv2.boxPoints(r))
ptsx = [x[0] for x in pts]
ptsy = [y[1] for y in pts]

NECLASIFICAT
din
NECLASIFICAT

point1 = pts[0]
point2 = pts[1]
point3 = pts[2]

point4 = pts[3]
minx = np.min(ptsx)
maxx = np.max(ptsx)
miny = np.min(ptsy)
maxy = np.max(ptsy)
center = [((maxx-minx)/2+minx),((maxy-miny)/2+miny)]
print(center)
cv2.polylines(frame, [pts], True, (0, 0, 255), 2)

# show the frame and record if the user presses a key


cv2.imshow("frame", frame)
key = cv2.waitKey(1) & 0xFF

# handle if the 'i' key is pressed, then go into ROI


# selection mode
if key == ord("i") and len(roiPts) < 4:
# indicate that we are in input mode and clone the
# frame
inputMode = True
orig = frame.copy()

# keep looping until 4 reference ROI points have


# been selected; press any key to exit ROI selction
# mode once 4 points have been selected
while len(roiPts) < 4:
cv2.imshow("frame", frame)
cv2.waitKey(0)

# determine the top-left and bottom-right points


# vectorul roiPts = vector din 4 coordonate alese de mine
roiPts = np.array(roiPts)
# s=un vector cu sumele x+y pentru fiecare dintre cele 4 coordonate
definite ca o pereche (x,y).
s = roiPts.sum(axis=1)
# tl este valoarea cea mai mica din vectorul s
tl = roiPts[np.argmin(s)]
# br este valoarea cea mai mare din vectorul s
br = roiPts[np.argmax(s)]

NECLASIFICAT
din
NECLASIFICAT

# grab the ROI for the bounding box and convert it


# to the HSV color space conversie din RGB in HSV color space
roi = orig[tl[1]:br[1], tl[0]:br[0]]
roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
# roi = cv2.cvtColor(roi, cv2.COLOR_BGR2LAB)

# compute a HSV histogram for the ROI and store the


# bounding box
roiHist = cv2.calcHist([roi], [0], None, [16], [0, 180])
roiHist = cv2.normalize(roiHist, roiHist, 0, 255, cv2.NORM_MINMAX)
roiBox = (tl[0], tl[1], br[0], br[1])

# if the 'q' key is pressed, stop the loop


elif key == ord("q"):
break

# cleanup the camera and close any open windows


camera.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()

9. Urmărire ținte multiple


# import the required packages
from imutils.video import WebcamVideoStream
#from imutils.video import FPS
import numpy as np
import argparse
import imutils
import time
import cv2
import dlib
from fps2 import FPS2
if __name__ == '__main__':
# Initialize the argument parse which is used to parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-t", "--type", required=True,

NECLASIFICAT
din
NECLASIFICAT

help="input from [0..5] for selection of type of tracker from


['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'GOTURN'] ")
args = vars(ap.parse_args())

print("[info] tracker selected is ", args["type"])

# a list of trackers type available in OpenCV3.2


#
trackerTypes = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW',
'GOTURN']

trackerType = trackerTypes[int(args["type"])]

trackerOpenCV = cv2.Tracker_create("MIL")

frontFaceDetector = dlib.get_frontal_face_detector()
initOnce = False
print("[info] starting to read a webcam ...")
capWebCam = WebcamVideoStream(0).start()
time.sleep(1.0)

# start the frame per second (FPS) counter


#fps = FPS2().start()
# loop over the frames obtained from the webcam
while True:
# grab each frame from the threaded stream,
# resize
# it, and convert it to grayscale (while still retaining 3
# channels)
frame1 = capWebCam.read()
frame = cv2.flip(frame1,1)
#frame = imutils.resize(frame, width=450)
#frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#frame = np.dstack([frame, frame, frame])

# display the size of the queue on the frame


#cv2.putText(frame, "Queue Size: {}".format(fvs.Q.qsize()),
# (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
if not initOnce:
faceRect = frontFaceDetector(frame, 0)
if(len(faceRect) == 0):
continue

NECLASIFICAT
din
NECLASIFICAT

# start the frame per second (FPS) counter


fps = FPS2().start()

bbox = faceRect[0]

print(bbox)

# convert dlib rect to opencv rect

curFaceBbox = (int(bbox.left()), int(bbox.top()), int(bbox.right() -


bbox.left()),
int(bbox.bottom() - bbox.top()) )

# intialize the Tracker

#curFaceBbox = cv2.selectROI("tracking", frame)

success = trackerOpenCV.init(frame, curFaceBbox)


initOnce = True
#continue
# Update tracker
success, curFaceBbox = trackerOpenCV.update(frame)
print(success, curFaceBbox)
if success:
# Tracking success
topLeft = (int(curFaceBbox[0]), int(curFaceBbox[1]))
bottomRight = (int(curFaceBbox[0] + curFaceBbox[2]),
int(curFaceBbox[1] + curFaceBbox[3]))
cv2.rectangle(frame, topLeft,bottomRight, (255,0,0), 2,1 )
else:
# Tracking failure
cv2.putText(frame, trackerType + " Tracking failure detected", (20,80),
cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,0,255),2)

fps.update()
cv2.putText(frame, "FPS: {:.2f}".format(fps.fps()),
(10, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

cv2.putText(frame, trackerType + " Tracker", (20,80),


cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,0,255),2)

NECLASIFICAT
din
NECLASIFICAT

# show the frame and update the FPS counter


cv2.imshow("OpenCV Tracking by " + trackerType, frame)

k = cv2.waitKey(10) & 0xff


if k == 27:
break
# stop the timer and display FPS information
fps.stop()
print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

# do a bit of cleanup
cv2.destroyAllWindows()
capWebCam.stop()

10. Algoritmul KCF


# import the required packages
from imutils.video import FileVideoStream
#from imutils.video import FPS
import numpy as np
import argparse
import imutils
import time
import cv2
import sys
from utils.fps2 import FPS2
from matplotlib import tight_bbox
if __name__ == '__main__':

# Initialize the argument parse which is used to parse the arguments


ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", required=True,
help="path to input video file")

ap.add_argument("-t", "--type", required=True,


help="input from [0..5] for selection of type of tracker from
['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'GOTURN'] ")
args = vars(ap.parse_args())

print("[info] tracker selected is ", args["type"])

NECLASIFICAT
din
NECLASIFICAT

# a list of trackers type available in OpenCV3.2


#
trackerTypes = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW',
'GOTURN']
trackerType = trackerTypes[int(args["type"])]
# initialize multiple Tracker object with tracking algo
multipleTrackerOpenCV = cv2.MultiTracker(trackerType)
# Since the read method of the openCV cv2.VideoCapture
# is blocking IO operation
# Therefore I am going to use thread enable version of reading
# the video. It is implemented in imutil package (pyImagesearch.com)
# start and open a pointer to the file video stream thread
# and allow the buffer to start to fill
print("[info] starting to read a video file ...")
fvs = FileVideoStream(args["video"]).start()
time.sleep(1.0)
# read the first frame
frame = fvs.read()
#if not success:
# print("[info]: Failed to read the video")
# sys.exit(1)

#
init = False
bboxes = [] # contains bounding boxes around the objects to be tracked
# initialize various objects in the first frame of the video
while True:
# select the ROI around the object to be tracked
box = cv2.selectROI('tracking', frame, showCrossair=False,
fromCenter=False)
print(box)
bboxes.append(box)
print("[info] print q to quit object selection and anyother key for next
object selection")
k = cv2.waitKey(0) & 0xff
if(k== 113):
break
print("[info] selecting objects {}".format(bboxes))
# start the frame per second (FPS) counter
fps = FPS2().start()

NECLASIFICAT
din
NECLASIFICAT

# loop over the frames obtained from the video file stream
while fvs.more():
# grab each frame from the threaded video file stream,
# resize
# it, and convert it to grayscale (while still retaining 3
# channels)
frame = fvs.read()
#frame = imutils.resize(frame, width=450)
#frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#frame = np.dstack([frame, frame, frame])

# display the size of the queue on the frame


#cv2.putText(frame, "Queue Size: {}".format(fvs.Q.qsize()),
# (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

# initialize the trackers only once


if not init:
success = multipleTrackerOpenCV.add(frame,bboxes)
init = True

success, boxes = multipleTrackerOpenCV.update(frame)

print("[info] no boxes {}".format(len(boxes)))

for box in boxes:


p1= (int(box[0]), int(box[1]))
p2 = (int(box[0] + box[2]), int(box[1] + box[3]))
cv2.rectangle(frame, p1, p2, (200, 0, 0))
fps.update()
cv2.putText(frame, "FPS: {:.2f}".format(fps.fps()),
(10, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

cv2.putText(frame, trackerType + " Tracker", (20,80),


cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,0,255),2)
# show the frame and update the FPS counter
cv2.imshow("Frame", frame)
k = cv2.waitKey(1) & 0xff
if k == 27:
break
# stop the timer and display FPS information
fps.stop()

NECLASIFICAT
din
NECLASIFICAT

print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))


print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))

# do a bit of cleanup
cv2.destroyAllWindows()
fvs.stop()

NECLASIFICAT
din
NECLASIFICAT

NECLASIFICAT
din

S-ar putea să vă placă și