Calculatoare și Tehnologia Informației [609223]
UNIVERSITATEA TEHNICĂ „Gheorghe Asachi” din IAȘI
FACULTATEA DE AUTOMATICĂ ȘI CALCULATOARE
DOMENIUL: Calculatoare și Tehnologia Informației
SPECIALIZAREA: Calculatoare
Captarea unei imagini pe o pagină WEB
și prelucrarea acesteia
LUCRARE DE LICENȚĂ
Coordonator șt iințific
Prof. dr. ing. Vasile Manta
Absolvent: [anonimizat], 2017
DECLARAȚIE DE ASUMARE A AUTENTICITĂȚII
LUCRĂRII DE LICENȚĂ
Subsemnatul(a) ,
legitimat(ă) cu seria nr. , CNP
autorul lucrării
elaborată în vederea susținerii examenului de finalizare a studiilor de licență
organizat de către Facultatea de Automatică și Calculatoare din cadrul Universității
Tehnice „Gheorghe Asachi” din Iași, sesiunea a anului universitar
, luând în considerare conținutul Art. 34 din Codul de etică universitară al
Universității Tehnice „Gheorghe Asachi” din Iași (Manualul Procedurilor, UTI.POM.02 –
Funcționarea Comisiei de etică universitară), declar pe proprie răspundere, că această
lucrare este rezultatul propriei activități intelectuale, nu conține porțiuni plagiate, iar
sursele bibliografice au fost folosite cu respectarea legislației române (legea 8/1996) și a
convențiilor internaționale privind drepturile de autor.
Data Semnătura
Cuprins
Capitolul 1. Introducere ……………………………………………………………………………………………………. 1
Capitolul 2. Fundamente teoretice ……………………………………………………………………………………… 2
2.1. Prelucrare de imagine ……………………………………………………………………………………………. 2
2.1.1. Scurt istoric………………………………………………………………………………………………… 2
2.1.2. Ce reprezintă îmbunătățirea imaginilor? …………………………………………………………. 2
2.1.3. Noțiunea de zgomot …………………………………………………………………………………….. 2
2.1.4. Tipuri de zgomot…………………………………………………………………………………………. 2
2.1.5. Operațiuni speciale (bazele filtrării spațiale) …………………………………………………… 3
2.1.6. Domeniul frecvențelor …………………………………………………………………………………. 4
2.2. Ce sunt WebSocket-urile? ………………………………………………………………………………………. 4
2.2.1. Ce înseamnă WebSocket-urile pentru IT? ………………………………………………………. 5
2.2.2. Ce înseamnă WebSocket-urile pentru arhitecți și developeri? ……………………………. 5
2.2.3. Cum sunt utilizate? ………………………………………………………………………………………. 5
2.2.4. De ce avem nevoie de WebSocket-uri? …………………………………………………………… 6
2.2.5. Câteva avantaje ale utilizării WebSocket-urilor ……………………………………………….. 6
2.3. Tehnologii utilizate ……………………………………………………………………………………………….. 6
2.3.1. Pagini Web și Servere Web …………………………………………………………………………… 7
2.3.2. Pagini Web Statice și Dinamice …………………………………………………………………….. 9
2.3.3. OpenCV…………………………………………………………………………………………………… 11
2.3.3.1. Ce este mai exact OpenCV? …………………………………………………………….. 11
2.3.3.2. Cum a apărut OpenCV-ul? ……………………………………………………………….. 12
2.3.4. Raspbian…………………………………………………………………………………………………… 12
Capitolul 3. Proiectarea aplicației …………………………………………………………………………………….. 14
3.1. Descrierea aplicației …………………………………………………………………………………………….. 14
3.2. Funcțiile aplicației……………………………………………………………………………………………….. 14
3.3. Stabilirea componentelor hardware ………………………………………………………………………… 14
3.4. Descrierea componentelor hardware ………………………………………………………………………. 14
3.4.1. Camera Web LOGITECH C270 ………………………………………………………………….. 14
3.4.2. Raspberry Pi……………………………………………………………………………………………… 15
3.4.2.1. Specificații și evoluție ……………………………………………………………………… 15
3.4.2.2. Arhitectura plăcuței Raspberry Pi Model B ………………………………………… 17
3.4.2.3. Sisteme de operare disponibile pentru Raspberry Pi …………………………….. 18
3.4.2.4. Analiza și alegerea sistemului de operare …………………………………………… 18
3.4.3. Cablu de rețea STP, Cât 5e ………………………………………………………………………….. 20
3.5. Interconectarea componentelor principale ………………………………………………………………. 20
3.8. Componentele software ………………………………………………………………………………………… 21
Capitolul 4. Implementarea aplicației ……………………………………………………………………………….. 22
4.1. Descărcare și instalare Raspbian ……………………………………………………………………………. 22
4.2. Conectarea plăcuței la laptop prin SSH ………………………………………………………………….. 23
4.3. Instalare OpenCV………………………………………………………………………………………………… 24
4.4. Crearea server-ului flask ………………………………………………………………………………………. 27
4.5. Crearea modulului Camera …………………………………………………………………………………… 27
4.6. Realizarea paginii ………………………………………………………………………………………………. 28
Capitolul 5. Testarea aplicației și rezultatele experimentale …………………………………………………. 33
5.1. Pornirea server-ului ……………………………………………………………………………………………… 33
5.2. Accesarea browser-ului ………………………………………………………………………………………… 33
5.3. Captarea imaginii………………………………………………………………………………………………… 34
5.4. Încărcarea imaginii pe pagină ……………………………………………………………………………….. 35
5.5. Aplicarea funcțiilor …………………………………………………………………………………………….. 35
5.6. Slide Filtre………………………………………………………………………………………………………….. 36
Concluzii……………………………………………………………………………………………………………………… 37
Bibliografie………………………………………………………………………………………………………………….. 38
Anexe………………………………………………………………………………………………………………………….. 39
Anexa 1. Codul din app.py – realizarea streaming-ului pe server-ul flask …………………………. 39
Anexa 2. Modulul camera.py ………………………………………………………………………………………. 40
Anexa 3. Codul pentru pagina Web, index.html …………………………………………………………….. 41
Captarea unei imagini pe o pagină WEB
și prelucrarea acesteia
Brînză Cătălin – Mihai
Rezumat
Proiectul propune o soluție pentru crearea unei aplicații online ce va avea ca rol captarea
unei imagini de la un video streaming oferit de o camer ă web urmat de salvarea și prelucrarea
acesteia pe o pagină web. Proiectul pune la dispoziție o interfață web în care userii, vor putea
accesa pagina unde vor beneficia de un streaming, putând astfel să salveze orice imagine doresc,
pe care ulterior o vor prelucra. Soluția pentru video streaming este una bazată pe implementarea
bibliotecii OpenCV .
OpenCV este un acronim pentru Open Source Computer Vision și este o bibliotecă de
funcții ce captează și prelucrează imaginile în timp real.
Implementarea aplicației am facut-o folosind PYTHON ca limbaj de programare, fiind un
limbaj ce oferă portabilitate, fiind open source și fiind capabil de includerea bibliotecii OpenCV ,
folosite pentru reușirea unui streaming de calitate.
Faza inițială a fost cea de creare a unei server flask (python), pe care vom urca aplicația
de tip stand-alone (controlată de pe orice dispozitiv), care va fi capabilă să ofere un live
streaming, captări de imagini și nu în ultimul rând prelucrări de imagine.
Comunicarea dintre pagina web și aplicația implementată în vederea folosirii librărie
OpenCV , se realizează printr-un WebSocket PYTHON, pe partea de web folosind obiectul
WebSocket oferit de JavaScript ce realizează conexiunea cu serverul, iar la preluarea mesajului
având capabilitatea de a modifica pagina web, fară a fi nevoie să se reîncarce pagina. Datele
trimise pe partea de WebSocket, reprezintă imaginea după procesare convertită în base64, tag-ul
<img> din HTML având capabilitatea de a face decoding pe mesajul primit de la WebSocket,
nefiind nevoie să salvăm imaginea în browser pentru a o putea prelua clientul.
Tot ce ține de construcția serverului și a aplicației, se va realiza pe mediul de dezvoltare
Linux, cu ajutorul placuței Raspberry Pi Model B. După construcția serverului și a streaming-
ului vor fi implementate o serie de butoane a căror scop sunt aplicarea unor filtre de prelucrare a
imaginii cu ajutorul limbajului de programare JavaScript.
Capitolul 1.Introducere
Capitolul 1. Introducere
Prelucrarea și analiza imaginilor (numită adeseori prescurtat doar prelucrarea imaginilor)
s-a născut datorită ideii ̧și necesității de a înlocui observatorul uman printr-o mașina. Este
important de precizat că analiza imaginilor a mers mai departe decât simpla înlocuire a
observatorului uman, deoarece au aparut soluții inovatoare pentru probleme cu care acesta nu
mai fusese confruntat, ca în cazul imaginilor non-vizibile (imagini acustice, ultrasonore, radar).
Imaginile 2D sunt constituite din matrici de valori care reprezintă diverse modalități de
codificare a culorilor pentru fiecare pixel. Există o mare varietate de formate ale imaginilor,
funcție de numărul de componente de culoare, domeniul de valori al acestora, gradul și
modalitatea de compresie etc.
Prelucrarea imaginilor presupune modificarea valorilor culorilor pixelilor prin diverse
metode și folosind o multitudine de operatori și algoritmi. De cele mai multe ori, aceasta are ca
scop:
o îmbunătățirile calității imaginilor (sporirea claritații, eliminarea zgomotului);
o scoaterea în evidență a anumitor detalii de interes (identificarea de muchii și
contururi semnificative, separarea unor obiecte din imagine de fundal);
o obținerea de diverse informații legate de caracteristicile imaginilor supuse
prelucrării.
Procesarea informațiilor conținute într-o imagine este strâns legată de procesarea de
semnale în general. Rezultatul aplicării unui algoritm de prelucrare a imaginilor poate fi o nouă
imagine sau un set de valori ale unor parametri sau caracteristici ale imaginii.
Imaginile se găsesc cel mai adesea sub forma unor fișiere în format binar. În cel mai
simplu caz, când nu se aplică algoritmi de compresie, imaginile conțin câte o valoare sau un set
de valori numerice pentru fiecare pixel constituent. Aceste valori sunt utilizate de programele de
prelucrare și afișare a imaginilor pentru a identifica și compune culorile pixelilor corespunzători.
Proiectul de licență are ca scop personal deprinderea de cunoștinte legate de limbajul de
marcare utilizat pentru crearea paginilor Web ce pot fi afișate într-un browser, numit HTML, c ât
și CSS, JavaScript și nu în ultimul rând o aprofundare a domeniul ce se ocupă cu prelucrarea de
imagine.
.
1
Brînză Cătălin – Mihai
Capitolul 2. Fundamente teoretice
2.1. Prelucrare de imagine
2.1.1. Scurt istoric
Prelucrarea de imagine s-a născut datorită ideii și necesitații de a înlocui observatorul
uman printr-o mașină de aceea mai este cunoscută și sub denumirea de Analizarea și manipularea
imaginilor cu ajutorul unui computer. Acest pas de manipulare și analiză include îmbunătățirea
imaginii și rezumarea datelor sau imaginile sunt analizate pentru a găsi reguli care nu sunt găsite
de ochiul uman. De exemplu, meteorologii folosesc această procesare pentru a analiza
fotografiile prin satelit.
2.1.2. Ce reprezintă îmbunătățirea imaginilor?
Îmbunătățirea imaginilor, poate fi considerată ca o parte a procesului în sine, denumită
preprocesare. Scopul principal al îmbunătățirii imaginilor este acela de a accentua anumite
caracteristici pentru analiza sau redarea acestora (pentru prelucrări ulterioare).
Metodele de îmbunătățire a imaginilor pot fi împărțite în două categorii și anume: metode
în domeniul spațial care se bazează pe transformări aplicate direct pixelilor dintr-o imagine și
metode în domeniul frecvențelor care folosesc transformata Fourier a unei imagini.
2.1.3. Noțiunea de zgomot
Noțiunea de zgomot poate fi definit ca orice proces (n) care afecteaza imaginea (f) și nu
face parte din scenă (semnalul inițial –s ). O transpunere sub formă de formulă a modelului
zgomotului auditiv este:
f(i,j) = s(i,j) + n(i,j)
Zgomotul este o informație nedorită care deteriorează calitatea unei imagini. Zgomotul
din imaginile digitale are multe surse, fiecare pas din procesul de achiziție introducând
perturbații (semnale false). Cauze pentru apariția zgomotului în imagini sunt multiple, de
exemplu rezoluția unui senzor de la aparatul foto sau digitizarea semnalului video (cuantizarea
nivelelor de culoare intensitate). [15]
2.1.4. Tipuri de zgomot
Zgomotul îl putem clasifica în două tipuri: sistematic și aleator. Zgomotul sistematic este
un semnal periodic indus de alte semnale electrice, astfel zgomotul periodic este detectat prin
aplicarea analizei Fourier, iar cele aleatoare sunt eliminate sau diminuate prin tehnici de analiză
spațială (operații de netezire).
În imaginile uzuale, zgomotul aleatoriu poate fi modelat prin distribuție gaussiană, uniformă sau
de tip sare și piper care este în general cauzat de funcționarea proastă a celulelor din senzorii
camerelor, erori ale locațiilor de memorie, erori de sincronizare în procesul de digitizare, erori pe
canalul de comunicație (pierdere de biți).
2
Capitolul 2.Fundamente teoretice
2.1.5. Operațiuni spațiale (bazele filtrării spațiale)
Spre deosebire de operațiunile punctuale, operațiunile spațiale se realizează asupra
pixelilor dintr-o vecinătate din imaginea inițială și valorile corespunzătoare ale unei subimagini
de aceeași dimensiune cu vecinătatea aleasă. Subimaginea este numită filtru, mască, nucleu,
fereastră. Valorile filtrului se numesc coeficienți sau ponderi. Operațiile de filtrare care se aplică
direct asupra pixelilor se mai numesc filtrări spațiale, pentru a le deosebi de tehnicile Fourier
care sunt referite ca filtrări în domeniul frecvențelor.
Filtrările spațiale se pot clasifica după mai multe criterii:
a) După efectul și destinația lor:
– pentrul eliminarea zgomotelor ;
– pentru netezirea(estomparea) detaliilor(bluring/smoothing);
– pentru accentuarea detaliilor (sharpening);
– pentru detecția muchiilor.
b) După structura și modul de aplicare:
– liniare, se aplică o operație liniară asupra imaginii (de obicei
operația de convoluție);
– neliniare, se aplică operații neliniare asupra imaginii.
Figura 1. Mecanismul aplicării unei măști (filtrare spațială) [15]
Filtrele de accentuare a contururilor: această operație de accentuare a conturu rilor se
utilizează în scopul punerii în evidență a liniilor și arcelor conținute într-o imagine. Deci prin
accentuarea contururilor se pun în evident detaliile dintr-o imagine.
Aspecte legate de contururi:
3
Brînză Cătălin – Mihai
➔conturul reprezintă o schimbare a nivelelor de gri cu o anumită lungime și o localizare
precisă;
➔variația nivelului de gri de-a lungul conturului este, dar variația la traversarea conturului
este semnificativă;
➔conturul are o direcție care este măsurabilă (direcția tangentei la contur).
Estomparea unei imagini se obține în domeniul spațial prin mediere, operație ce este
similară integrării. Prin urmare, accentuarea contururilor prin tehnici spațiale se obține prin
operatori de derivare spațială.
2.1.6. Domeniul frecvențelor
Această reprezentare își are rădăcinile în tehnica matematică de analiză a seriilor Fourier,
în care, orice funcție periodică poate fi exprimată ca o sumă de sinusuri și/sau cosinusuri de
frecvențe diferite, fiecare termen multiplicat cu coeficienți diferiți. Chiar și funcții care nu sunt
periodice (dar a căror arie sub curbă este finită ) pot fi exprimate ca o integrală de sinusuri și/sau
cosinusuri multiplicați cu o funcție de ponderare. Formularea, în acest caz, este transformata
Fourier, iar utilitatea ei este și mai mare decât a seriilor Fourier în majoritatea problemelor
practice. Ambele reprezentări împărtășesc caracteristica importantă că o funcție, exprimată fie
printr-o serie Fourier, fie printr-o transformată Fourier, poate fi reconstruită complet printr-un
proces invers, fără pierderi de informație. Acesta este una dintre cele mai importante
caracteristici ale acestor reprezentări pentru că permit lucrul în „domeniul Fourier ” și apoi
întoarcerea în domeniul inițial fără a pierde informație. [15]
În cele din urmă, utilitatea seriilor Fourier și a transformatei Fourier în rezolvarea de
probleme practice, le-a făcut utilizate pe scară largă și studiate ca și instrumente fundamentale.
Apariția calculului digital și descoperirea unui algoritm rapid de transformare Fourier (Fast
Fourier Transform – FFT) la sfârșitul anilor 1950, au revoluționat domeniul procesării
semnalelor. Aceste două tehnologii de bază au permis pentru prima dată procesări practice și
interpretări semnificative pentru o serie de semnale de importanță umană și industrială, de la
monitoare medicale și scannere, la comunicații electronice moderne.
2.2. Ce sunt WebSocket-urile?
HTML5 WebSocket reprezintă primul upgrade important din istoria comunicațiilor Web.
Înaintea WebSocket-ului, toate comunicațiile dintre clienții web și serverele erau realizate doar
utilizând protocolul HTTP. Acum se pot transfera date în mod dinamic utilizând conexiunea cu
un WebSocket care este întotdeauna pregătit pentru realizarea schimburilor de mesaje
bidirecționale într-un mod simultan.
Este o nouă modalitate pentru comunicarea clienților cu serverul și viceversa, fără a
încărca vreun protocol HTTP utiliz ând propriul protocol de comunicare. Ultima versiune este
RFC 6455. Versiunile anterioare ale acestui protocol s-au dovedit a avea câteva proleme de
securitate și atât timp cât erau implementate în câteva browsere precum Opera, nu erau activate
automat. Noile versiuni ale acestui protocol au îmbunătățit aceste probleme și browserele actuale
lucrează cu suport.
Pe lângă posibilitatea de a avea propriul protocol, mai are unul care poate să fie folosit de
aplicațiile web să deschidă și să închidă conexiuni și să trimită mesaje utilizând această
4
Capitolul 2.Fundamente teoretice
conexiune. Aceasta este numită WebSockets API și sunt definite în specificațiile W3C.
Cu WebSocket-urile se pot realiza comunicații bi-direcționale între server și client fără o
încărcare a memoriei așa cum o fac metodele obișnuite ale protocolului HTTP. Acestea sunt mult
mai rapide, mult mai scalabile și robuste, cu performanțe crescute a aplicațiilor web ce se vor a fi
rulate în timp real. În practică, conform anumitor analize făcute de “The Kaazing Corporation”
acestea ar putea reduce dimensiunea traficul headerelor de la 500:1 la 1000:1 și reducând latența
cu 3:1. Acestea reprezentând îmbunătățirea serioasă a performanțelor, mai ales pentru aplicațiile
ce trebuie rulate în timp real. [4]
2.2.1. Ce înseamnă WebSocket-urile pentru IT?
Presiunea pentru a construi aplicații care pot comunica în timp real au premeditat apariția
WebSocket-ului. Soluțiile precum AJAX și COMET ce rulau peste protocolul HTTP și astfel
simulând interacțiunea de timp real, nu sunt tocmai adecvate pentru ca ele utilizau serverele
HTTP într-un mod în care acestea nu au fost niciodată construite pentru asa ceva, cauzând
blocarea masivă a resurselor. Odată cu apariția aplicațiilor web dinamice, costul resurselor a
crescut foarte tare. De aceea, odată cu apariția WebSocket-urilor s-a putut realiza o scădere
drastică de resurse utilizate pe partea de server. Sunt foarte multe exemple unde aplicațiile de tip
real-time bazate doar pe protocolul HTTP erau distribuite pe sute de servere, dar odată cu
portarea lor pe serverele utilizate prin WebSocket-uri au fost înlocuite cu doar două sau trei
servere, reducând masiv costul și numărul mare de servere folosite. [4]
2.2.2. Ce înseamnă WebSocket-urile pentru arhitecți și developeri?
WebSocket-ul însăși este independent bazat pe protocolul TCP, dar este construit pentru a
suporta oricare alt protocol care în mod normal ar rula pe o conexiune de tip TCP. Cea mai bună
modalitate de a ne da seama ce reprezintă WebSocket-ul, este un șablon deasupra căruia oricare
protocol poate rula. API-ul WebSocket-ului suportă abilitatea de a defini sub-protocoale precum
XMPP, STOMP și AMQP. În acest fel developerii nu mai trebuie sa se gândească la termenii
paradigmei de trimitere – recepționare a mesajelor, ci ei pot selecta cel mai bun protocol pentru
tipul propriu de aplicație pe care-l dezvolta. Singura necesitate a browserelor este de a rula o
librărie JavaScript care poate interpreta legătura conexiunii cu un WebSocket. [4]
Conexiunea WebSocket-ului este inițializată utilizând protocolu HTTP. Serverele HTTP
interpretează conexiunea WebSocket-ului ca fiind o cerere de tip upgrade, putând astfel fi un
mediu HTTP și putând folosi infrastructura pentru a adăuga funcționalitatea de a rula protocoale
mult mai avansate, putând astfel să se realizeze comunicarea bi-direcțională între client și server.
2.2.3. Cum sunt utilizate?
Înainte ca serverul și clientul să înceapă a trimite și primi mesaje, trebuie să se stabilească
o conexiune înainte de toate. Aceasta este realizată prin stabilirea unei “handshake” ( a unei
stranger de mână), unde clientul trimite o cerere pentru a se conecta, și dacă serverul dorește, îi
va trimite un răspuns acceptând conexiunea. Specificațiile protocolului a fost nevoit să se asigure
ca atât protocolul HTTP de bază al clienților cât și WebSocket-ul pot sa opereze pe același port.
Acesta este motivul pentru care “handshake-ul” realizează conexiunea serverului de la un
protocol HTTP la unul de tip WebSocket. [5]
5
Brînză Cătălin – Mihai
Un exemplu de cum s-ar putea realiza “handshake-ul” este următorul:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, super-chat
Sec-WebSocket-Version: 13
2.2.4. De ce avem nevoie de WebSocket-uri?
Avem nevoie să utilizăm WebSocket-urile pentru a crea aplicații ce rulează pe browserele
clientului pentru a comunica cu serverele în timp real. La momentul actual există două metode ce
sunt disponibile pentru a realiza acest lucru:
Prima metoda este rezervată aplicațiilor pentru retragerea constantă a oricărei date noi.
Dacă există o dată nouă, atunci aceasta este trimisă către client.
2.2.5. Câteva avantaje ale utilizării WebSocket-urilor
Realizează o cumunicare completă bi-direcțională pentru Web, efectuând comunicarea
dintre client și server în ambele direcții în același timp. Developerii au fost nevoiți sa găsească o
modalitate de a executa comunicări simultane utilizând o tehnică numită “polling” și “long-
poling”. Un alt avantaj este creșterea eficienței comunicației dintre client și server. În mod
tradițional, aplicațiile web necesită ca userii să realizeze o conexiune cu un server utilizând
protocolul HTTP. Doar utilizând doi bytes ca frame, poate înlocui sute de bytes ai headerelor
HTTP. În mod normal, un număr mare de useri sunt implicați în utilizarea resurselor serverului
atunci când se conectează la acesta. WebSocket-urile dau voie developerilor sa reducă numărul
mare de legături nefolositoare utilizând o rata de 1000:1. Utilizând în continuu “polling”, latența
este redusă dramatica. [5]
2.3. Tehnologii utilizate
Pentru cercetătorul care descoperea libertatea de comunicare și oferta internațională de
Internet, multitudinea de biblioteci, reviste și grupuri de dezbatere, accesul la Internet seamănă
cu un vis care nu se mai termină, vacanța pe care urmează să o faci în Europa sau Asia la distanțe
foarte mari prin site-uri unde sunt prezentate locuri frumoase și utilizatorul stând în fața
calculatorului își aduce lumea cea mare în afara calculatorului și mică la calculator.
Prin Internet înțelegem de obicei ansamblul rețelelor de calculatoare interconectate din
întreaga lume. De fapt, specialiștii susțin că Internetul nu este o rețea ci un ansamblu de reguli,
protocoale de comunicație, care permit transferul de date între rețele de pe glob, accesul la
informațiile stocate în calculatoarele acestora.
Accesul la Internet este atât modul de conectare în rețea, cât mai ales, accesul la
informația ce se vehiculează prin calculatoarele legate în rețea, posibilitatea de comunicație cu
specialiștii din toată lumea întreagă.
Internetul este o gigantică rețea de calculatoare, mai precis, o rețea de rețele de
6
Capitolul 2.Fundamente teoretice
calculatoare. Unele dintre aceste calculatoare oferă o diversitate de servicii pentru oameni.
Dezvoltarea internetului a fost foarte rapidă, în anul 1985, aproximativ 2000 de
calculatoare erau legate la Internet. In momentul de față există zeci chiar sute de milioane de
calculatoare conectate în întreaga lume, care permit accesul în rețea a unui număr foarte mare de
oameni. În fiecare an, comunitatea primește milioane de noi utilizatori care doresc să utilizeze
internetul pentru a cunoaște informații noi din domenii diferite.
Internetul în România a pătruns relative încet, multă vreme fiind considerat un lux inutil.
Chiar și acum, pentru uz personal, mai ales datorită costurilor foarte mari ale serviciilor
telefonice, este destul de puțin utilizat. Din punct de vedere al infrastructurii lucrurile au avansat
destul de mult, din punct de vedere al resurselor informatice disponibile evoluția este destul de
greoaie.
Majoritatea companiilor și chiar unele structur i administrative au înțeles prezența în
Internet că este foarte important, încă nu există resurse și depozite informaționale românești
semnificative. Din acest motiv traficul observat în rețeaua românească este mai mult de aducere
de informații din exterior decât de export de informații în cadrul țării.
În contextul internațional actual de afaceri, academic și tehnologic, fenomene ca globalizarea și
liberalizarea accesului la informație dinamică și nivelul de performanță al dezvoltărilor în
domeniul comunicațiilor și al calculatoarelor, sunt deja lucruri comune și legate unele de altele.
Dincolo de granițe, în restul omenirii, Internetul a devenit deja cea mai comodă sursă de
informație, în timp ce ceea ce este disponibil și în România pe Internet este fie vechi, fie
incorect, fie lipsește prin costurile ridicate.
Pentru a ne da seama ce ne rezervă viitorul în privința rețelei Internet, trebuie să înțelegem
tipurile de tehnologii elaborate de experții implicați în dirijarea rețelei și pentru utilizarea
internetului cât mai ușor cu putință.
– Obiecte
Creatorii paginilor Web nu mai sunt limitați de texte și grafică, astfel încât putem fi siguri
că vom găsi o mulțime de elemente interesante pe Web și cu o viteză foarte mare de accesare.
Câteva inovații recente permit chiar și distribuirea de programe prin Web.
– Mesaje e-mail
Nu mai suntem limitați la mesaje simple de text. Limbajul HTML permite formatarea
acestora, cu caractere adline și cursive, și cu diferite formate de paragraf. Mai mult decât atât,
putem atașa mesaje de e-mail, imagini și alte elemente multimedia.
– Securitate
Specialiștii din spatele rețelei Internet lucrează pentru a securiza comerțul on-line,
oferind metode de protejare a tranzacțiilor din multitudinea de domenii de activitate. Ei creează
un mediu mai sigur pentru copiii care se joacă pe Web, furnizând criterii de evaluare a paginilor,
și asigură securitatea rulării aplicațiilor distribuite, prin autentificări de cod și o securitate foarte
bine pusă la punct.
2.3.1. Pagini Web și Servere Web
Construcția World Wide Web este pe baza unui protocol numit Hypertext Transfer
Protocol ( HTTP ). HTTP este un protocol mic și rapid care se potrivește foarte bine sistemelor
informatice multimedia și distribuite în salturile între site-uri. [14]
Web-ul constă în pagini cu informații de pe gazde care rulează software de tip server Web. Gazda
este de multe ori identificată cu serverul Web, lucru care nu este corect. Serverul Web este un
software, nu calculatorul în sine.
7
Brînză Cătălin – Mihai
Un Web server este un program care furnizează pagini Web la cerere. Când un utilizator
de la o adresă IP specifică și solicită un anumit fișier, serverul Web încearcă să obțină acel fișier
și să-l trimită înapoi utilizatorului.
Fișierul solicitat poate fi codul sursă HTML al unei pagini Web, o imagine GIF, un fișier
Flash, un document XML, sau un fișier A VI. Browserul Web este cel care determină ceea ce
trebuie cerut, nu serverul Web.
Conexiunile la serverul Web stabilesc pe măsură ce sunt accesate, se solicită o cerere a
unei pagini de la un server Web, o conexiune IP este stabilită prin Internet între gazda solicitantă
și gazda pe care rulează serverul Web. Pagina Web cerută este transmisă prin acea conexiune, iar
aceasta este întreruptă de îndată ce pagina este primită (de exemplu, imagini GIF sau JPG).
Pe un același host pot rula mai multe aplicații de Internet, de exemplu un server Web, un
server FTP, un server DNS și un server de mail SMTP POP3 pot rula în același timp.
Fiecărui server îi este atribuit un port pentru a asigura că fiecare server va răspunde
numai cererilor din partea clienților corespunzători.
Majoritatea serverelor folosesc un set de porturi predefinite. Serverele Web folosesc de
obicei portul 80, dar acesta poate fi schimbat. Pot fi instalate pe porturi nestandard pentru a fi
ascunse, și de asemenea, pot fi instalate mai multe servere Web pe un singur calculator
asociindu-le porturi diferite. [14]
Internetul reprezintă o mulțime globala de calculatoare interconectate, similar unei rețele
locale, dar la o scară mult mai largă. Elementul primar al Internet-ului este World Wide Web
(cunoscut sub denumirea de Web sau WWW ). WWW este un suport pentru text, grafică,
animație și sunet. Documentele destinate Web-ului sunt cunoscute sub numele de pagini Web.
Pentru a înțelege mai bine World Wide Web se pornește de la modul în care este
organizată informația în mediile tipărite. Aceste medii reprezintă un model adecvat pentru web și
modul său de organizare.
Paginile Web oferă posibilitati multiple și interesante: paginile de informații se pot regăsi
pe calculatoare răspândite în lumea întreagă. Paginile în sine pot fi documente foarte complexe,
interesante și atractive. Paginile Web sunt memorate pe HDD unui server specializat și gestionate
printr-un software special și sunt regasite și afișate prin intermediul navigatoarelor (browser).
Navigatorul Web afișează paginile de Web prin interpretarea unor marcatori definiți cu
ajutorul unui limbaj special denumit HTML (HyperText Markup Language) utilizați pentru a
codifica pagina de Web cu informația de afișat. Marcatorii au diferite semnificații. De exemplu
aceștia semnifică modul în care vor fi așezate diversele părți ale paginii sau stabilesc legături
între documente/fișiere. Tipic, o pagină de Web este legată de o diversitate de fișiere cum ar fi
fișiere text, grafice sau multimedia. Mecanismul prin care sunt create căile de acces între
documente este denumit hipertext, prezentat anterior. Atunci când utilizatorul acționează prin
click de mouse asupra unei legături, cum ar fi o porțiune de text, un element grafic, etc,
navigatorul încarcă fișierul la care punctează această legătură și îl afișează. Legăturile din cadrul
textului sunt ușor de identificat deoarece majoritatea navigatoarelor, implicit, colorează diferit de
restul textului aceste legături și le subliniază.
Un site Web este definit ca o colecție coerentă de informații prezentată sub forma unor
pagini Web, fișiere multimedia, documente și de alte tipuri, între care există legături.
Intr-un site bine proiectat toate celelalte pagini punctează către pagina principală,chiar dacă
navigatoarele moderne au butoane pentru acest lucru.
Atunci când se realizează un site Web aceste fișiere sunt păstrate, în mod uzual, într-un
director sau o colecție de directoare în HDD local și este ferit cu numele de site local .Serverul
Web este dedicat memorării, transmiterii și regăsirii paginilor de Web și a fișierelor legate de
acestea.
8
Capitolul 2.Fundamente teoretice
Prin publicarea unui site local (upload), directorul, împreună cu conținutul său, este
transferat la server-ul Web care conține Software-ul prin care site-ul este transmis navigatoarelor
Web ale calculatoarelor conectate la Internet. Odata publicat, site-ul se transformă din site local
în site Web, iar interacțiunea utilizatorului cu el are loc similar modului descris în Figura 2.
Deși cea mai mare parte a informațiilor din World Wide Web este stocată în pagini Web scrise
folosind limbajul HTML, există un număr destul de mare de documente provenite din alte tipuri
de servicii de publicare a informațiilor din Internet. [14]
Figura 2. Comunicare navigator web cu server web
2.3.2. Pagini Web Statice și Dinamice
HTML
HTML este o formă de marcare orientată către prezentarea documentelor text pe o
singură pagină, utilizând un software de redare specializat, numit agent utilizator HTML, cel mai
bun exemplu de astfel de software fiind browserul web. HTML furnizează mijloacele prin care
conținutul unui document poate fi adnotat cu diverse tipuri de metadate și indicații de redare.
Indicațiile de redare pot varia de la decorațiuni minore ale textului, cum ar fi specificarea
faptului că un anumit cuvânt trebuie subliniat sau că o imagine trebuie introdusă, până la
scripturi sofisticate, hărți de imagini și formulare. Metadatele pot include informații despre titlul
și autorul documentului, informații structurale despre cum este împărțit documentul în diferite
segmente, paragrafe, liste, titluri etc. și informații cruciale care permit ca documentul să poată fi
legat de alte documente pentru a forma astfel hiperlink-uri (sau web-ul). [3]
HTML este un format text proiectat pentru a putea fi citit și editat de oameni utilizând un
editor de text simplu. Totuși scrierea și modificarea paginilor în acest fel solicită cunoștințe
solide de HTML și este consumatoare de timp. Editoarele grafice (de tip WYSIWYG) cum ar fi
Macromedia Dreamweaver , Adobe GoLive sau Microsoft FrontPage permit ca paginile web sa
fie tratate asemănător cu documetele Word, dar cu observația că aceste programe generează un
9
Brînză Cătălin – Mihai
cod HTML care este de multe ori de proastă calitate.
Paginile HTML sunt formate din etichete sau tag-uri și au extensia „.html” sau „.htm”. În
marea lor majoritate aceste etichete sunt pereche, una de deschidere <eticheta> și alta de
închidere </eticheta>, mai există și cazuri în care nu se închid, atunci se folosește <eticheta />.
Navigatorul web interpretează aceste etichete afișând rezultatul pe ecran. HTML-ul este un
limbaj care nu face deosebire între litere majuscule și minuscule. [3]
Pagina principală a unui domeniu este fișierul “index.html”. Această pagină este setată a
fi afișată automat la vizitarea unui domeniu.
Un exemplu de pagina HTML cu titlul Prezentare și conținutul Licență arată in felul
următor:
<html>
<head>
<title> Prezentare </title>
</head>
<body> Licență </body>
</html>
JavaScript
JavaScript este un limbaj de programare orientat obiect bazat pe conceptul prototipurilor.
Este folosit mai ales pentru introducerea unor funcționalități în paginile web, codul JavaScript
din aceste pagini fiind rulat de către browser. Limbajul este binecunoscut pentru folosirea sa în
construirea site-urilor web, dar este folosit și pentru accesul la obiecte încastrate în alte aplicații.
În ciuda numelui și a unor similarități în sintaxă, între JavaScript și limbajul Java nu există nicio
legatură. Ca și Java, JavaScript are o sintaxă apropiată de cea a limbajului C, dar are mai multe
în comun cu limbajul Self decât cu Java.
Cea mai des întâlnită utilizare a JavaScript este în scriptarea paginilor web. Programatorii
web pot îngloba în paginile HTML script-uri pentru diverse activități cum ar fi verificarea
datelor introduce de utilizatori sau crearea de meniuri și alte efecte animate.
Browserele rețin în memorie o reprezentare a unei pagini web sub forma unui arbore de
obiecte și pun la dispoziție aceste obiecte script-urilor JavaScript, care le pot citi și manipula.
Arborele de obiecte poartă numele de Document Object Model sau pe scurt DOM.
O tehnică de construire a paginilor web tot mai întâlnită în ultimul timp este AJAX,
abreviere de la „Asynchronous JavaScript and XML ”. Această tehnică constă în executarea de
cereri HTTP în fundal, fără a reîncărca toata pagina web, și actualizarea numai anumitor porțiuni
ale paginii prin manipularea DOM-ului paginii. Tehnica AJAX permite construirea unor interfe țe
web cu timp de răspuns mic, întrucât operația de încărcare a unei pagini HTML complete este în
mare parte eliminată. [2]
Tehnologii pe parte de Client
Majoritatea browserelor noi permit folosirea și a altor tehnologii, dintre care cele mai
importante sunt:
➢cascading Style Sheets (CSS) este un standard pentru formatarea elementelor unui
document HTML. Stilurile se pot atașa elementelor HTML prin intermediul unor fișiere
externe sau în cadrul documentului, prin elementul <style>;
➢appleturi Java;
10
Capitolul 2.Fundamente teoretice
➢macromedia Flash.
URL-uri
Formatul unei locații din Internet este numit URL(Uniform Resource
Locator – Descriptor Uniform de Resurse). Structura completă a unui URL este urmatoarea:
Protocol://nume-calculator-gazda:port/cale-director/resursa
Protocolul sau serviciul este reprezentat de regulile care guvernează transferul datelor în
rețea. În practică se utilizează următoarele protocoale:
➢file – specifică un URL local;
➢http – indică adresa Internet a unei pagini Web sau altă resursă;
➢ftp – utilizat pentru adresarea în Internet a fișierelor prin intermediul protocolului de
transfer de fișiere FTP;
➢gopher – indică adresa URL a unui director Gopher, reprezintă un sistem utilizat pentru
localizarea și tranferul informațiilor de indexare a numelor fișierelor în Internet;
➢telnet – permite conectarea în timp real la un alt calculator în Internet și utilizarea acestuia
ca și cum ar un calculator local.
Portul este reprezentat printr-un număr și este specific fiecărei aplicații. Majoritatea
aplicațiilor de rețea utilizează porturi pentru comunicare. Pe un calculator pot exista mai multe
aplicații de rețea, fiecare aplicație utilizând un port distinct.
Numele resursei este reprezentat de numele fișierului referit. Aceasta poate fi o pagină
Web, un fișier multimedia, un document , un fișier executabil.
2.3.3. OpenCV
2.3.3.1. Ce este mai exact OpenCv?
OpenCV (Open Source Computer Vision Library) este o viziune open-source pe
calculator și o bibliotecă de software pentru învățarea mașinilor. OpenCV a fost construit pentru
a oferi o infrastructură comună pentru aplicațiile de vizionare pe calculator și pentru a accelera
utilizarea percepției mașinilor în produsele comerciale. Fiind un produs cu licență BSD, OpenCV
facilitează utilizarea și modificarea codului de către companii.
Are interfețe C ++, C, Python, Java și MATLAB și suportă 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. Un CUDA full-featured și interfețe
OpenCL sunt dezvoltate în mod activ chiar acum. [6]
Una dintre țintele OpenCV-ului este de a realiza o infrastructură de procesare de imagini
foarte simplă de folosit, pentru a ajuta developerii sa construiască aplicații sofisticate foarte
rapid. Această librărie conține peste 500 de funcții ce ocupă foarte multe zone ale acestui
domeniu, cum ar fi: inspectarea produselor industriale, procesarea imaginilor medicale,
securitate, interfața cu utilizatorul, calibrarea camerelor și a roboților. Deoarece procesarea de
imagini și mașinile de învățare sunt mână în mână, OpenCV-ul conține pe lângă acestea și un
MLL (Machine Learning Library). Această sublibrărie este focusată pe grupare și recunoaștere.
11
Brînză Cătălin – Mihai
2.3.3.2. Cum a aparut OpenCV-ul?
OpenCV-ul a fost construit la inițiativa unui angajat de la Intel, pentru construirea
aplicațiilor ce puteau profita de avantajul puterii CPU-ului, astfel Intel-ul în timp a publicat
multe proiecte incluzând urmărirea în timp real și afișarea pereților 3D. Unul din autorii ce
lucrau pentru Intel când vizita universitățile a remarcat faptul că unele dintre cele mai de top
universități precum MIT Media Lab, își construiseră propria infrastructura de procesare de
imagini, cod ce a fost distribuit de la un student la altul pentru a-și crea propriile aplicații .
Această librărie a fost construită ca o modalitate pentru infrastructura procesării de
imagini să fie universal valabilă pentru to ți developerii. [6]
Țintele acestei librării au fost următoarele:
➢cercetare avansată în procesarea de imagini prin utilizarea nu numai a unei versiuni a
librăriei open-source ci și a uneia în care codul era optimizat pentru metodele basic;
➢diseminare cunoștințelor prin asigurarea unei infrastructuri comune pentru care
dezvoltatorii ar putea crea aplicații de procesare de imagini, astfel încât codul sa fie mai ușor de
citit și transferabil;
➢aplicații comerciale de procesare a imaginilor făcându-le portabile, cu o performanță
optimizată a codului în mod gratuit, folosind doar o licență ce nu necesită cumpărarea
aplicațiilor.
2.3.4. Raspbian
Raspbian este un sistem de operare gratuit optimizat pentru setul de instrucțiuni al
arhitecturii ARMv6, pe care se bazează microcalculatorul Raspberry Pi. Aceasta derivă din
sistemul de operare Debian 7 “ Wheezy”. Acest sistem de operare oferă peste 35000 de pachete
software precompilate și ușor de instalat, optimizate pentru a rula pe hardware-ul ARM 11 al
Raspberry Pi. Pachetul de bază Raspbian conține un mediu de lucru LXDE, managerul de
ferestre Openbox, browser-ul web Midori, instrumente de dezvoltare software (IDLE, Stratch) și
exemple de coduri sursă pentru funcții multimedia.
Sistemul de operare Raspbian este un sistem de tip “ hard-float”, adică acesta operează în
virgulă mobilă prin emulare hardware. Astfel, nu se oferă suport pentru folosirea blocului de
procesare vectorială în virgulă mobilă. [1][9]
Sistemul de operare Debian pentru arhitecturi ARM este compilat pentru setul de
instrucțiuni ARM versiunea 4. Arhitectura de tip hard-float Debian este compilată pentru
ARMv7. Arhitectura procesorului ARM al lui Raspberry Pi este de tip ARMv6. Tehnic, Raspbian
este conceput cu setările de compilare ajustate pentru a produce cod în virgulă mobilă emulat
hardware optimizat pentru Raspberry Pi. Pentru a ajuta această optimizare, se mai folosește și
interfața binarăde aplicație în virgulă mobilă si arhitectura de microprocesor ARM pe 32 de biți
cu funcțiile arhitecturii ARMv6. [1] [9]
În versiuni mai recente ale Raspbian, multe dintre elementele semnificative necesare ale
lui Debian Wheezy au fost portate pentru arhitectura ARMv6, deși distribuția oficială necesită
arhitectura ARMv7. Astfel, performanța pentru aplicații care folosesc operații aritmetice de
aritmetică în virgulă mobilă este crescută deoarece sistemele de operare precedente pentru
Raspberry Pi folosesc setări de tip” soft float”, mai puțin eficiente, prin care operațiile aritmetice
în virgulă mobilă native pentru arhitectura ARMv6 sunt emulate software. [1][9]
12
Capitolul 2.Fundamente teoretice
Figura 3. Interfața Raspbian
Sistemul de fișiere este standard pentru un sistem derivate din Linux. Aceasta este de tip
ierarhic, împărțit în directoare, dintre care reamintim printre cele mai importante:
o /bin – în care se instalează programele de utilizator ;
o /boot – în care se află fișierele necesare la pornire;
o /dev – conține fișiere speciale care reprezintă dispozitivele sistemului;
o /etc – aici se regăsesc fișierele de configurare a sistemului;
o /etc/init.d – conține scripturile pentru pornirea serviciilor;
o /home – directorul utilizatorului;
o /home/pi – directorul utilizatorului pi (root);
o /lib – driverele și modulele kernel;
o /proc – un director virtual care conține informațiile legate de procesele care
rulează pe sistemul de operare;
o /sys – un director special pentru Raspberry Pi care conține driverele pentru
dispozitivele hardware;
o /usr – conține programe și date utilizabile de către toți utilizatorii;
o /usr/src – sursele sistemului Linux;
o /var – fișierele pentru procesare (similar unui buffer) și loguri de sistem.
13
Brînză Cătălin – Mihai
Capitolul 3. Proiectarea aplicației
3.1. Descrierea aplicației
În această lucrare este prezentată proiectarea unei aplicații cu ajutorul placuței Raspberry
Pi Model B, care se ocupă cu procesarea și prelucrarea de imagine, ce are ca scop aplicarea mai
multor filtre asupra unei imagini captate de la un live streaming oferit de o cameră web ce vine
conectată la plăcuță. Sursa imaginilor va fi setată de fiecare utilizator, captând orice imagine
dorește din mediul în care se află.
Aplicația conține un modul pentru cameră care este apelat în fișierul principal al
aplicației oferind astfel live streaming-ul dorit. Fiecare persoană care va utiliza aplicația va putea
aplica la alegere orice filtru dorește asupra imaginii captate și sa o salveze in computer.
3.2. Funcțiile aplicației
Această aplicație realizată cu ajutorul placuței Raspberry Pi Model B, la care este atașată
o cameră web, va oferi un live streaming de la care vom capta un frame (va rezulta o imagine),
pe care o vom salva în computerul propriu și o vom reîncărca ulterior pentru a o prelucra cu
ajutorul funcțiilor implementate în JavaScript. Imaginile modificate vor putea fi salvate la rândul
lor și analizate în detaliu dupa caz.
3.3. Stabilirea componentelor hardware
În stabilirea și alegerea componentelor hardware, a fost necesară o analiză mai
amănunțită pentru ca la final să avem parte de rezultate de o înaltă calitate. Acestea fiind spuse,
componentele alese sunt următoarele:
➔Raspberry Pi Model B
➔Camera Web LOGITECH C270
➔SanDisk Adapter
➔MicroSDHC
➔Cablu de rețea STP, Cat 5e
➔Cablu USB tip C (alimentare plăcuță)
➔Cablu HDMI / Laptop HP (pentru vizualizarea interfetei)
3.4. Descrierea componentelor hardware
3.4.1. Camera Web LOGITECH C270
În ceea ce privește live streaming-ul și captarea unei imagini pentru realizarea acestui
proiect, am ales Camera Web LOGITECH C 270, Figura 4. Una dintre punctele forte care m-au
determinat să aleg această cameră este acela că dacă încăperea din care realizăm un video este
scufundată în lumină obscură, camera Web Logitech își va ajusta automat luminozitatea pentru a
oferi cele mai bune imagini, datorită tehnologiei Logitech RightLight. Camera Web Logitech C
720 este compatibilă la orice PC sau laptop.
14
Capitolul 3.Proiectarea aplicației
Specificațiile camerei web sunt următoarele [13]:
Rezoluție video (pixeli) 1280 x 720
Rezoluție foto Până la 3 MP
Interfața USB 2.0
Microfon inclus DA
Frame rate (fps) 30
Figura 4. Camera Web Logitech C 720
3.4.2. Raspberry Pi
3.4.2.1. Specificații și evoluție
În prezent, există o gamă largă de plăci de dezvoltare embedded optimizate pentru
numeroase aplicații. Un criteriu de selecție a plăcii potrivite este complexitatea aplicației. Dacă
aplicația necesită comunicarea simplă cu periferice (senzori, etc.), atunci plăcile cu
microcontroler Arduino, Netduino, Wiring S, etc. reprezintă soluția optimă. Pentru aplicații de
complexitate crescută, care necesită puterea de calcul al unui procesor ARM pentru a rula
aplicații Linux, alegerea potrivită este un computer pe o singură placă (SBC – Single Board
Computer). Dintre acestea reamintim Beaglebone si Raspberry Pi.
Apariția microcalculatorului Raspberry Pi în anul 2012 a adus domeniul embedded la un
nou nivel. Acesta oferă un mediu facil pentru învățarea programării si dezvoltarea de proiecte
hardware la un preț redus. Dimensiunile acestuia sunt comparative cu cele ale unui card bancar
15
Brînză Cătălin – Mihai
(85.60 mm × 53.98 mm) și a fost creat de către fundația britanică „The Raspberry Pi
Foundation” cu intenția de a promova învățarea programării în școli. Succesul comercial a
acestuia a venit pe fondul unui preț redus de vânzare raportat la performanțele oferite comparativ
cu alte modele existente pe piață (pcDuino de la LinkSprite, APC de la VIA, Cubieboard de la
CubieTech, etc.)
Plăcuța folosită în realizarea proiectului este Raspberry Pi Model B, prezentată în Figura
5, o fotografie pozată și editată de către mine în programul Photoshop CS6. [1]
Figura 5. Raspberry Pi Model B
Raspberry Pi Model B este compus dintr-un SoC fabricat de Broadcom, model
BCM2835, care include un procesor de tip ARM1176JZF-S, funcționând la 700 MHz (printr-o
setare din firmware, acesta este capabil să funcționeze la 1GHz), un GPU VideoCore IV si 256
MB de memorie RAM pentru revizia 1, respectiv 512 MB de memorie RAM pentru revizia 2.
Acesta nu conține un hard disk sau o unitate SSD, folosind în schimb un card de memorie flash
SD pentru boot-are si stocare pe termen lung. Pentru partea de boot-are am folosit un SanDisk
Adapter în interiorul căruia am introdus un MicroSDHC de capacitate 32GB, Figura 6.
MicroSD-ul este un card de memorie flash utilizat pentru stocarea informațiilor , unde
SD este abrevierea de la Secure Digital. Cardurile de acest gen sunt folosite la telefoanele mobile
și la alte dispozitive. Este cel mai mic card de memorie care poate fi cumpărat la 15mm x 11 mm
x 1mm, fiind de aproximativ un sfert din dimensiunea unei dimensiuni normale ale unui card SD.
Există adaptoare ca cel folosit de către mine, care fac posibilă conectarea microSD-urilor la
dispozitive care au sloturi special pentru SD. [1]
16
Capitolul 3.Proiectarea aplicației
Figura 6. Adapter și MicroSD
3.4.2.2. Arhitectura plăcuței Raspberry Pi Model B
În Figura 7 este prezentată o trecere în revistă a conexiunilor interne din Raspberry Pi
modelul B. Aceasta reprezintă diagrama bloc a microcalculatorului. Blocul I/O include interfața
GPIO, interfața DSI pentru conectarea unui monitor extern cu interfață compatibilă, interfața CSI
pentru conectarea unei camere de filmat/ fotografiat și interfețe S-Video și HDMI pentru
conectarea unor dispozitive de afișare externe.
GPIO (General Purpose Input/Output) este un pin de pe un cip a cărui comportament (de
intrare sau de ieșire) poate fi controlat prin programare de către utilizator la rulare. Acest pin nu
are un scop special definit și de obicei este nefolosit. Ideea din spatele GPIO este de a da
posbilitatea unui designer de sisteme integrate de a crea circuite digitale folosind o serie de astfel
de pini și câteva linii de control disponibile pe cip în detrimental creării de circuite digitale
dedicate adiționale.
Pinii GPIO sunt folosite în cipuri (circuite integrate, SoC, FPGA, etc.), cipuri
multifuncționale (codec-uri audio, manageri de putere, cartele video, etc), sisteme pentru
aplicații integrate (Raspberry Pi, Arduino, etc ) în care sunt folosiți pentru a citi valori de la
senzori de mediu (infraroșu, temperatură, orientare, accelerare), pentru a controla motoare în
current continuu, ecrane LCD sau LED-uri.
Pe plăcuța Raspberry Pi există 26 de pini grupați în același bloc numit P1. Dintre aceștia,
8 sunt pini GPIO, restul fiind folosiți pentru protocoale de comunicații (SPI, UART) și pentru
alimentare la 3.3V , 5V și respectiv masa circuitului GND (0V). Nivelul de tensiune disponibil pe
pinii GPIO este de 3.3V , aceștia fiind intoleranți la 5V .
Toți pinii GPIO pot fi reconfigurați pentru a asigura funcțiile alternative, SPI, PWM și
altele. Doar pinii GPIO 14 și 15 pot fi asignați pentru alternativă de UART, având posibilitatea
de a-i reasigna către funcția GPIO pentru a asigura un număr de 17 pini GPIO.
Fiecare funcție este detaliată în fișa tehnică a cipului BCM2835. Fiecare pin GPIO este
capabil de schimbări ale semnalului în nivelul maxim/minim și de executarea întreruperilor.
Histerezisul pe intrare al pinilor GPIO poate fi de tip pornit/oprit, rata de cădere poate fi rapidă
sau limitată iar curentul de sursă și cel absorbit poate fi configurat de la 2 mA până la 16 mA.
17
Brînză Cătălin – Mihai
Aceaste proprietăți se aplică tuturor celor 26 de pini ai blocului P1. [1]
Figura 7. Diagramă bloc Raspberry Pi Model B [1]
3.4.2.3. Sisteme de operare disponibile pentru Raspberry Pi
De la lansara sa, tot mai multe sisteme de operare au fost dezvoltate pentru a fi
compatibile cu arhitectura Raspberry Pi. Dintre acestea amintim Raspbian (o variantă adaptată a
sistemului de operare Debian Wheezy ), RaspBMC (un firmware adaptat pentru aplicații
multimedia), Pidora (o variantă a cunoscutului sistem Fedora), RISC OS (un sistem de operare
derivat din UNIX), Gentoo Linux, FreeBSD, NetBSD, Plan9, Slackware Linux ș.a.m.d . [7]
În general, orice kernel derivat din Linux este compatibil cu arhitectura hardware a
Raspberry Pi. Astfel, Raspberry PI suportă și versiuni neoficiale pentru platformă ale sistemelor
de operare Android și Firefox OS.
Alegerea unui sistem de operare pentru Raspberry Pi poate avea numeroase criterii. Unul
dintre acestea este aplicația pentru care este utilizat microcalculatorul. Aplicațiile curente includ
domenii precum domeniul multimedia, robotica, servere de putere redusă, pentru fiecare existând
sisteme de operare optimizate. [8]
Astfel, pentru aplicații multimedia (sisteme de home entertainment, console de jocuri,
etc.), sistemele de operare recomandate sunt RaspBMC, OpenELEC, XBMC. Pentru aplicațiile
de robotică, cele mai utilizate sisteme sunt Raspbian, datorită pachetului mare de aplicații
precompilate, util în astfel de aplicații, RISC OS. [8]
3.4.2.4. Analiză și alegerea sistemului de operare
Sistemele evidențiate în subcapitolul 3.4.1.3 în cadrul acestei lucrări sunt majoritar
derivate din Linux si astfel, au proprietăți similare. O comparație între ele trebuie să țină cont de
criterii atât obiective, cât si subiective. Dintre criteriile obiective propuse, se regăsesc dificultatea
de punere în funcțiune a sistemului, pachetul de aplicații disponibil, gradul de integrare diverse
aplicații și posibilitatea de dezvoltare a sistemului. Criteriile subiective sunt dependente de
utilizator, printre acestea regăsindu-se criterii precum interfața dintre sistem și utilizator și
dificultatea de utilizare a sistemului.
Pe baza primului criteriu, datorită numeroaselor documentații disponibile pe Internet,
sistemele Raspbian, RISC OS și RaspBMC au un grad redus de dificultate în ceea ce privește
18
Capitolul 3.Proiectarea aplicației
instalarea, pași ce trebuie urmați în general fiind scrierea imaginii sistemului pe cardul SD,
inserarea în slotul SD de pe Raspberry Pi și bootarea normală a sistemului, cu configurările
necesare. Instalarea sistemului ArchLinux prezintă un grad de dificultate crescut, deoarece
utilizatorul trebuie să utilizeze un mediu de tip Terminal pentru a descărca, instala și configura
sistemul, acest lucru nefiind la îndemâna unui utilizator comun. Dificultatea crescută de instalare
contrastează cu performanța Arch Linux, unul dintre cele mai apreciate sisteme Linux.
La capitolul pachetelor de aplicație disponibile, liderul detasat este Raspbian cu peste
35000 de aplicații disponibile, deoarece Raspbian provine din Debian, unul dintre cele mai
utilizate și apreciate sisteme de operare Linux. RaspBMC urmează după, cu peste 20000 de
aplicații, pentru că, deși si acesta derivă tot din Debian, sistemul se adresează în principal
aplicațiilor multimedia, restrângând numărul aplicațiilor folositoare din pachetul inițial. Pentru
Arch Linux sunt disponibile aproximativ 4600 de aplicații, acestea fiind mai bine adaptate
sistemului datorită strânsei legături din cadrul comunității Arch. Date despre pachetele
disponibile pentru RISC OS nu sunt disponibile la data prezentă.
De la lansare, Raspberry Pi este utilizat în tot mai multe aplicații. Dintre acestea, se
regăsesc aplicații precum computer personal (desktop, laptop, tabletă), aplicații multimedia
(centru de divertisment, etc.), aplicații embedded (robotică, sisteme inteligente, etc), ș.a.m.d.
Astfel se pot clasifica în funcție de aplicație și sistemele disponibile.
Pentru utilizarea de tip computer personal, Raspbian si Arch Linux sunt alegerile cele mai
potrivite, datorită pachetelor de aplicații disponibile, a stabilității sistemului si a interfeței facile
cu utilizatorul. Aceste sisteme au fost concepute pentru acest domeniu, corespondențele lor în
domeniul PC fiind deja consacrate. RISC OS este o alternativă bună, fiind dezavantajat de faptul
că portul Ethernet este dezactivat datorită instabilității sistemului, iar activarea lui poate crea
probleme pentru utilizatorii începători. RaspBMC are ca aplicabilitate domeniul multimedia,
existând astfel numeroase constrângeri la utilizarea în regim de computer personal.
Pentru aplicațiile embedded, sistemul Raspbian oferă numeroase facilități prin care se
poate utiliza interfața GPIO a plăcii Raspberry Pi, în limbajele C, Python, Perl, Java, etc. Astfel
de facilități sunt oferite si de către RaspBMC, pentru a extinde sistemul multimedia oferit în
direcții aflate la alegerea utilizatorului. Dezavantajul acestor două sisteme constă în spațiul mare
ocupat pe mediul de stocare. De asemenea, utilizarea într-o aplicație de tip embedded duce la o
constrângere a sistemelor, acestea fiind concepute în principal pentru aplicațiile menționate
anterior. Arch Linux oferă, de asemenea, un mediu stabil pentru embedded. Un potențial mare îl
prezintă sistemul RISC OS, datorită spațiului mic ocupat pe mediul de stocare și a procesării
CMT. Aplicațiile embedded sunt singulare, în general, alte procese fiind redundante. Astfel,
spațiul necesar este redus direct proportional cu costurile iar procesarea este foarte rapidă,
datorită procesorului ARMv6.
Din punct de vedere al comunității consacrate fiecărui sistem si a posibilității de
dezvoltare a sistemului, Raspbian si RISC OS au cele mai mari si dezvoltate comunități, existând
numeroase versiuni precompilate de kernel-uri disponibile în funcție de aplicația dorită si a
dispozitivelor hardware utilizate. Arch Linux prezintă de asemenea o comunitate în creștere, iar
versiuni ale RaspBMC care extind aplicația de sistem multimedia sunt deja disponibile.
Din punct de vedere al interfeței cu utilizatorul si a dificultății de utilizare, Raspian este
alegerea potrivită, datorită provenienței Debian, sistem consacrat pentru aceste criterii. Arch
Linux este asemănător la acest capitol, fiind mai configurabil si mai robust. RISC OS are o
interfață minimalistă, bazată pe sistemul din anii 1980, iar ca utilizabilitate, utilizatorul necesită
anumite cunostințe bine intemeiate. [10]
19
Brînză Cătălin – Mihai
3.4.3. Cablu de rețea STP, Cat 5e
Deși Internetul wireless este din ce în ce mai popular, în multe locuri, cum ar fi hotelurile
sau camerele de cămin, Internetul se poate obține doar printr-o conexiune pe fir. Astfel pentru
proiectul în cauză pentru a realiza conectarea la internet a plăcuței Raspberry Pi Model B, am
ales cablul de rețea Hama STP Cat 5e. Cablul mai poate fi folosit de asemenea pentru a construe
o rețea de computere, acasă ori la birou, conectând un PC și un model DSL, un router modem
sau un switch de rețea, fiind recomandat pentru Internet de mare viteză cu STP (Shielded Twisted
Pair).
Caracteristicile generale ale acestui cablu de rețea sunt următoarele:
Tip Cablu de rețea
Semnal Digital
Ecranare STP
Lungime 3m
Conectori 8P8C
Culoare Gri
3.5. Interconectarea componentelor principale
Interconectarea componentelor alese pentru implentarea acestei aplicații este prezentată
in Figura 8, imagine construită de asemenea în programul Photoshop CS 6.
Figura 8. Interconectarea componentelor hardware
20
Capitolul 3.Proiectarea aplicației
În Figura 7, laptopul utilizatorului primește un semnal wireless de la un router sau telefon
(hot-spot), care va transmite semnalul prin cablul de rețea menționat mai sus printr-o conexiune
Bridge. Placuța va primi curent fiind conectat la laptop prin cablu USB tip C.
La plăcuța Raspberry Pi Model B, va veni conectata camera web și introdus Adaptorul SanDisk
în care se află MicroSD-ul de 32GB.
3.6. Componente software
Pentru implementarea aplicației ce ține de software am ales pentru implementarea
serverului flask si a modulului pentru cameră, limbajul de programare Python. Am ales acest
limbaj pentru că este ușor de utilizat și spre deosebire de alte limbaje unele sintaxe de cod sunt
mult mai succinte.
Pentru realizarea paginii web am ales limbajul HTML ajutat bineînteles de limbajul
JavaScript și standardul CSS (Cascading Style Sheets)
Schema paginii generată de codul din index.html este prezentată în Figura 9.
Figura 9. Schema paginii web
În MENIU FILTRE prezent în Figura 8, vor fi prezente butoanele realizate cu ajutorul
HTML, la care aspectul va fi redat de standardul CSS. Cel mai important lucru este contribuția
acestor butoane în aplicația noastră și acela fiind aplicarea filtrelor asupra imaginilor captate,
prin implementarea unor funcții care ne vor ajuta la prelucrarea iamginilor, cu ajutorul limbajului
JavaScript.
21
Brînză Cătălin – Mihai
Capitolul 4. Implementarea aplicației
Implementarea aplicației a necesitat o serie de pași asupra cărora a fost nevoie de timp și
atenție pentru evitarea eventualelor erori în buna funcționare a aplicației. V oi prezenta în cele ce
urmează pașii ce au dus la realizarea acestei aplicații.
4.1. Descărcare și instalare Raspbian
Primul pas a fost de a intra pe link-ul www.raspberrypi.org , dupa care vom căutat butonul
de download din bara de navigare, în partea de sus a ecranului. Odată făcut acest pas apare o
casetă ce conține un link către fișierele NOOBS. Aceste fișiere pot fi descărcate prin intermediul
unui torrent sau direct descărcând o arhivă zip a acestor fișiere. [12]
Dupa descărcarea arhivei zip ce conțin fișierele NOOBS, am luat Adaptorul SanDisk în
care am introdus MicroSD-ul de 32 GB. Următorul pas a fost cel de formatare a microSD-ului
dupa care am dezarhivat toate fișierele din arhivă pe microSD. După ce fișierele au fost copiate
am introdus Adaptorul în slotul SD al placuței Raspberry Pi Model B.
Pentru instalarea sistemului Raspbian va fi necesară conectarea plăcuței la net prin cablul
de rețea , menționat mai sus, la un monitor cu ajutorul unui cablu HDMI și conectarea la o sursă
de alimentare, în cazul meu la laptop, pentru a putea beneficia de ajutorul interfeței,dar și
conectarea unui mouse împreună cu tastură pentru realizarea instalării sistemului. Dupa câteva
secunde va aparea o imagine ca în Figura 10, unde vom bifa casuța Raspbian
[RECOMMENDED] și vom apasa butonul de Install din stanga sus, după care vom astepta
câteva minute. Instalarea se face singură fară a mai fi nevoie să bifam ceva important, iar la
finalul instalării, interfața Raspbian va fi ca cea amintită mai sus, Figura 3.
Figura 10. Instalare Raspbian
22
Capitolul 4. Implementarea aplicației
4.2. Conectarea plăcuței la laptop prin SSH
Pentru conectarea placuței Raspberry Pi Model B la laptop prin SSH, după ce toate
componentele prezentate mai sus au fost interconectate ca în Figura 8, va trebui făcută o
conexiune de tipul Bridge. Acest lucru se va face intrând în Control Panel, după care vom intra în
Network and Internet, unde vom alege Change adapter settings. După efectuarea acestor pași vor
apărea două conexiuni, una va fi de la conexinea wi-fi la care este conectat laptopul, iar a doua
de la conexiunea cablul ui de rețea care vine mufat la laptop și la plăcuță, fiind pentru moment
neconectat.
Pentru a transmite semnulul wi-fi de la laptop la plăcuță am selectat cele două conexiuni,
iar prin operația Click-Dreapta va apărea operația Bridge Connections, iar odată selectată vom
avea o nouă conexiune care va oferi internet și plăcuței Raspberry Pi Model B. Toate aceste
lucruri pot fi observate în imaginea pe care am realizat-o în Figura 11.
Figura 11. Conexiunea Bridge.
După ce știm că plăcuța are conexiune la internet, este momentul sa ne conectăm la ea cu
SSH (Secure Shell), prin intermediul programului PuTTy. V om merge în meniul START din
laptop și vom intra în terminalul Windows, unde vom introduce comanda ipconfig, după care
vom verifica IP-ul din dreptul adresei Ipv4, de la conexiunea Ethernet adapter Network Bridge.
Dupa aflarea IP-ului vom intra în programul PuTTy, unde vom selecta tipul conexiunii,
SSH, portul 22 și adresa IP descoperită. Odată conectați ne va fi solicit contul și parola de la
sistemul Raspberry PI, Figura 12.
23
Brînză Cătălin – Mihai
Figura 12. Conectare SSH
4.3. Instalare OpenCV
Instalarea OpenCV este un proces cu mai multe etape (chiar și consumator de timp) care
ne va solicita să instalăm mai multe dependențe și pre-rechizite. [11]
· Pasul 1: INSTALAREA DEPENDENȚELOR
Primul lucru a fost acela de a actualize oricare pachet existent, urmat de actualizarea
firmware-ului Raspberry Pi. Acest lucru a fost realizat prin execuția următoarelor comenzi în
terminalul Linux la care avem acces cu ajutorul programului PuTTy:
Instalare OpenCV
1. $ sudo apt-get update
2. $ sudo apt-get upgrade
3. $ sudo rpi-update
După actualizarea firmware-ului ca trebui sa repornim Raspberry Pi, acest lucru
realizându-se prin execuția comenzii:
Instalare OpenCV
1. $ sudo reboot
După repornire va trebui să instalăm câteva instrumente de dezvoltare, executând
comanda:
Instalare OpenCV
1. $ sudo apt-get install build-essential git cmake pkg-config
Următoarea comandă va instala pachetele de imagine I/O, pachete care ne permit să
încărcăm formate de fișiere de imagine, cum ar fi JPEG, PNG, TIFF, etc.
24
Capitolul 4. Implementarea aplicației
Instalare OpenCV
1. $ sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-
dev
La fel cum am descărcat pachetele de imagine I/O, avem nevoie și de pachetele video,
care ne vor permite să încărcăm diverse formate de fișiere video.
Instalare OpenCV
1. $ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
libv4l-dev
2. $ sudo apt-get install libxvidcore-dev libx264-dev
Următorul lucru care trebuie instalat este biblioteca de dezvoltare GTK astfel încât să
putem compila highgui sub modulul de OpenCV , care ne va permite să afișăm imaginile pe
ecranul nostru dar și de a constru interfețe simpe, GUI. Comanda pentru acest lucru este:
Instalare OpenCV
1. $ sudo apt-get install libgtk2.0-dev
Diferite operații în interiorul OpenCV , cum ar fi de exemplu operațiunile de matrici, pot
fi optimizate folosind dependențe adăugate.
Instalare OpenCV
1. $ sudo apt-get install libatlas-base-dev gfortran
Ultimul lucru de la pasul numărul 1 va fi instalarea Python-ului, astfel încât sa putem
compila modulele din OpenCV .
Instalare OpenCV
1. $ sudo apt-get install python2.7-dev python3-dev
· Pasul 2: Codul sursă OpenCV
În acest moment avem toare pre-rechizitele instale, astfel încât putem descărca o versiune de
OpenCV . Următoarele comenzi va descărca și va dezarhiva arhiva OpenCV .
Instalare OpenCV
1
2
3 $ cd ~
$ wget-O opencv.zip https://github.com/Itseez/opencv/archive/2.4.10.zip
$ unzip opencv.zip
· Pasul 3: Setări Python
Instalare pip, un manager de pachete Python.
25
Brînză Cătălin – Mihai
Instalare OpenCV
1. $ wget https://bootstrap.pypa.io/get-pip.py
2. $ sudo python get-pip.py
În continuare ne este sugerat să folosim mediile virtuale, care sunt o practică standard în
comunitatea Python.
Instalare OpenCV
1. $ sudo pip install virtualenv virtualenvwrapper
2. $ sudo rm –rf ~/.cache/pip
Următoarea comandă va creea mediul nostrum virtual Python.
Instalare OpenCV
1. $ mkvirtualenv cv –p python3
Instalare NumPy o dependență important pentru legările Pyrhon pentru OpenCV .
Instalare OpenCV
1. $ pip install numpy
· Pasul 4: Compilare și instalare OpenCV
Instalare OpenCV
1.
2.
3.
4.
5.
6.
7.
8.
9. $ cd ~/opencv-3.0.0/
$ mkdir build
$ cd build
$ cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_C_EXAMPLES=ON \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib 3.0.0/modules \
-D BUILD_EXAMPLES=ON ..
Compilare OpenCV
Instalare OpenCV
1. $ make
2. $ sudo make install
3. $ sudo ldconfig
· Pasul 5: Verificarea instalării cu succes a OpenCV-ului
26
Capitolul 4. Implementarea aplicației
Instalare OpenCV
1.
2.
3.
4.
5. $ workon cv
$ python
>>> import cv2
>>> cv2.__version__
'2.4.10'
4.4. Crearea serverului flask
Primul pas în realizarea server-ului web pe Raspberry Pi Model B, folosind framework-ul
Python Fșask, îl reprezintă configurarea corespunzătoare a serverului. Pentru acest lucru va
trebui sa redeschidem terminalul și fișierul nostru app.py echivalentul în C al fișierului main.c, în
care am introdus următorul cod pentru construirea și verificarea funcționalității corecte a unei
aplicații web de baza Flask.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello world'
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
În urma acestui cod, aplicația web va fi accesibilă pentru orice dispozitiv din rețea, prin
introducerea urmatorului link pe orice browser web: http://0.0.0.0:5000/ , unde 0.0.0.0 este pentru
plăcuța un localhost,iar pentru conexiunea altor dispozitive la aplicație, 0.0.0.0 va fi înlocuit cu
IP-ul care ne-am conectat prin SSH. Înainte de a introduce link-ul amintit mai sus, va trebui
lansată în execuție aplicația prin introducerea comenzii python app.py în terminal. Acest
lucru va fi făcut mereu când vom dori să accesam aplicația.
4.5. Crearea modulului Camera
Crearea acestui modul va realiza un live streaming de la camera conectată la plăcuța
Raspberry Pi la pagina web HTML. Pentru realizarea acestui lucru vom creea fișierul camera.py
în care vom importa librariile instalate la OpenCV și anume cv2. Acest lucru se va realiza prin
introducerea următoarei linii de cod: import cv2. Conținutul acestui fișier va prezenta în cele
ce urmează construcția unei clase VideoCamera unde cu ajutorul OpenCV pentru un video
stream cât mai corect capturile primite de cameră vor fi encodate în format JPEG.
from time import time
import cv2
class Camera(object):
def __init__(self):
27
Brînză Cătălin – Mihai
self.camera = cv2.VideoCapture(-1)
def get_frame(self):
(grab,frame) = self.camera.read()
#cv2.imwrite("frame.jpg",frame)
#self.image = open("frame.jpg").read()
(ret,jpeg)=cv2.imencode('.jpg',frame)
return jpeg.tostring()
După crearea clasei VideoCamera, vom apela clasa în fișierul app.py prezentat în codul
din Anexa 1. În fișierul amintit pe lângă apelarea clasei se va mai importa base64, care este un
grup asemănător codificării binare, schemă care reprezintă date binare în ascii formând un șir
prin traducerea ei într-o reprezentare radix 64. Acest lucru îl vom folosi pentru a encoda o
imagine realizată de streaming în format JPEG.
În codul amintit în Anexa 1, vom avea o variabilă frame declarată global, care va primi o
secvență de la cameră, care va fi encodată în momentul în care vom dori să captăm o imagine
oferită de streaming.
4.6. Realizarea paginii web
Pentru realizarea paginii web a fost nevoie de aprofundarea în primul rând al limbajului
HTML. După acumularea de cunoștințe am creat fișierul standard index.html , fișier care va
începe cu directiva <HTML> care specifică browserului faptul că informația care urmează în
fișier este în format HTML. Ultima directivă a fișierului va fi </HTML> și marchează sfârșitul
documentului HTML.
După această primă directivă urmează un bloc marcat de directivele <HEAD> și
</HEAD> care reprezintă antetul documentului informațiile din cadrul acestui bloc nefiind
afișate de către browser.
În continuate am afișat titlul aplicației implementate. Acest lucru a fost realizat prin
urmatoarea linie de cod :
<body bgcolor="#ecf0f1" topmargin="50" leftmargin="50" rightmargin="50">
<h1> <center> Captarea unei imagini pe o pagină WEB și prelucrarea acesteia </center> </h1>
</body>
În liniile de cod exemplificate mai sus, pe lângă scrierea titlului pe pagină am setat și
backgroundul paginii atribuind directivei <body> atributul „bgcolor” care va fi egal cu "#ecf0f1"
ce va da o nuantă de gri backgroundului. Pe lângă culoare, în directivul respectiv am setat și
marginile paginii, asemănător setărilor paginii din Microsoft Word.
Directivele <h1> și <center> indică faptul că titlul aplicației este primul header și va fi
poziționat centrat în pagină pentru o estetică cât mai plăcută.
După cum poate fi observat directivele au un început și un final, directiva de sfârșit fiind
precedat de caracterul „/ ”, unde tagurile de sfârșit nu vor conține niciodata atribute.
Cel mai important lucru din această aplicație este a introduce imagini pe care le vom
prelucra ulterior, iar acest lucru este posibil prin directiva HTML <IMG>.
Această directivă folosește valoarea atributului SRC care este unul obligatoriu deorece
valoarea este un URL și reprezintă locul de unde va fi preluată imaginea care se dorește a fi
28
Capitolul 4. Implementarea aplicației
adăugată în pagină.
<img src="{{ url_for('video_feed') }}" height="70%" width="45%" align="left" display=
"inline-block">
În această linie de cod este apelarea camerei care oferă streamingul pe pagina HTML,
prin valoarea atributului SRC care este "{{ url_for('video_feed') }}" unde am setat dimenisiunile
chenarului în care va aparea streamingul.
În continuarea am construit un buton SNAP atribuindui o funcție care ne va ajuta la
captarea imaginii pe care o vede camera din mediul în care ne aflăm. Funcția arată in felul
următor:
function snap() {
$.ajax({
url: '/getImage',
type: 'POST',
success: function(response) {
document.getElementById("img1").src = "data:image/jpeg;base64," +
response;
},
error: function(error) {
console.log(error);
}
});
};
Pentru această funcție am folosit tehnica AJAX, care va executa cererea de captare ori de
câte ori dorim, fară a fi nevoiți să reîncarăm toata pagina web după ce am apasat odată pe buton,
prind răspuns de la cameră o imagine în format jpeg, encodată cu ajutorul base64.
Am evidențiat cele spuse în Figura 13.
Figura 13. Captarea imaginii
29
Brînză Cătălin – Mihai
După realizarea codului aferent captării am realizat o clasă de butoane ale caror funcții în
JavaScript vor avea rolul de a prelucra imaginea captată. Clasa de butoane arată în modul
următor:
<div class="butoane">
<img id="blah" src="#" alt="" />
<img id="myCanvas" style="margin-left: 45;"> </canvas>
<button type="button" onclick="gray()" id = "gri"> Grayscale </button>
<button type="button" onclick="black()" id =
"blackwhite">AlbNegru</button>
<button type="button" onclick="flipImage()" id = "umbra">Flip</button>
<button type="button" onclick="invert()" id =
"inverseaza">Invert</button>
<button type="button" onclick="accentuareConturSobel()" id =
"conturSobel">Sobel</button>
<button type="button" onclick="filtruMediu3()" id =
"mediu">FiltruMediu3*3</button>
<button type="button" onclick="filtruMediu5()" id =
"mediu">FiltruMediu5*5</button>
<button type="button" onclick="gaus()" id = "gausian">Gaus</button>
<a id="saveJpg" download="myImage.jpg" href="data:,"> <button> SaveFilter
</button> </a>
</div>
Pentru toate butoanele din această clasă de tipul button în directiva <style > am atribuit
tuturor butoanelor odată, font (Helvetica), culoare, dimensiune, dar și efecte cum ar fi o umbră în
jurul butoanelor dar și schimbarea culorii acestora din albastru în portocaliu în momentul în care
avem mouse-ul în dreptul acestora, Figura 14.
Figura 14. Butoanele
După realizarea setului de butoane am atribuit fiecarui buton în parte cate o funcție în
JavaScript ce vor avea ca scop aplicarea unor filtre asupra imaginii dorite. O aplicație JavaSCript
poate fi adăugată într-un document HTML utilizând directiva pereche <SCRIPT>. </SCRIPT>.
Se pot include oricâte directive <SCRIPT> într-o pagină WEB în oricare din scțiunile
documentului <HEAD> sau <BODY>.
30
Capitolul 4. Implementarea aplicației
Singura restricție ar fi că în interiorul acestei directive nu se pot introduce alte directive
HTML. Introducere de directive HTML aici va fi semnalată ca eroare de către browser în
momentul în care va afișa pagina.
Una din cele mai importante facilitați oferite de JavaScript este posbilitatea de a detecta
anumite evenimente care au loc în pagină și de a reacționa la acestea. Un exemplu de astfel de
eveniment poate fi chiar trecerea cu cursorul mouse-ului peste un anumit obiect (hyperlink,
imagine sau buton.), încărcarea paginii, descărcarea paginii, apăsarea unei taste.
În continuare voi prezenta doar o funcție dintre cele realizate în JavaScript celelalte fiind
în Anexa 3.
function invert() {
var imgObj = document.getElementById('blah');
var img2 = document.getElementById('myCanvas');
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
var imgW = imgObj.width;
var imgH = imgObj.height;
canvas.width = imgW;
canvas.height = imgH;
canvasContext.drawImage(imgObj, 0, 0, imgW,imgH);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
for(var y = 0; y<imgPixels.height; y++){
for(var x = 0; x < imgPixels.width; x++){
var i = (y * 4) * imgPixels.width + x * 4;
imgPixels.data[i] = 255-imgPixels.data[i] ;
imgPixels.data[i + 1] = 255- imgPixels.data[i+1] ;
imgPixels.data[i + 2] = 255- imgPixels.data[i+2] ;
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width,
imgPixels.height);
img2.src = canvas.toDataURL();
return canvas.toDataURL();
}
Această metoda de negativare (invert) a unei culori se obține scăzând valorile ei din
valoarea maximă posbilă pe care o poate lua componentele de culoare. Negativarea imaginilor
este utilă pentru afișarea unor imagini medicale sau pentru realizarea de imagini negative pe
suporturi fizice, de exemplu, de tip peliculă.. Atribuirea funcțiilor fiecarui buton se va face prin
apelarea funcției prin atributul onclick=invert(), putându-se observa mai bine în Figura 14.
Pe pagină mai există o serie de slide-uri la care se aplică butoane de tip min-max, putând
seta diferite funcționalitați printre care:
31
Brînză Cătălin – Mihai
➢Blur
➢Brightness
➢Contrast
➢Hue Rotate
➢Opacity
➢Invert
➢SaturateSepia
La finalul acestor butoane secundare, va exista un buton de reset care va modifica
imaginea filtrată cu un pas mai sus. Acest lucru va fi posibil prin următoarea funcție.
<script>
$("input[type=range]").change(editImage);
$('#imageEditor').on('reset', function () {
setTimeout(function() {
editImage();
},0);
});
</script >
32
Capitolul 5.Testarea aplicației și rezultatele experimentale
Capitolul 5. Testarea aplicației și rezultatele experimentale
Interfața cu utilizatorul este dezvoltată folosind limbajul HTML, rezultând pagina web
care va oferi toate funcționalitățile aplicației. V oi prezenta în continuare capturi de ecran cu
explicarea unor pași importanți în execuția aplicației, dar și rezultate experimentale.
5.1. Pornirea serverului
După interconectarea elementelor hardware și conexiunea placuței Raspberry Pi Model B
la internet cu cablul de rețea, vom intra în folderul în care avem fișierul app.py, acest lucru
realizându-se prin comanda “cd” și vom da drumul la server prin execuția comenzii:
python app.py
Dacă aplicația nu prezintă erori și va funcționa corect, în terminalul Linux vom avea
aceeași imagine ca în Figura 15.
Figura 15. Pornirea serverului
5.2. Accesarea browser-ului
După cum sugerează și imaginea din Figura 15, în acest moment putem accesa aplația
introducând acel link în browser-ul nostru, însă acel link îl putem schimba cu ip-ul din stânga
sus, urmat bineînteles de portul 5000. (Figura 16.)
33
Brînză Cătălin – Mihai
Figura 16. Link intrare pagină web
5.3. Captarea imaginii
După lansarea în execuție a aplicației în prima parte a paginii vom avea partea de video
streaming oferit de cameră, butonul de captare imagine SNAP și chenarul unde va aparea
imaginea captată. După apasarea unui click asupra butonului SNAP vom capta o imagine din
cadrul streamingului cu posibilitatea de a salva pe dispozitivul nostrum aceea imagine, dacă nu
ne place poza captată apăsam din nou butonul SNAP, înlocuind imaginea, Figura 17.
Figura 17. Streaming și captare imagine
34
Capitolul 5.Testarea aplicației și rezultatele experimentale
5.4. Încărcarea imaginii pe pagină
După ce imaginea sau imaginile dorite au fost salvate în dispozitiv, următorul lucru
important este încărcarea imaginii pe pagină, urmând a fi prelucrate. Acest lucru se va face prin
apasarea butonului de sub video streaming, denumit “Browse”, ce ne va permite să alegem orice
imagine dorim. Dupa efectuarea acestui lucru imaginea selectată va apărea în dreptul meniului
de butoane, Figura 18.
Figura 18. Încărcare imagine
5.5. Aplicarea funcțiilor
Odată reușită încărcarea imaginii dorite, suntem în stadiul în care putem aplica imaginii
ceea ce sugerează si titlul, o metodă ce va prelucra imaginea și ne va oferi detalii concludente.
Singurul lucru care trebuie făcut pentru acest lucru este apăsarea butonului dorit după care, în
urma acestui lucru, lângă imaginea încărcată va apărea imaginea prelucrată, ca exemplu voi atașa
în Figura 19 aplicarea negativării imaginii, cod pe care l-am explicat și în capitolele anterioare.
Figura 19. Negativare
35
Brînză Cătălin – Mihai
5.6. Slide Filtre
După aplicarea unei funcții asupra imaginii, pentru o prelucrare mai în detaliu a imaginii,
cu ajutorul filtrelor din slide-ul implementat din josul paginii web, vom putea aplica imaginii alte
caracteristici. Ca exemplu, voi atașa în Figura 20, imaginea rezultată din aplicarea negativării, cu
efectul de blur.
Figura 20. Blur
36
Concluzii
Concluzii
În proiectul current, am încercat sa creez o aplicație ce combină partea de hardware cu
partea de software, care ar putea ajuta utilizatorii neinițiați în concepe IT dar și cei neinițiați în
domeniul prelucrării de imagini, să descopere mai ușor frumusețea acestor domenii. Aceasă
lucrare prezintă o abordare realizabilă a captării unei imagini din mediul în care ne aflăm cu
ajutorul unei camera web și prelucrarea acesteia prin aplicarea unor funcții ce vor scoate în
evidență detalii ale imaginilor.
Pentru realizarea acestei aplicații au fost folosite una sau mai multe abordări, metode sau
algoritmi pentru fiecare fază. Fiecare pas a fost tratat cu mai multe sau mai puține detalii. Cel
mai mult descris a fost pasul de realizare a paginii web și prezentarea formatării paginii, dar și
crearea funcțiilor de prelucrare. Pentru realizarea funcțiilor s-au încercat mai multe abordări și
algoritmi decât au fost prezentați în această lucrare, în final oprindu-mă la implementarea
algoritmilor de prelucrare prin limbajul JavaScript.
Soluția propusă pentru aplicarea acestor algoritmi este de a capta o imagine de la o sursă
video, pe care o vom salva în dispozitivul propriu, având posibilitatea să o reîncărcăm pe pagină
pentru a fi prelucrată.
Aplicația implementată garantează captarea de imagini de înaltă calitate, fiind astfel
capabilă să fie folosită și ca dispozitiv de studiu. Este o aplicație open source, astfel încât toate
persoanele pot avea acces la codul sursă a proiectului.
La nivel general, aplicația este structurată pe modelul client-server, permițând astfel
comunicarea dintre client ce are acces la interfață și server ce are rolul de a gestiona cererile
clientului.
Consider că aplicația în cauză poate fi completată și îmbunătățită în continuare de către
alte persoane pasionate ce doresc să studieze prelucrarea de imagine.
Din cauza faptului că acesta este un prototip, aplicația poate fi extinsă și îmbunătățită prin
adăugarea unor funcționalități cum ar fi:
· detectarea unei fețe umane și captarea acesteia;
· adaugarea mai multor filtre.
Concluzia finală după această lucrare este că câmpurile de procesare și prelucrare de
imagine sunt domenii foarte importante ale tehnologiei informației. În repetate rânduri este foarte
greu să reușești ceea ce îți propui luând aproape totul de la zero, dar bucuria e mare când ceva
nou rezultă din munca ta. De asemenea există multe secrete neexplorate care fac acest domeniu
unul foarte interesant.
37
Brînză Cătălin – Mihai
Bibliografie
[1]https://en.wikipedia.org/wiki/Raspberry_Pi#Model_B
[2]https://ro.wikipedia.org/wiki/JavaScript
[3]https://ro.wikipedia.org/wiki/HyperText_Markup_Language
[4]http://www.developerfusion.com/article/143158/an-introduction-to-websockets/
[5]http://kaazing.com/websocket/
[6]http://opencv.org/
[7]http://elinux.org/RPi_Hub
[8]http://www.makeuseof.com/tag/7-operating-systems-you-can-run-with-raspberry-pi/
[9]http://www.raspbian.org/RaspbianAbout
[10]http://www.techradar.com/news/software/operating-systems/raspberry-pi-operating-
systems-5-reviewed-and-rated-1147941
[11]www.pyimagesearch.com/2015/10/26/how-to-install-opencv-3-on-raspbian-jessie/
[12]https://www.raspberrypi.org/learning/noobs-install/worksheet/
[13]https://mediagalaxy.ro/camera-web-logitech-c270-1280-x-720-pixeli-negru?
gclid=CjwKEAjwm7jKBRDE2_H_t8DVxzISJACwS9Wb7vI8FxFfChRMjLy59dHc-
VKTLzNXpYRZYQVQ7QKykBoChSXw_wcB
[14]https://ro.wikipedia.org/wiki/Hypertext_Transfer_Protocol
[15]Notițe curs Prelucrarea Imaginilor
38
Anexe
Anexe
Anexa 1. Codul din app.py – realizarea streaming-ului pe server-ul flask
#!/usr/bin/env python
from flask import Flask, render_template, Response
# emulated camera
from camera import Camera
import base64
from io import BytesIO
app = Flask(__name__)
frame=0
@app.route('/')
def index():
"""Video streaming home page."""
return render_template('index.html')
def gen(camera):
"""Video streaming generator function."""
while True:
global frame
frame = camera.get_frame()
yield (b'–frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
@app.route('/video_feed')
def video_feed():
"""Video streaming route. Put this in the src attribute of an img tag."""
return Response(gen(Camera()),
mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/getImage', methods=['POST'])
def getImage():
print "Call image"
global frame
frame_string = base64.b64encode(frame)
return frame_string
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, threaded=True)
39
Brînză Cătălin – Mihai
Anexa 2. Modulul camera.py
from time import time
import cv2
class Camera(object):
def __init__(self):
self.camera = cv2.VideoCapture(-1)
def get_frame(self):
(grab,frame) = self.camera.read()
#cv2.imwrite("frame.jpg",frame)
#self.image = open("frame.jpg").read()
(ret,jpeg)=cv2.imencode('.jpg',frame)
return jpeg.tostring()
40
Anexe
Anexa 3. Codul pentru pagina WEB, index.html
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<style>
button:hover {
background:#f39c12;
}
button {
font-family:'Helvetica';
font-weight:bold;
color:#34495e;
border-radius: 60px 60px 60px 60px;
-moz-border-radius: 60px 60px 60px 60px;
-webkit-border-radius: 60px 60px 60px 60px;
border: 0px solid #4cc0ff;
background-color:#4cc0ff;
width:100px;
height:40px;
-webkit-box-shadow: 7px 7px 5px 0px rgba(128,133,133,1);
-moz-box-shadow: 7px 7px 5px 0px rgba(128,133,133,1);
box-shadow: 7px 7px 5px 0px rgba(128,133,133,1);
}
.butoane {
margin-top: 50px;
margin-bottom: 30px;
}
.sliders {
width: 30%;
display: inline-block;
border: 2px solid #000;
padding-left: 10px;
}
.sliders p {
margin: 18px 0;
vertical-align: middle;
}
img
{
-webkit-box-shadow: 10px 10px 14px 0px rgba(46,44,46,0.6);
41
Brînză Cătălin – Mihai
-moz-box-shadow: 10px 10px 14px 0px rgba(46,44,46,0.6);
box-shadow: 10px 10px 14px 0px rgba(46,44,46,0.6);
}
.sliders label {
display: inline-block;
margin: 10px 0 0 0;
width: 100px;
font-size: 1.1rem;
color: #22313F;
text-align: left;
vertical-align: middle;
}
.sliders input
{
position: relative;
margin: 10px 20px 0 10px;
vertical-align: middle;
}
input[type=range]
{
/*removes default webkit styles*/
-webkit-appearance: none;
/*fix for FF unable to apply focus style bug */
border-radius: 5px;
/*required for proper track sizing in FF*/
width: 150px;
}
input[type=range]::-webkit-slider-runnable-track {
width: 300px;
height: 7px;
background: #ABB7B7;
border: none;
border-radius: 3px;
}
input[type=range]::-webkit-slider-thumb
{
-webkit-appearance: none;
border: none;
height: 20px;
width: 20px;
42
Anexe
border-radius: 50%;
background: #4B77BE;
margin-top: -6px;
vertical-align: middle;
}
input[type=range]:focus {
outline: none;
}
input[type=range]:hover {
cursor: pointer;
}
#reset
{
display: inline-block;
height: 2.5rem;
width: 95%;
background-color: #22A7F0;
border-radius: 5px;
cursor: pointer;
outline: none;
font-size: 1.5rem;
color: #fff;
margin: 0 10px 10px 0px;
border: 2px solid transparent;
}
#reset:hover
{
color: #22A7F0;
background-color: #fff;
border: 2px solid #22A7F0;
}
</style>
<title> LICENTA </title>
<script>
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#blah')
43
Brînză Cătălin – Mihai
.attr('src', e.target.result)
.width(550)
.height(500);
};
reader.readAsDataURL(input.files[0]);
}
}
function snap() {
$.ajax({
url: '/getImage',
type: 'POST',
success: function(response) {
document.getElementById("img1").src = "data:image/jpeg;base64," +
response;
},
error: function(error) {
console.log(error);
}
});
};
function black() {
var imgObj = document.getElementById('blah');
var img2 = document.getElementById('myCanvas');
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
var imgW = imgObj.width;
var imgH = imgObj.height;
canvas.width = imgW;
canvas.height = imgH;
canvasContext.drawImage(imgObj, 0, 0, imgW,imgH);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
for(var y = 0; y<imgPixels.height; y++){
for(var x = 0; x < imgPixels.width; x++){
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i
+ 2]) /3;
var negru = 0;
if(avg>127)
44
Anexe
{ negru=255 }
imgPixels.data[i] = negru;
imgPixels.data[i + 1] = negru;
imgPixels.data[i + 2] = negru;
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width,
imgPixels.height);
img2.src = canvas.toDataURL();
return canvas.toDataURL();
}
function gray() {
var imgObj = document.getElementById('blah');
var img2 = document.getElementById('myCanvas');
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
var imgW = imgObj.width;
var imgH = imgObj.height;
canvas.width = imgW;
canvas.height = imgH;
canvasContext.drawImage(imgObj, 0, 0, imgW,imgH);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
for(var y = 0; y<imgPixels.height; y++){
for(var x = 0; x < imgPixels.width; x++){
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i
+ 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width,
imgPixels.height);
img2.src = canvas.toDataURL();
return canvas.toDataURL();
}
function flipImage()
{
var image=document.getElementById('blah');
var img2 = document.getElementById('myCanvas');
45
Brînză Cătălin – Mihai
var myCanvas=document.createElement("canvas");
var myCanvasContext=myCanvas.getContext("2d");
var imgWidth=image.width;
var imgHeight=image.height;
// You'll get some string error if you fail to specify the dimensions
myCanvas.width= imgWidth;
myCanvas.height=imgHeight;
// alert(imgWidth);
myCanvasContext.drawImage(image,0,0);
// this function cannot be called if the image is not rom the same domain.
You'll get security error
var imageData=myCanvasContext.getImageData(0,0, imgWidth, imgHeight);
// Traverse every row and flip the pixels
for (i=0; i<imageData.height; i++)
{
// We only need to do half of every row since we're flipping the halves
for (j=0; j<imageData.width/2; j++)
{
var index=(i*4)*imageData.width+(j*4);
var mirrorIndex=((i+1)*4)*imageData.width-((j+1)*4);
for (p=0; p<4; p++)
{
var temp=imageData.data[index+p];
imageData.data[index+p]=imageData.data[mirrorIndex+p];
imageData.data[mirrorIndex+p]=temp;
}
}
}
myCanvasContext.putImageData(imageData,0,0,0,0, imageData.width,
imageData.height);
img2.src=myCanvas.toDataURL();
return myCanvas.toDataURL();
}
function invert() {
var imgObj = document.getElementById('blah');
var img2 = document.getElementById('myCanvas');
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
var imgW = imgObj.width;
var imgH = imgObj.height;
canvas.width = imgW;
canvas.height = imgH;
46
Anexe
canvasContext.drawImage(imgObj, 0, 0, imgW,imgH);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
for(var y = 0; y<imgPixels.height; y++){
for(var x = 0; x < imgPixels.width; x++){
var i = (y * 4) * imgPixels.width + x * 4;
imgPixels.data[i] = 255-imgPixels.data[i] ;
imgPixels.data[i + 1] = 255- imgPixels.data[i+1] ;
imgPixels.data[i + 2] = 255- imgPixels.data[i+2] ;
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width,
imgPixels.height);
img2.src = canvas.toDataURL();
return canvas.toDataURL();
}
function accentuareConturSobel()
{
var imgObj = document.getElementById('blah');
var img2 = document.getElementById('myCanvas');
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
var imgW = imgObj.width;
var imgH = imgObj.height;
canvas.width = imgW;
canvas.height = imgH;
canvasContext.drawImage(imgObj, 0, 0, imgW,imgH);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
var max=0;
var rez= [];
for(var y = 1; y<imgPixels.height-1; y++)
{
for(var x = 1; x < imgPixels.width-1; x++)
{
// o fereastra de 3×3 pixeli centrata in i5
var i1 = ((y-1) * 4) * imgPixels.width + (x-1) * 4;
var i2 = ((y-1) * 4) * imgPixels.width + x * 4;
var i3 = ((y-1) * 4) * imgPixels.width + (x+1) * 4;
var i4 = (y * 4) * imgPixels.width + (x-1) * 4;
var i5 = (y * 4) * imgPixels.width + x * 4;
var i6 = (y * 4) * imgPixels.width + (x+1) * 4;
47
Brînză Cătălin – Mihai
var i7 = ((y+1) * 4) * imgPixels.width + (x-1) * 4;
var i8 = ((y+1) * 4) * imgPixels.width + x * 4;
var i9 = ((y+1) * 4) * imgPixels.width + (x+1) * 4;
// valorile de gri pentru pixelii din fereastra
var avg1 = (imgPixels.data[i1] + imgPixels.data[i1 + 1] +
imgPixels.data[i1 + 2]) / 3;
var avg2 = (imgPixels.data[i2] + imgPixels.data[i2 + 1] +
imgPixels.data[i2 + 2]) / 3;
var avg3 = (imgPixels.data[i3] + imgPixels.data[i3 + 1] +
imgPixels.data[i3 + 2]) / 3;
var avg4 = (imgPixels.data[i4] + imgPixels.data[i4 + 1] +
imgPixels.data[i4 + 2]) / 3;
var avg5 = (imgPixels.data[i5] + imgPixels.data[i5 + 1] +
imgPixels.data[i5 + 2]) / 3;
var avg6 = (imgPixels.data[i6] + imgPixels.data[i6 + 1] +
imgPixels.data[i6 + 2]) / 3;
var avg7 = (imgPixels.data[i7] + imgPixels.data[i7 + 1] +
imgPixels.data[i7 + 2]) / 3;
var avg8 = (imgPixels.data[i8] + imgPixels.data[i8 + 1] +
imgPixels.data[i8 + 2]) / 3;
var avg9 = (imgPixels.data[i9] + imgPixels.data[i9 + 1] +
imgPixels.data[i9 + 2]) / 3;
//derivata pe orizontala
var result1 = avg3 – avg1 + 2*(avg6-avg4) + avg9 – avg7;
//derivata pe verticala
var result2 = avg7 – avg1 + 2*(avg8-avg2) + avg9 – avg3;
// amplitudinea
var result = Math.sqrt(result1*result1 + result2*result2);
if(result>max)
{
max=result;
}
rez[i1] = result;
}
}
for(var y = 1; y<imgPixels.height-1; y++)
{
for(var x = 1; x < imgPixels.width-1; x++)
{
var i1 = ((y-1) * 4) * imgPixels.width + (x-1) * 4;
var i5 = (y * 4) * imgPixels.width + x * 4;
var final = rez[i1]/max*255;
imgPixels.data[i5] = final;
imgPixels.data[i5 + 1] = final;
imgPixels.data[i5 + 2] = final;
}
48
Anexe
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width,
imgPixels.height);
img2.src = canvas.toDataURL();
return canvas.toDataURL();
}
function filtruMediu3()
{
var imgObj = document.getElementById('blah');
var img2 = document.getElementById('myCanvas');
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
var imgW = imgObj.width;
var imgH = imgObj.height;
canvas.width = imgW;
canvas.height = imgH;
canvasContext.drawImage(imgObj, 0, 0, imgW,imgH);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
var max=0;
var rez = [];
for(var y = 1; y<imgPixels.height-1; y++)
{
for(var x = 1; x < imgPixels.width-1; x++)
{
// o fereastra de 3×3 pixeli centrata in i5
var i1 = ((y-1) * 4) * imgPixels.width + (x-1) * 4;
var i2 = ((y-1) * 4) * imgPixels.width + x * 4;
var i3 = ((y-1) * 4) * imgPixels.width + (x+1) * 4;
var i4 = (y * 4) * imgPixels.width + (x-1) * 4;
var i5 = (y * 4) * imgPixels.width + x * 4;
var i6 = (y * 4) * imgPixels.width + (x+1) * 4;
var i7 = ((y+1) * 4) * imgPixels.width + (x-1) * 4;
var i8 = ((y+1) * 4) * imgPixels.width + x * 4;
var i9 = ((y+1) * 4) * imgPixels.width + (x+1) * 4;
// valorile de gri pentru pixelii din fereastra
var avg1 = (imgPixels.data[i1] + imgPixels.data[i1 + 1] +
imgPixels.data[i1 + 2]) / 3;
var avg2 = (imgPixels.data[i2] + imgPixels.data[i2 + 1] +
imgPixels.data[i2 + 2]) / 3;
var avg3 = (imgPixels.data[i3] + imgPixels.data[i3 + 1] +
imgPixels.data[i3 + 2]) / 3;
49
Brînză Cătălin – Mihai
var avg4 = (imgPixels.data[i4] + imgPixels.data[i4 + 1] +
imgPixels.data[i4 + 2]) / 3;
var avg5 = (imgPixels.data[i5] + imgPixels.data[i5 + 1] +
imgPixels.data[i5 + 2]) / 3;
var avg6 = (imgPixels.data[i6] + imgPixels.data[i6 + 1] +
imgPixels.data[i6 + 2]) / 3;
var avg7 = (imgPixels.data[i7] + imgPixels.data[i7 + 1] +
imgPixels.data[i7 + 2]) / 3;
var avg8 = (imgPixels.data[i8] + imgPixels.data[i8 + 1] +
imgPixels.data[i8 + 2]) / 3;
var avg9 = (imgPixels.data[i9] + imgPixels.data[i9 + 1] +
imgPixels.data[i9 + 2]) / 3;
result = (avg1+avg2+avg3+avg4+avg5+avg6+avg7+avg8+avg9)/9;
rez[i1] = result;
}
}
for(var y = 1; y<imgPixels.height-1; y++)
{
for(var x = 1; x < imgPixels.width-1; x++)
{
var i1 = ((y-1) * 4) * imgPixels.width + (x-1) * 4;
var i5 = (y * 4) * imgPixels.width + x * 4;
var final = rez[i1];
imgPixels.data[i5] = final;
imgPixels.data[i5 + 1] = final;
imgPixels.data[i5 + 2] = final;
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width,
imgPixels.height);
img2.src = canvas.toDataURL();
return canvas.toDataURL();
}
function filtruMediu5()
{
var imgObj = document.getElementById('blah');
var img2 = document.getElementById('myCanvas');
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
var imgW = imgObj.width;
var imgH = imgObj.height;
canvas.width = imgW;
canvas.height = imgH;
50
Anexe
canvasContext.drawImage(imgObj, 0, 0, imgW,imgH);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
var max=0;
var rez = [];
var filterWidth = 5;
var filterHeight = 5;
var factor = 1/(filterWidth*filterHeight);
var result = 0;
var a=0;
var b=0;
for(var i = 0; y<imgPixels.width; i++)
{
for(var j = 0; j < imgPixels.height; j++)
{
result=0;
for (var m = 0; m<filterWidth; m++)
{
for (var n = 0; n<filterHeight; n++)
{
a = (m + i – (filterWidth / 2));
b = (n + j – (filterHeight / 2));
if (a<0)
a = w + a;
else
a %= w;
if (b<0)
b = h + b;
else
b %= h;
var x = (b * 4) * imgPixels.width + a * 4;
var avg = (imgPixels.data[x] + imgPixels.data[x + 1] +
imgPixels.data[x + 2]) / 3;
result += avg;
}
}
var y = (j * 4) * imgPixels.width + i * 4;
result *= factor;
rez[y] = result;
}
}
for(var y = 0; y<imgPixels.height; y++)
{
for(var x = 0; x < imgPixels.width; x++)
{
var i = (y * 4) * imgPixels.width + x * 4;
51
Brînză Cătălin – Mihai
imgPixels.data[i] = rez[i];
imgPixels.data[i] = rez[i];
imgPixels.data[i] = rez[i];
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width,
imgPixels.height);
img2.src = canvas.toDataURL();
return canvas.toDataURL();
}
function gaus()
{
var imgObj = document.getElementById('blah');
var img2 = document.getElementById('myCanvas');
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
var imgW = imgObj.width;
var imgH = imgObj.height;
canvas.width = imgW;
canvas.height = imgH;
canvasContext.drawImage(imgObj, 0, 0, imgW,imgH);
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
var max=0;
var rez = [];
var filterWidth = 3;
var filterHeight = 3;
var factor = 1/16;
var result = 0;
var filter =[[1,2,1],
[2,4,2]
[1,2,1]
];
var a=0;
var b=0;
for(var i = 0; y<imgPixels.width; i++)
{
for(var j = 0; j < imgPixels.height; j++)
{
result=0;
for (var m = 0; m<filterWidth; m++)
{
52
Anexe
for (var n = 0; n<filterHeight; n++)
{
a = (m + i – (filterWidth / 2));
b = (n + j – (filterHeight / 2));
if (a<0)
a = w + a;
else
a %= w;
if (b<0)
b = h + b;
else
b %= h;
var x = (b * 4) * imgPixels.width + a * 4;
var avg = filter[m][n]*(imgPixels.data[x] + imgPixels.data[x +
1] + imgPixels.data[x + 2]) / 3;
result += avg;
}
}
var y = (j * 4) * imgPixels.width + i * 4;
result *= factor;
rez[y] = result;
}
}
for(var y = 0; y<imgPixels.height; y++)
{
for(var x = 0; x < imgPixels.width; x++)
{
var i = (y * 4) * imgPixels.width + x * 4;
imgPixels.data[i] = rez[i];
imgPixels.data[i] = rez[i];
imgPixels.data[i] = rez[i];
}
}
canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width,
imgPixels.height);
img2.src = canvas.toDataURL();
return canvas.toDataURL();
}
function download() {
var img2 = document.getElementById('myCanvas');
var canvas = document.createElement('canvas');
var canvasContext = canvas.getContext('2d');
var imgW = img2.width;
var imgH = img2.height;
53
Brînză Cătălin – Mihai
canvas.width = imgW;
canvas.height = imgH;
canvasContext.drawImage(img2, 0, 0, imgW,imgH);
this.href = canvas.toDataURL('image/jpeg');
};
// editing image via css properties
function editImage() {
console.log('#someButton was clicked');
var gs = $("#gs").val(); // grayscale
var blur = $("#blur").val(); // blur
var br = $("#br").val(); // brightness
var ct = $("#ct").val(); // contrast
var huer = $("#huer").val(); //hue-rotate
var opacity = $("#opacity").val(); //opacity
var invert = $("#invert").val(); //invert
var saturate = $("#saturate").val();//saturate
var sepia = $("#sepia").val(); //sepia
var filter = 'grayscale(' + gs+
'%) blur(' + blur +
'px) brightness(' + br +
'%) contrast(' + ct +
'%) hue-rotate(' + huer +
'deg) opacity(' + opacity +
'%) invert(' + invert +
'%) saturate(' + saturate +
'%) sepia(' + sepia + '%)';
$("#myCanvas").css("filter", filter);
$("#myCanvas").css("-webkit-filter", filter);
};
</script>
<script src="{{url_for('static', filename='js/jquery.js')}}"></script>
</head>
<body bgcolor="#ecf0f1" topmargin="50" leftmargin="50" rightmargin="50">
<h1> <center> Captarea unei imagini pe o pagină WEB și prelucrarea acesteia
</center> </h1>
54
Anexe
<div width="100%" height="100%" display="inline-block">
<img src="{{ url_for('video_feed') }}" height="70%" width="45%"
align="left" display= "inline-block">
<button type="button" align="middle" onclick="snap()" id =
"UP_SNAP">SNAP</button>
<img class="img-responsive" src="data:image/jpeg;base64," height="70%"
width="45%" align="right" display="inline-block" alt="" id = "img1">
</div>
<div align="none" display="block">
<input type='file' onchange="readURL(this);" />
<a id="saveSnap" download="captare.jpg" href="data:image/jpeg;base64,">
<button <button style="margin-left: 891;"> SaveSnap </button> </a>
<br></br>
</div>
<div class="butoane">
<img id="blah" src="#" alt="" />
<img id="myCanvas" style="margin-left: 45;"> </canvas>
<button type="button" onclick="gray()" id = "gri"> Grayscale </button>
<button type="button" onclick="black()" id =
"blackwhite">AlbNegru</button>
<button type="button" onclick="flipImage()" id = "umbra">Flip</button>
<button type="button" onclick="invert()" id =
"inverseaza">Invert</button>
<button type="button" onclick="accentuareConturSobel()" id =
"conturSobel">Sobel</button>
<button type="button" onclick="filtruMediu3()" id =
"mediu">FiltruMediu3*3</button>
<button type="button" onclick="filtruMediu5()" id =
"mediu">FiltruMediu5*5</button>
<button type="button" onclick="gaus()" id = "gausian">Gaus</button>
<a id="saveJpg" download="myImage.jpg" href="data:,"> <button> SaveFilter
</button> </a>
</div>
<script>
document.getElementById('saveJpg').addEventListener('click', download,
false);
</script>
<div class="sliders">
<form id="imageEditor">
<p>
<label for="gs">Grayscale</label>
55
Brînză Cătălin – Mihai
<input id="gs" name="gs" type="range" min=0 max=100 value=0>
</p>
<p>
<label for="blur">Blur</label>
<input id="blur" name="blur" type="range" min=0 max=10 value=0>
</p>
<p>
<label for="br">Brightness</label>
<input id="br" name="br" type="range" min=0 max=200 value=100>
</p>
<p>
<label for="ct">Contrast</label>
<input id="ct" name="ct" type="range" min=0 max=200 value=100>
</p>
<p>
<label for="huer">Hue Rotate</label>
<input id="huer" name="huer" type="range" min=0 max=360 value=0>
</p>
<p>
<label for="opacity">Opacity</label>
<input id="opacity" name="opacity" type="range" min=0 max=100 value=100>
</p>
<p>
<label for="invert">Invert</label>
<input id="invert" name="invert" type="range" min=0 max=100 value=0>
</p>
<p>
<label for="saturate">Saturate</label>
<input id="saturate" name="saturate" type="range" min=0 max=500 value=100>
</p>
<p>
<label for="sepia">Sepia</label>
<input id="sepia" name="sepia" type="range" min=0 max=100 value=0>
</p>
<input type="reset" form="imageEditor" id="reset" value="Reset" />
56
Anexe
</form>
</div>
<script>
$("input[type=range]").change(editImage);
$('#imageEditor').on('reset', function () {
setTimeout(function() {
editImage();
},0);
});
</script>
</body>
</html>
57
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Calculatoare și Tehnologia Informației [609223] (ID: 609223)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
