Calculatoare și tehnologia informației [603298]
UNIVERSITATEA TEHNICĂ „Gheorghe Asachi” din IAȘI
FACULTATEA DE AUTOMATICĂ ȘI CALCULATOARE
DOMENIUL: Calculatoare și tehnologia informației
SPECIALIZAREA:Tehnologia informației
Detectarea vaselor de sânge în
imagini medicale utilizând metode de
segmentare Level Set
LUCRARE DE LICENȚĂ
Coordonator stiințific
Ș.l.dr.ing. Paul-Corneliu Herghelegiu
Student(ă)
Ghiuzan Adelina
Iași, 2018
DECLARAȚIE DE ASUMARE A AUTENTICITĂȚII
LUCRĂRII DE LICENȚĂ
Subsemnatul(a) ADELINA GHIUZAN ,
legitimat(ă) cu CI seria NT nr. 688068, CNP [anonimizat]
autorul lucrării DETECTAREA VASELOR DE SÂNGE ÎN IMAGINI MEDICALE
UTILIZÂND METODE DE SEGMENTARE LEVEL SET
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 IULIE a anului universitar
2017-2018, 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
Introducere…………………………………………………………………………………………………………………….. 1
Capitolul 1. Fundamentare teoretică și documentare bibliografică ……………………………………….. 2
1.1. Prezentarea temei și domeniul de aplicare ………………………………………………………………. 2
1.2. Imagini………………………………………………………………………………………………………………. 3
1.3. Procesarea imaginilor …………………………………………………………………………………………… 4
1.3.1. Procesarea imaginilor in domeniul spațial ……………………………………………………….. 4
1.3.1.1. Gradient……………………………………………………………………………………………….. 5
1.3.2. Procesarea imaginilor în domeniul frecvențelor ……………………………………………….. 6
1.3.2.1. Transformata Fourier ……………………………………………………………………………… 6
1.3.3. Filtrarea imaginilor în domeniul frecvențelor …………………………………………………… 8
1.3.3.1. Filtru Gaussian trece-bandă …………………………………………………………………….. 9
1.3.3.2. Filtru Butterworth trece-bandă ………………………………………………………………. 10
1.3.3.3. Filtre în cuadratură ……………………………………………………………………………….. 10
1.4. Segmentarea imaginilor ……………………………………………………………………………………… 13
1.4.1. Level Set……………………………………………………………………………………………………. 13
1.4.1.1. Optimizarea procesului de segmentare ……………………………………………………. 14
1.4.1.2. Optimizarea metodei Level Set ……………………………………………………………… 15
1.5. Tehnologii utilizate în implementare …………………………………………………………………….. 15
Capitolul 2. Proiectarea aplicației …………………………………………………………………………………… 17
2.1. Tehnologii utilizate …………………………………………………………………………………………….. 17
2.2. Specificațiile sistemului harware …………………………………………………………………………. 17
2.3. Prezentarea generală a aplicației ………………………………………………………………………….. 17
2.3.1. Îmbunătățirea calității imaginii …………………………………………………………………….. 18
2.3.2. Aplicarea filtrelor în cuadratură ……………………………………………………………………. 19
2.3.3. Segmentarea ………………………………………………………………………………………………. 19
Capitolul 3. Implementarea aplicației ……………………………………………………………………………… 21
3.1. Descriere generală ……………………………………………………………………………………………… 21
3.2. Procesarea imaginilor …………………………………………………………………………………………. 21
3.2.1. Transformata Fourier …………………………………………………………………………………… 21
3.2.2. Filtru Butterworth trece-jos ………………………………………………………………………….. 23
3.2.3. Filtre în cuadratură ……………………………………………………………………………………… 25
3.3. Segmentarea imaginilor ……………………………………………………………………………………… 30
3.3.1. Metoda Level Set ………………………………………………………………………………………… 30
3.4. Interfața cu utilizatorul ……………………………………………………………………………………….. 33
3.4.1. Meniuri……………………………………………………………………………………………………… 33
3.4.2. Butoane……………………………………………………………………………………………………… 34
3.4.3. Vizualizarea imaginilor ……………………………………………………………………………….. 35
3.4.4. Parametri…………………………………………………………………………………………………… 35
Capitolul 4. Testarea aplicației și rezultate experimentale ………………………………………………….. 37
4.1. Testarea aplicației ………………………………………………………………………………………………. 37
4.2. Rezultate experimentale ……………………………………………………………………………………… 37
4.2.1. Rezultatele filtrului Butterworth trece-jos ………………………………………………………. 38
4.2.2. Rezultatele filtrului în cuadratură ………………………………………………………………….. 38
4.2.3. Rezultatele metodei Level Set ………………………………………………………………………. 43
Concluzii și direcții viitoare de dezvoltare ……………………………………………………………………….. 47
Bibliografie………………………………………………………………………………………………………………….. 48
Anexe………………………………………………………………………………………………………………………….. 49
Detectarea vaselor de sânge în imagini medicale utilizând
metode de segmentare Level Set
Adelina Ghiuzan
Rezumat
Proiectul are ca scop principal detectarea structurilor tubulare într-o imagine medicală
2D, utilizând metode de filtrare și tehnici de segmentare.
Implementarea aplicației s-a realizat în mediul de dezvoltare Microsoft Visual Studio
2015 utilizând limbajul de programare C++. Pentru crearea interfeței s-a utilizat mediul de
programare Qt care pune la dispoziție funcții proprii, elemente de interfață grafică, clase
specifice lucrului cu imagini, iar pentru procesarea imaginilor s-a utilizat biblioteca open-source
OpenCV , scrisă în C, C++, ce conține peste 500 de funcții care acoperă domenii precum
imagistica medicală, securitatea, calibrarea camerelor fotografice, vedere stereo sau robotică.
Principalul subiect al proiectului este detectarea structurilor tubulare utilizând metoda de
segmentare Level Set, însa pentru aplicarea acesteia este necesară o etapă de pre-procesare a
imaginii în care calitatea imaginilor este îmbunătățită prin utilizarea filtrului Butterworth trece-
jos, și sunt evidențiate structurile orientate pe diferite direcții și de diferite dimensiuni prin
utilizarea filtrului în cuadratură. Această etapă de pre-procesare este necesară pentru a obține
rezultate cât mai corecte.
Filtrarea imaginilor s-a realizat în domeniul frecvențelor, deoarece față de filtrarea în
domeniul spațial, este mai eficientă. Acest lucru se realizează prin aplicarea transformatei
Fourier Discrete, iar filtrele se aplică asupra rezultatului obținut în urma transformării. De
asemenea, s-a ales filtrarea în domeniul frecvențelor deoarece, metoda de segmentare utilizează
doar partea reală a rezultatului filtrului în cuadratură, componentă ce contribuie la evoluția
conturului asupra imaginii inițiale. Pentru vizualizarea rezultatelor în urma filtrărilor s-a aplicat
inversa transformatei Fourier.
În acest proiect, utilizatorul are două sarcini importante, și anume: încărcarea unei
imagini asupra căreia se aplică automat funcțiile de filtrare și realizarea conturului inițial pentru
a puteam aplica metoda de segmentare. Segmentarea se bazează pe un set de formule
matematice, pe rezultatul real al filtrului în cuadratură și pe evoluția conturului la pasul anterior
(conturul la pasul zero fiind conturul realizat de utilizator), motiv pentru care segmentarea
imaginii se realizează pentru un număr de iterații specificat, prezentând utilizatorului, rezultatele
la fiecare iterație. Criteriul de stop al segmentării îl constituie numărul de iterații specificat de
utilizator.
Scopul final al acestui proiect constă în obținerea imaginii inițiale cu vasele de sânge
conturate.
Introducere
Introducere
Imagistica medicală este o specialitate științifică recentă, care reunește o largă varietate
de științe în scopul studierii modului în care se formează, înregistrează, transmit, analizează,
procesează, percep și se stochează imagini ale organelor sau țesuturilor, prin diferite tehnici, cu
scopul de a le folosi pentru a diagnostica bolile.
Imagistica medicală este foarte importantă în fluxul de lucru în domeniul medicinii,
deoarece odată cu creșterea cantității și a complexității datelor din imagini intervine necesitatea
unor metode automate de analiză care ajută medicul în explorarea datelor. O tehnică specifică de
imagistică este angiografia, în care vasele de sânge sunt descrise injectând un agent de contrast
care crește contrastul între vasele de sânge și țesutul înconjurător. În aceste imagini, vasele de
sânge pot fi văzute ca structuri tubulare cu diametre variate. Abaterile de la această structură
reprezintă semne de boală, cum ar fi stenozele care introduc un flux sanguin redus sau anevrisme
cu risc de ruptură. Această lucrare se concentrează asupra segmentării și vizualizării vaselor de
sânge din angiografia oculară. Angiografia oculară este o examinare fotografică ce permite
cercetarea vaselor de sânge care irigă coroida și retina. Acest tip de angiografie este esențial în
monotorizarea diabetului și în studierea irisului.
Modalitățile moderne de imagistică generează seturi de date foarte mari și complicate.
Prin urmare, există o nevoie tot mai mare de a dezvolta metode eficiente și robuste de analizare,
procesare și vizualizare pentru a ajuta la interpretarea imaginilor medicale, scopul principal fiind
menținerea sănătății omului și vindecarea acestuia.
Scopul acestei lucrări este detectarea vaselor de sânge într-o imagine medicală 2D
aplicând diferite tehnici de filtrare și morfologia matematică pentru analiza și prelucrarea
structurilor geometrice.
Această lucrare este împărțită în trei procese majore, urmărind realizarea unui algoritm de
detecție cât mai eficient și precis.
Primul proces constă în îmbunătățirea calității imaginii și eliminarea zgomotului din
imagine. Această operație se poate realiza prin aplicarea mai multor filtre de netezire precum:
filtrul Gaussian trece-jos, filtrul Butterworth trece-jos, filtrul ideal. În această lucrare s-a ales
aplicarea filtrului Butterworth trece-jos. Rezultatul obținut va fi transmis în etapa de aplicare a
fitlrului în cuadratură.
Al doilea proces major constă în aplicarea filtrului în cuadratură pentru detecția
structurilor tubulare orientate în anumite direcții și de dimensiuni variate. Pentru a produce un
rezultat care captează linii și muchii cu mare precizie, se folosește o integrare a filtrelor în
cuadratură pe mai multe scări. Rezultatul obținut în urma aplicării filtrului în cuadratură poate fi
folosit în tehnicile de segmentare .
Cele două filtre alese, sunt aplicate în domeniul frecvențelor, fapt ce duce la nevoia
transformării imaginii inițiale din domeniul spațial în domeniul frecvențelor utilizând
transformata Fourier.
Ultimul proces presupune segmentarea imaginii, având ca scop principal detectarea
vaselor de sânge utilizând metoda de segmentare Level Set ce implică rezolvarea unei metode
numerice pentru a urmări evoluția unui contur sau a unei suprafețe. Metodele de segmentare, în
majoritatea aplicațiilor, sunt utilizate pentru recunoașterea unui obiect: recunoașterea feței sau a
textului, recunoașterea amprentei, detecția mișcărilor unui om sau mașini, prin partiționarea
imaginii în două regiuni: fundal și obiecte.
1
Adelina Ghiuzan
Implementarea unor algoritmi de segmentare trebuie să fie foarte riguroasă și eficientă
deoarece în domeniul medicinii nu se admit greșeli în procesarea și interpretarea datelor
medicale.
2
Capitolul 1. Fundamentare teoretică și documentare bibliografică
Capitolul 1. Fundamentare teoretică și documentare bibliografică
De la începutul stiinței, observația vizuală a jucat un rol important în reprezentarea
rezultatelor experimentale, în acea vreme singurele posibilități fiind descrierea verbală și
desenarea manuală. Un pas foarte important a fost inventarea fotografiei care a permis
înregistrarea rezultatelor într-un mod obiectiv. Trei exemple proeminente de aplicații științifice
din fotografie sunt astronomia, fotogrammetria și fizica particulelor, astfel, astronomii au putut
măsura pozițiile și magnitudinea stelelor, prin fotogrammetrie s-au produs hărți topografice din
imagini aeriene și căutarea prin nenumărate imagini din camerele cu bule de hidrogen a condus
la descoperirea multor particule elementare în fizică. În general, imaginile erau utilizate pentru
documentație, descrieri calitative și ilustrarea fenomenului observat [1].
În zilele noastre, calculatoarele personale și stațiile de lucru au devenit suficient de
puternice pentru a procesa datele dintr-o imagine. Ca rezultat, componentele software și
hardware devin standarde pentru manipularea imaginilor, secvențelor de imagini și vizualizarea
3D.
Tehnologia este acum disponibilă oricărui om de știință sau inginer. În consecință,
procesarea imaginilor s-a extins și se extinde rapid. Tehnicile de procesare a imaginilor sunt
aplicate aproape tuturor științelor naturale și disciplinelor tehnice.
1.1. Prezentarea temei și domeniul de aplicare
Tema principală a proiectului este detectarea vaselor de sânge în imagini medicale
utilizând metode de segmentare Level Set, deoarece, în domeniul medicinii moderne, este
necesară existența unor algoritmi avansați și eficienți de analiză, prelucrare și interpretare a
rezultatelor.
Domeniul medical este o sursă interesantă de imagini. Modalitățile imagistice precum
computerul tomograf (CT) sau imagistica prin rezonanță magnetică (RMN) generează o cantitate
imensă de date despre o imagine . Odată cu tehnologia îmbunătățită, dimensiunile și rezoluțiile
imaginilor cresc, astfel, imaginile tradiționale 2D au fost înlocuite cu volume de imagini 3D în
mai multe examinări.
Scopul acestei lucrări este de a detecta structurile tubulare reprezentând vasele de sânge,
având la bază o imagine 2D și ghidarea atenției privitorului spre regiunile de interes, pentru o
prezentare mai bună a acestora. În termeni medicali, procesul de imagistică a vaselor de sânge se
numește angiografie. Cele mai frecvente dispozitive medicale de imagistică, sau modalități de a
obține angiograme sunt ultrasunete (US), fluoroscopia, computerul tomograf (CT), imagistica
prin rezonanța magnetică (RMN). Ultrasunetele și fluoroscopia sunt de obicei folosite pentru a
obține imagini 2D, în schimb ce computerul tomograf și imagistica prin rezonanță magnetică
generează imagini 3D.
3
Adelina Ghiuzan
1.2. Imagini
O imagine poate fi definită ca o funcție bidimensională f(x, y), unde x și y reprezintă
coordonatele spațiale și amplitudinea funcției f pentru orice pereche de coordonate (x, y) se
numește intensitate sau nivelul de gri al imaginii în acel punct. Atunci când valorile pentru
coordonatele x, y și intensitatea f sunt finite, cantități discrete, atunci imaginea este digitală.
Digitizarea reprezintă aproximarea unei scene reale. Imaginea digitală este alcătuita dintr-un
număr finit de elemente, fiecare având o locație specifică și o anumită valoare. Cel mai utilizat
termen pentru a descrie elementele unei imagini este pixelul (PICture ELement) și poate exprima
culoarea, opacitatea (transparența) și poziția în matricea în care se divide imaginea [2].
Majoritatea imaginilor se încadrează în două categorii:
•imaginile de tip raster sunt deseori numite hărți de biți (Bitmap) și sunt
reprezentate printr-o matrice de pixeli. Aceste imagini pot fi recunoscute prin
mărirea suficientă a imaginii, astfel încât să se poată observa contururile pătrate
ale fiecărui pixel;
•imaginile de tip vector sunt realizate din linii subțiri și curbe, cunoscute ca și căi,
și sunt înradăcinate în teoria matematicii. Orice linie sau curbă poate avea
atribuită o culoare. Datorită acestei abordări formale definite în desen, fiecare
imagine poate fi dimensionată și redimensionată în mod repetat fără a pierde
rezoluția și pentru a nu părea pixelate. Imaginile vectoriale pot fi recunoscute prin
vizionarea marginilor sale. Acest tip de imagine va apărea mereu netedă,
indiferent de dimensiunea sau apropierea acesteia, altfel spus, indiferent de
dimensiunea fontului, aspectul său nu se schimbă niciodată [3].
Imaginile pot fi stocate și salvate într-o mare varietate de formate. Cele mai comune
formate de imagini sunt:
•Bitmap (.bmp) este un format dezvoltat de Microsoft pentru sistemul de operare
Windows. Aceste fișiere sunt de dimensiuni mari și necomprimate, bogate în
culoare, de înaltă calitate. Fiecare pixel este stocat cu informații complete pentru
luminozitate și 16 milioane de culori. Dezavantajul acestui format este
deformarea imaginii la mărirea dimensiunii, elementele apărând încețoșate și
zgâriate;
•JPEG (.jpg) este un format dezvoltat de Joint Photoraphic Experts Group și este
cel mai răspândit format online pentru fotografii, grafice etc. Imaginile JPEG au o
scală de comprimare care scade dimensiunea fișierului, dar crește artefactele sau
pixelizarea cu cât este imaginea mai mult comprimată. Imaginile sunt comprimate
utilizând un algoritm de conversie a cosinusului discret (similar cu trasformările
Fourier). Algoritmul pastrează informațiile maxime privind culoarea și anume o
paletă de 16,7 milioane de culori;
•GIF (.gif) este un format dezvoltat de CompuServe special pentru utilizarea
online. GIF comprimă dimensiunea unei imagini reducând paleta la 256 de culori.
GIF-urile sunt cel mai bine utilizate pentru butoane, clipuri și alte imagini cu doar
câteva culori sau nuanțe de culori, în special pentru desene sau texte prezentate ca
imagine, dar nu pentru fotografii de înaltă rezoluție;
•PNG (.png) combină avantajelor formatelor JPEG și GIF, și anume: compresie
fără pierderi vizibile, 16,7 milioane de culori și un fundal transparent și întrețesut.
Din punct de vedere al culorilor, imaginile pot fi:
•binare – imagini alb-negru si pot fi reprezentate folosind o matrice ce conține doar
valorile 0 și 255, în care 0 indică negru, iar 255 indică alb. În alte situații,
4
Capitolul 1. Fundamentare teoretică și documentare bibliografică
matricea conține numai valori de 0 și 1, în care valoarea 1 reprezintă culoarea
alb;
•grayscale – imaginile cu niveluri de gri și pot fi reprezentate ca o matrice ce
conține valori intre 0 și 255, în care 0 indică negru, 255 indică alb, iar restul
valorilor indică nivelurile de gri. Fiecare element al matricei reprezintă
intensitatea pixelului respectiv. Aceste tipuri de imagini, se reprezintă în mod
obișnuit pe 8 biți pentru fiecare pixel [4].
•color – imaginile color se bazează pe modelul de culoare RGB (Red, Green, Blue)
în care fiecare pixel are cele trei componente: roșie, verde și albastră. Modelul de
culoare RGB se bazează pe teoria potrivit căreia toate culorile vizibile pot fi
create folosind culorile primare adiționale de roșu, verde și albastru. Aceste culori
sunt cunoscute ca „aditivi primari”, deoarece atunci când sunt combinați în
cantități egale, produc alb. Atunci când două sau trei dintre ele sunt combinate în
cantități diferite, se produc alte culori generându-se astfel pana la 16 milioane de
culori. Pentru o astfel de imagine, fiecărui pixel din imagini îi sunt asignate 3
valori pentru cele trei componente, de obicei valori întregi, făra semn pe 8 biți,
rezultând reprezentarea unui pixel pe 24 de biți [5].
1.3. Procesarea imaginilor
Procesarea digitală a imaginilor reprezintă procesul prin care imaginile sunt analizate și
manipulate cu scopul de a îmbunătăți calitatea imaginilor, de a crea perspective diferite sau
pentru a extrage informații din imaginea digitală utilizând algoritmi specifici.
Există o cerere tot mai mare de procesare a imaginilor în diverse domenii de aplicare
precum: multimedia, securitatea datelor, imagistica medicală, biometrie, înțelegerea textului,
recunoașterea modelului, comprimare etc.
Principalele operații efectuate asupra imaginilor sunt cele pentru:
•îmbunătățirea calității;
•eliminarea zgomotului;
•restaurare;
•comprimare;
•detectarea anumitor caracteristici.
Îmbunatățirea imaginilor poate fi considerată ca o parte a procesului de preprocesare.
Scopul principal al acestui proces este accentuarea anumitor caracteristici pentru analiza sau
redarea acestora, necesare prelucrărilor ulterioare.
Metodele de îmbunătățire a imaginilor pot fi împărțite în două categorii:
•metode în domeniul spațial – se bazează pe transformări aplicate direct pixelilor
dintr-o imagine;
•metode în domeniul frecvențelor – folosesc transformata Fourier a unei imagini
[6].
1.3.1. Procesarea imaginilor in domeniul spațial
Termenul „domeniul spațial” se referă la planul imaginii propriu-zis, în care operațiile de
manipulare și procesare se realizează direct asupra pixelilor.
Tehnicile de îmbunătațire în domeniul spațial includ operații punctuale (accentuarea
contrastului, reducerea zgomotului etc) sau operații spațiale (procesarea utilizând măști), în care
valoare pixelilor de ieșire depinde doar de valoarea de intrare corespunzătoare și de operațiile
locale sau vecinătate.
5
Adelina Ghiuzan
Filtrele aplicate asupra imaginilor în domeniul spațial se împart în mai multe categorii:
1. după efectul și destinația lor:
•filtre pentru eliminarea zgomotelor ;
•filtre pentru netezirea detaliilor – înlocuiesc valoarea pixelului curent cu o medie
a vecinilor lui. Acestea sunt numite de netezire deoarece netezesc detaliile care
reprezintă variațiile bruște ale intensității dintre pixelii vecini și anume,
frecvențele înalte. Printre filtrele de netezire se regăsesc: filtru medie aritmetică,
filtru cu medie ponderată (de exemplu: filtru Gaussian pentru eliminarea
zgomotului Gaussian) ;
•filtre de accentuare a contururilor – se pun în evidență detaliile dintr-o imagine
prin tehnici spațiale folosind operatori de derivare spațială (de exemplu: derivata
de ordin I are un minim și maxim local – gradientul, derivata de ordin II trece prin
zero – laplacianul unei imagini) ;
•filtre pentru detecția muchiilor.
2.după structura și modul de aplicare:
•liniare – înlocuiesc valoarea pixelului curent cu produsul de convoluție dintre
vecinătatea pixelului curent și o mască de convoluție ;
•neliniare – elimină zgomotele dintr-o imagine, pastrând în același timp fronturile
și detaliile din imagine, față de filtrele trece-jos care degradează imaginea prin
reducerea detaliilor din imagine . Exemple de filtre neliniare: filtre de ordine din
care face parte și filtrul Median, cel mai potrivit pentru înlăturarea zgomotului
sare și piper [6].
1.3.1.1. Gradient
Înainte de a discuta tehnicile de detectare a liniilor și a muchiilor, vom începe cu o scurtă
prezentare a modelului tipic al unei muchii. Un model ideal de muchie ar fi o tranziție bruscă
între două nivele diferite de intensitate dintr-o imagine (frontieră). Cu toate acestea, datorită
limitării lățimii de bandă, cele mai multe muchii din imaginile achiziționate de un sistem de
achiziție sunt mai mult sau mai puțin netede, astfel, o muchie tipică poate fi modelată ca o
tranziție lină între două nivele de intensitate, așa cum este prezentat în Figura 1.1.
Un candidat ideal în detecția muchiilor este reprezentat de derivata de ordin I, deoarece
oferă un rezultat diferit de zero pe parcursul întregii tranziții și în centrul muchiei se găsește
intensitatea maximă. Astfel, magnitudinea derivatei de ordin I, poate reprezenta o modalitate
simplă pentru detectarea liniile și muchiile într-o imagine [7].
6
Figura 1.1: Model de muchie și variația derivatelor [7]
Capitolul 1. Fundamentare teoretică și documentare bibliografică
Deoarece studiem imagini, derivata de ordin I este redată de gradient, definit de
derivatele parțiale prezentate în (1) pentru o imagine bidimensională I, în sistemul de coordonate
Cartezian. Gradientul unei imagini măsoară modul în care aceasta se schimbă. Acesta oferă două
tipuri de informații: amplitudinea (mărimea gradientului) care ne spune cat de repede se schimbă
imaginea și direcția în care se schimba imaginea cel mai rapid. Conform modelului prezentat în
Figura 1.1, muchiile pot fi identificate de către un gradient ce conține valori diferite de zero
(non-zero gradient), ceea ce presupune că amplitudinea gradientului trebuie să fie mai mare ca
zero, ecuație reprezentată în (2) [7].
∇I=(∂I/∂x,∂I/∂y)T(1)
|∇I|=√(∂I/∂x)2+(∂I/∂y)2>0 (2)
Cu toate acestea, obiectele din imaginile reale sunt rareori descrise de nivele constante de
intensitate, de aceea este necesară utilizarea unui prag T diferit de 0 pentru a detecta muchiile,
astfel încât|∇I|>T.
Detectarea frontierelor în imagini se bazează pe operatori care aproximează în planul
discret gradientul sau laplacianul. Aproximarea discretă a gradientului poate fi exprimată prin
diferențe finite astfel:
Gx=∂f(x,y)
∂x=f(x+Δx,y)−f(x,y)
Δx(3)
Gy=∂f(x,y)
∂y=f(x,y+Δy)−f(x,y)
Δy(4)
Aceste aproximări corespund convoluției funcției imagine cu măștile:
M1=[−11]șiM2=[1
−1].[5]
Pentru aproximarea gradienților mai pot fi folosite și aproximările Sobel sau Prewitt.
1.3.2. Procesarea imaginilor în domeniul frecvențelor
Analiza imaginilor în domeniul frecvențelor este o metodă foarte utilizată, centrată în
jurul instrumentului matematic special numit tranformata Fourier. Transformata Fourier este un
tip particular de transformare integrală care ne permite vizualizarea imaginilor și procesarea
acestora dintr-un alt punct de vedere prin transformarea imaginii inițiale într-un alt spațiu. După
aplicarea transformatei Fourier pentru transformarea imaginii din domeniul spațial, în domeniul
frecvențelor, operațiile de procesare sunt aplicate asupra imaginii rezultate. În domeniul
frecvențelor, imaginea este reprezentată de către componentele de frecvență, și anume
magnitudine și fază.
1.3.2.1. Transformata Fourier
Teorema lui Fourier arată că orice funcție periodică poate fi reprezentată ca o sumă de
termeni sinus și/sau cosinus (ca o serie Fourier). Dacă funcția este neperiodică, dar are aria de
sub grafic finită, aceasta poate fi exprimată ca o integrală în funcție de termeni sinus sau cosinus,
multiplicată cu un anumit factor. În prelucrarea imaginilor se lucrează cu funcții discrete, deci
folosind forma discretă a transformatei Fourier [5].
7
Adelina Ghiuzan
Din punct de vedere matematic, transformata Fourier pentru o funcție discretă
bidimensională (imagine) este:
F(k,l)=∑i=0N−1
∑j=0M−1
f(i,j)e−i2π(kiN+ljM)
,eix=cosx+isinx (5)
unde f este imaginea în domeniul spațial și F este imaginea în domeniul frecvențelor. Rezultatul
transformării este un număr complex. Afisarea rezultatului este posibilă fie printr-o imagine
reală, fie printr-o imagine complexă sau printr-o magnitudine și o imagine de fază. Pe parcursul
algoritmilor de procesare a imaginii, magnitudinea este cea mai utilizată, deoarece aceasta
conține toate informațiile cu privire la structura geometrică a imaginii. Dacă se doresc
transformări asupra imaginii, și imaginea trebuie retransformată, atunci sunt necesare atât
magnitudinea cât și faza [8].
Pentru a obține magnitudinea în domeniul Fourier, de exemplu, pentru o imagine cu
niveluri de gri,cu valori doar între 0 și 255 , transformarea Fourier trebuie să fie de tip discret,
rezultând o transformare Fourier discretă (DFT). Pașii pentru a obține magnitudinea unei imagini
I sunt următorii [8]:
1.Extinderea imaginii la o dimensiune optimă, deoarece performanța transformatei
Fourier depinde de dimensiunea imaginii. Tinde să fie mai rapidă pentru
dimensiunile imaginii care sunt multiple de numerele 2, 3, 5. Prin urmare, pentru
a obține performanțe maxime, în general este recomandat să se insereze valori de
frontieră (margini) în imagine pentru a obține o imagine cu caracteristicile
necesare transformatei Fourier.
2.Deoarece rezultatul transformatei Fourier este în domeniul complex, este necesar
pregatirea locației pentru salvarea atât a valorilor complexe, cât și a celor reale.
Acest lucru implică faptul că pentru fiecare valoare a imaginii, rezultatul va
cuprinde două valori (câte una pentru fiecare componentă). În plus, domeniul
frecvențelor este mai mare decât perechea sa (domeniul spațial). Prin urmare, vom
transforma imaginea noastră de intrare în acest tip și o vom extinde cu alt canal
pentru a salva valorile complexe.
3.Aplicarea transformatei Fourier asupra imaginii.
4.Transformarea valorilor reale și complexe în magnitudine. Un număr complex are
o componentă reală (Re) și o componentă imaginară (Im). Rezultatele
transformatei Fourier sunt numere complexe. Magnitudinea în urma aplicării
transformatei Fourier se calculează astfel.
M=2√Re(DFT(I))2+Im(DFT(I))2(6)
5.Trecerea la o scară logaritmică. Intervalul dinamic al coeficienților Fourier este
prea mare pentru a fi afișat pe ecran, unele valori fiind prea mici care vor rezulta
puncte negre, iar altele sunt prea mari reprezentând puncte albe. Pentru a utiliza
scara valorilor gri pentru vizualizare, se transformă de la o scară liniară, la o scară
logaritmică astfel:
M1=log(1+M) (7)
6.Decuparea și rearanjarea. Deoarece în primul pas s-a realizat o extindere a
imaginii, după realizarea operațiilor prezentate anterior, valorile introduse la pasul
1 trebuie eliminate. În vederea vizualizării, cadranele imaginii trebuie rearanjate,
8
Capitolul 1. Fundamentare teoretică și documentare bibliografică
astfel încât, originea (0, 0) să corespundă cu centrul imaginii. Aceasta se
realizează prin intershimbarea cadranelor stânga sus și dreapta jos, respectiv
stânga jos si dreapta sus, din imaginea care rezultă în urma aplicării transformatei
Fourier:
7.Normalizarea. Această operație este utilizată tot în scopul vizualizării rezultatului
prin împărțirea valorilor transformatei Fourier la valoarea maximă, pentru a
obține valori în intervalul [0, 1].
Un exemplu de afișare a spectrului transformatei Fourier, este prezentat în Figura 1.3 și
Figura 1.4.
Transformata Fourier este inversibilă, astfel funcția originală poate fi recuperată prin
aplicarea inversei transformatei Fourier, prin urmare, o imagine din domeniul frecvențelor poate
fi transformată înapoi în domeniul spațial:
f(x,y)=1
MN∑i=0N−1
∑j=0M−1
F(i,j)ei2π(kiN+ljM)
(8)
1.3.3. Filtrarea imaginilor în domeniul frecvențelor
Filtrarea în domeniul frecvențelor se bazează pe transformata Fourier. De obicei, acest
proces presupune înmulțirea imaginii de intrare cu o funcție de filtrare, pixel cu pixel:
G(k,l)=F(k,l)H(k,l) (9)
în care F(k, l) este imaginea de intrare în domeniul Fourier, H(k, l) este funcția de filtrare și G(k,
l) este imaginea filtrată. Pentru a transforma imaginea obținută din domeniul frecvențelor în
9
Figura 1.2: Shiftarea
spectrului transformatei
Fourier [5]
Figura 1.4: Spectrul
transformatei Fourier shiftat
[5]
Figura 1.3: Spectrul
transformatei Fourier
nemodificat [5]
Adelina Ghiuzan
domeniul spațial trebuie aplicată transformata Fourier inversă. Deoarece multiplicarea în
domeniul Fourier este asemănătoare cu procesul de convoluție, toate filtrele de frecvență pot fi
teoretic implementate și în domeniul spațial [9].
În domeniul frecvențelor se utilizează de preferință următoarele filtre:
•filtre trece-jos pentru netezirea imaginilor;
•filtre trece-sus pentru accentuarea muchiilor;
•filtre trece-bandă pentru accentuarea muchiilor și netezirea imaginilor în același
timp. Banda de trecere este utilizată pentru atenuarea frecvențelor foarte joase sau
foarte înalte, pastrând o bandă de frecvențe medii [6].
Filtrele trece-bandă reprezintă o combinație atât a filtrelor trece-jos, cât și a filtrelor
trece-sus. Acestea atenuează toate frecvențele mai mici decât o frecvență minimă cunoscută și
frecvențele mai mare decât frecvența maximă, astfel în imaginea de ieșire răman doar frecvențele
din interiorul benzii, și anume, frecvențele care se încadrează între cele două limite. Aceste filtre
pot fi create prin înmulțirea unui filtru trece-jos și a unui filtru trece-sus în domeniul
frecvențelor, unde frecvența de tăiere a filtrului trece-jos este mai mare decât cea a filtrului trece-
sus.
1.3.3.1. Filtru Gaussian trece-bandă
Filtrul Gaussian este folosit în procesarea imaginilor deoarece are o proprietate aparte, și
anume, atunci când acesta este transformat între domeniul spațial și domeniul frecvențelor,
rămâne un filtru Gaussian [9].
Filtrul Gaussian trece-bandă este rezultatul înmulțirii între filtrul Gaussian trece-jos și
filtrul Gaussian trece-sus exprimate astfel:
HLP(u,v)=e−D2(u,v)/2DL2
(10)
HHP(u,v)=1−e−D2(u,v)/2DH2
(11)
HBP(u,v)=HLP(u,v)∗HHP(u,v),DL>DH (12)
În ecuațiile (10), (11) și (12), DL și DH reprezintă frecvențele de tăiere ale filtrelor trece-
jos și trece-sus, iar D(u, v) reprezintă distanța față de origine.
10
Figura 1.5: Filtru Gaussian
trece-bandă [5]
Capitolul 1. Fundamentare teoretică și documentare bibliografică
Un exemplu de filtru Gaussian trece bandă este reprezentat în Figura 1.5.
1.3.3.2. Filtru Butterworth trece-bandă
Filtrul Butterworth trece-bandă poate fi derivat matematic prin înmulțirea funcțiilor de
transfer ale filtrelor trece-jos și trece-sus, filtrul trece-jos având cea mai mare frecvență de tăiere
[9].
HLP(u,v)=1/(1+[D(u,v)/DL]2n) (13)
HHP(u,v)=1−1/(1+[D(u,v)/DH]2n) (14)
HBP(u,v)=HLP(u,v)∗HHP(u,v) (15)
În ecuațiile (13), (14) și (15) DL și DH reprezintă frecvențele de tăiere ale filtrelor trece-jos
și trece-sus, D(u, v) reprezintă distanța față de origine, iar n este ordinul filtrului.
În Figura 1.6 este exemplificat filtrul Butterworth trece-bandă de ordin 4 pentru frecvența
minimă egală cu 30 și frecvența maximă egală cu 120.
11
Figura 1.6: Filtru
Butterworth trece-bandă [5]
Adelina Ghiuzan
1.3.3.3. Filtru în cuadratură
Pentru detectarea liniilor și a muchiilor, cea mai simplă soluție este utilizarea gradientului
prezentat în 1.3.1.1, însă aplicarea acestuia asupra unei imagini oferă răspunsuri diferite dacă se
modifică luminozitatea scenei. În unele cazuri, este bine să se separe tipul de eveniment (de
exemplu: linie sau muchie) și apoi puterea evenimentului. Acest lucru se poate realiza utilizând
filtrele în cuadratură care reprezintă tipul evenimentului prin intermediul fazei locale și puterea
acestuia prin magnitudinea filtrului rezultat.
Filtrele în cuadratură sunt perechi de filtre complexe, în care părțile reale sunt orientate
pe linii, iar părțile imaginare sunt orientate pe muchii. Când este construit un filtru în cuadratur ă
este importantă detectarea structurilor în toate direcțiile, fiind folosite seturi de filtre în
cuadratură cu diferite orientări. De asemenea sunt necesare filtrări la diferite scări pentru
detectarea structurilor de diferite mărimi [7].
Filtrele în cuadratură pot fi definite în domeniul Fourier astfel:
Fk(u)=0,u∗nk≤0 (16)
unde, u este coordonata în domeniul frecvențelor și n k este direcția filtrului. Această condiție
prezintă faptul că filtrul nu va lua în considerare frecvențele de pe partea negativă a filtrului
direcție [7].
Aceste filtre sunt proiectate pentru a fi separabile în funcții de rază (R) și direcție (D)
astfel:
F(u)=R(ρ)D(^nk) (17)
unde ρ=‖u‖și ^u=u/‖u‖.
Funcția de direcție este reprezentată astfel:
Dk(^u)={(^u∗^nk)2,^u∗^nk>0
0,altfel(18)
În timp ce funcția de direcție determină restricția unghiulară pentru a face diferența între
orientările structurilor, funcția radială este proiectată pentru detectarea formelor structurilor în
domeniul frecvențelor. Funcția radială poate fi reprezentată astfel:
R(ρ)=e−4B2∗log(2)∗log2∗(ρ/ρi)
.(19)
unde, B este lățimea de bandă, ρ i este frecvența din centrul filtrului [7].
Pentru majoritatea aplicațiilor, este foarte importantă detectare structurilor orientate în
toate direcțiile, filtrele în cuadratură fiind cele mai folosite. Pentru a acoperi spațiul tuturor
orientărilor în 2D sunt necesare cel puțin 3 orientări, iar în 3D sunt necesare 6 orientări. În
această lucrare se vor folosi 4 direcții pentru imagini 2D și anume:
^n1=(1,0)T,^n2=(a,a)T,^n3=(0,1)T,^n4=(−a,a)T(20)
unde a=1/√2.
În practică, aplicarea filtrelor în cuadratură pe direcțiile specificate va produce mai multe
rezultate, faza locală fiind caracteristică fiecărei direcții. Atunci când se combină rezultatele
pentru direcțiile dorite pentru maparea fazelor locale, orientările diferite introduc ambiguitatea.
12
Capitolul 1. Fundamentare teoretică și documentare bibliografică
Pentru filtru orientat de-a lungul gradientului, faza locală va tinde către 90o, pe când un filtru
orientat contrar gradientului va produce o fază care tinde spre -90o. Prin urmare, cele două filtre
vor produce un efect de anulare, iar în maparea fazei locale vor apărea discontinuități. De aceea,
pentru a evita ambiguitatea, din rezultatele filtrelor, partea imaginară va fi considerată valoarea
absolută [7].
Ultimul pas în procesul de filtrare este combinarea filtrelor pentru diferite scări , fiecare
scară fiind rezultatul sumei tuturor filtrelor de direcție. Această integrare este utilizată pentru a
trata vase de sânge de diferite lățimi, și se realizează prin sumarea ponderată a filtrelor astfel:
q=∑i=1N
|qi|β∗qi
∑i=1N
|qi|β(21)
unde N este numărul scărilor, q i este rezultatul filtrului pentru fiecare scară și β⩾0 este
parametrul de lățime. Reținem faptul ca valorea 0 a parametrului oferă media aritmetică a
tuturor filtrelor pentru scările alese, de aceea parametrul poate fi ales în intervalul 0 < < 5.
După realizarea integrării tuturor filtrelor, din rezultatul complex obținut, valorile pozitive ale
părții reale indică interiorul obiectului, iar valorile negative indică exteriorul acestuia [7].
În Figura 1.8 și Figura 1.9 sunt descrise rezultatele filtrelor pentru cele 4 direcții
prezentate anterior, cu a = 2, și rezultatul filtrului pentru diferite scări.
13
Figura 1.7: Imaginea
inițială [7]
Adelina Ghiuzan
1.4. Segmentarea imaginilor
Segmentarea imaginilor reprezintă procesul de împărțire a unei imagini în regiuni
semnificative, ce pot fi analizate ulterior în funcție de interesul asupra fiecărei regiuni. Scopul
principal este de a împărți o imagine în regiuni ce au o corelație puternică cu obiectele din lumea
reală. Regiunile segmentate sunt omogene în funcție de anumite proprietăți, cum ar fi intensitatea
pixelilor sau textura. Acest proces este întâlnit în majoritatea aplicațiilor care au ca scop
detectarea unui obiect: recunoașterea feței sau a textului, recunoașterea amprentei, detecția
mișcărilor unui om sau a unei mașini etc. Pentru multe aplicații, segmentarea se reduce la
detectarea unui singur obiect ce îndeplinește anumite criterii într-o imagine.
1.4.1. Level Set
Metoda Level Set presupune segmentarea imaginii prin rezolvarea unei metode numerice
pentru a urmări evoluția unei curbe sau a unei suprafețe. Această abordare pentru segmentarea
imaginilor cu contururi active a fost dezvoltată de matematicienii americani Osher și Sethian în
anul 1988 și aplicată în segmentarea imaginilor medicale de către Maladi în anul 1993 [7].
Evoluția curbelor sau a suprafețelor spre conturul unei anumite structuri de interes
reprezintă o metodă de segmentare a imaginilor folosită atât în domeniul graficii asistate de
calculator, precum și în alte arii de cercetare precum domeniul fizicii computaționale.
14
Figura 1.8: Rezultatele filtrului pentru cele 4 direcții ale imaginii originale din Figura 1.7 [7]
Figura 1.9: Rezultatele filtrului pentru diferite scări [7]
Capitolul 1. Fundamentare teoretică și documentare bibliografică
Imaginile pot fi segmentate într-un mod simplu, și anume folosind un prag de
segmentare, însă această metodă este foarte sensibilă la zgomot. Soluția standard pentru a
acoperi problema zgomotului, este includerea mijloacelor de regularizare folosind tehnici de
optimizare a energiei. Pentru imagini 2D, folosim o energie foarte utilizată în domeniul
metodelor de segmentare a imaginilor:
E(C(s))=∫∫ΩCf(x,y)dxdy−α∮
Cds(22)
unde C este o curbă unidimensionată reprezentând limita segmentării, ΩC este interiorul
curbei. Atunci când se maximizează această energie, obiectivul este găsirea unei curbe C, astfel
încât să cuprindă toate valorile pozitive ale funcției f (prima integrală), în timp ce lungimea
curbei este minimizată (a doua integrală). În această lucrare, funcția f(x,y)=Re(q) este
partea reală a rezultatului în urma aplicării filtrelor în cuadratură, α este un parametru de
regularizare ce poate fi setat în funcție de nivelul zgomotului din imagine. [8].
O curba C, poate fi reprezentată ca fiind o funcție (x, t) dependentă de timp astfel:
C(t)={x:ϕ(x,t)=0} (23)
unde t este timpul, x∈ℝn este coordonata în domeniul spațial, iar n definește dimensiunile
spațiului încorporat de C, astfel: o curbă plană se definește în ℝ2, iar o suprafață într-un
volum în ℝ3 [8]. Funcția de evoluție la momentul t = 0 poate fi reprezentată în modul
următor:
ϕ(x,t=0)=∓d (24)
unde d reprezintă distanța dintre oricare punct al imaginii și conturul inițial; distanța este pozitivă
dacă punctul se află în exteriorul conturului, negativă dacă se află în interiorul conturului și zero
pe marginile acestuia și se poate calcula folosind formula pentru calculul distanței dintre două
puncte în planul euclidian:
d=√(x1−x2)2+(y1−y2)2(25)
Astfel, pentru a găsi o curbă C care înconjoară vasele de sânge putem folosi direct f =
Re(q) în (22). Pentru a evolua curba în direcția gradientului funcției de energie E[C(s)] putem
folosi funcția de evoluție Level Set [8].
∂ϕ
∂t=−Re(q)|∇ϕ|+αk|∇ϕ| (26)
unde ϕ este funcția de evoluție Level Set, Re(q) este partea reală a filtrului în cuadratură
(Re(q) = 0 indica muchiile, Re(q) < 0 indică exteriorul și Re(q) > 0 indică interiorul vasului de
sânge) și k este curbura. Această curbură poate fi exprimată ca divergența normală în modul
următor:
k=∇⋅∇ϕ
|∇ϕ|(27)
Conform ecuațiilor (26) și (27) putem spune că, curba se deplasează în direcția sa
normală cu o funcție de viteză specificată de Re(q). Dacă Re(q) este pozitiv în interiorul vaselor,
curba se va extinde în interiorul acestor regiuni, altfel, curba se contractă în exteriorul vaselor de
15
Adelina Ghiuzan
sânge până când R(q) este egal cu zero; valorile pozitive și negative sunt redate de culori
luminoase sau întunecate.
1.4.1.1. Optimizarea procesului de segmentare
Segmentarea imaginilor poate fi considerată o problemă de optimizare, având ca scop
identificarea unei segmentări speciale care maximizează sau minimizează o funcție de energie
precum (22). V om prezenta o strategie de optimizare folosită în învățarea automată, adaptată
pentru metoda Level Set.
Cea mai simplă metodă numerică de optimizare este gradientul descendent, în care
gradientul unei funcții de energie este folosit pentru căutarea unei soluții optime. Cu toate
acestea, dezavantajele acestei abordări este convergența slabă pentru mai multe probleme
practice. Pentru a evita soluții complexe și sofisticate, o abordare simplă și intuitivă pentru a
extinde gradientul descendent este adăugarea unui impuls (momentum). Această idee a fost
inițial propusă în modelul Rumelhart în anul 1986, unde antrenarea unei rețele neuronale
reprezenta o problemă de optimizare. Ideea de bază constă în adaugarea unei fracțiuni din
direcția de căutare pasului curent, ceea ce adaugă o „inerție” fizică mișcării din spațiul de
căutare. Beneficiile practice ale acestei strategii sunt că optima locală poate fi depășită în timp ce
accelerează în direcții favorabile creșterea ratei de convergență. În mod normal, gradientul
descendent poate fi descris astfel:
sk=−αk∇Ek (28)
unde sk este pasul la iterația k, sk este lungimea pasului și ∇E este gradientul funcției de
energie/cost E [7].
Gradientul descendent cu impuls este exprimat în modul următor:
sk=−η(1−ω)∇Ek+ωs(k−1) (29)
unde η>0 este numit rata de învățare și ω este impulsul. Pentru ω=0 vom obține un
gradient descendent simplu, iar pentru ω=1 obținem o inerție infinită, s k = sk-1.
1.4.1.2. Optimizarea metodei Level Set
Pe măsură ce funcția Level Set evoluează în timp, soluția se deplasează de-a lungul
traiectoriei gradientului într-un spațiu al tuturor curbelor posibile. Acest spațiu se referă la
varietatea curbelor, putând fi numit „colector”. Ideea principală în optimizarea metodel Level Set
se bazează pe încorporarea impulsului prin modificarea traiectoriei de-a lungul colectorului.
Pentru a face acest lucru, funcția de evoluție Level Set trebuie evoluată pe baza unui timp
arbitrar T, rezultând funcția: ~ϕ(x,t+T),în care funcția ~ϕeste o soluție intermediară
pentru a estima gradientul prin diferențe finite [7]:
∇E(t)≈~ϕ(x,t+T)−ϕ(x,t)
T. (30)
~ϕ(x,t+T)=ϕ(x,t)+Δt∂ϕ
∂t(31)
Folosind ecuațiile (26), (29), (30), (31), actualizarea funcției de evoluție se realizează
astfel:
16
Capitolul 1. Fundamentare teoretică și documentare bibliografică
ϕ(x,t+T)=ϕ(x,t)+T∗s(x,t) (32)
unde T=nΔt, n este numărul de iterații și Δt este timpul.
Pentru un număr de iterații, algoritmul poate fi rezumat la 4 pași esențiali, prezentați în
modul următor:
1.Calculul funcției ~ϕ(x,t+T)intermediare, conform (31);
2.Aproximarea gradientului E, conform (30);
3.Calcului pasului s (x, t) conform (29), care modifică direcția gradientului prin
impuls;
4.Actualizarea funcției Level Set, conform (32).
1.5. Tehnologii utilizate în implementare
Pentru implementarea aplicației, s-au utilizat 3 tehnologii:
1.C++
−este un limbaj de programare general, compilat, orientat obiect (OOP), dezvoltat
de Bjarne Stroustrup si este o extensie a limbajului C. Prin urmare este posibilă
codificarea C++ într-un stil C. În anumite scenarii, acesta poate fi codificat în
oricare din cele două moduri și este astfel, un exemplu eficient al unui limbaj
hibrid. C++ este considerat un limbaj de nivel intermediar, deoarece încorporează
atât caracteristici de nivel înalt, cât și de nivel scăzut. Acesta a fost inițial denumit
„C cu clase”, deoarece avea toate proprietățile limbajului C cu un concept
suplimentar, și anume clasele. Cu toate acestea, în anul 1983 a fost redenumit „C+
+”. Acesta este unul dintre cele mai populare limbaje de programare folosite în
primul rând în sisteme/aplicații software, drivere, aplicații client-server.
−Principalul avantaj al limbajului de programare C++ este colecția de clase
predefinite, care reprezintă tipuri de date care pot fi instanțiate de mai multe ori.
Limbajul facilitează, de asemenea, declararea claselor definite de către utilizator.
Pot fi definite mai multe obiecte dintr-o anumită clasă pentru a implementa
funcțiile din cadrul clasei. Obiectele pot fi definite ca instanțe create la momentul
executării. Câteva din conceptele esențiale includ moștenirea claselor,
polimorfismul, abstractizarea datelor, încapsularea, funcțiile virtuale, spațiile de
nume, pointerii etc [10].
2.Qt
−Qt este un sistem inter-platformă ce oferă un mediu de dezvoltare integrat (IDE)
pentru C++, permițând programatorilor să dezvolte aplicații pentru mai multe
17
Figura 1.10: Exemple de iterații în urma aplicării metodei de segmentare Level Set [7]
Adelina Ghiuzan
platforme desktop, încorporate și dispozitive mobile, precum Android și iOS. Este
disponibil pentru sistemele de operare Linux, MacOS și Windows [11].
−datorită bibliotecii cu elemente de control, permite o dezvoltare rapidă atât a
aplicațiilor cu interfață grafică, cât și a celor fără interfață grafică, precum
serverele.
3.OpenCV („Open Source Computer Vision Library ”)
−este o bibliotecă de funcții open source, scrisă în C și C++. Biblioteca a fost
proiectată astfel încât să ofere eficiență computațională pentru aplicații în timp
real. Biblioteca OpenCV conține peste 500 de funcții care acoperă domenii
precum imagistica medicală, securitatea, calibrarea camerelor fotografice, vedere
stereo sau robotică.
18
Capitolul 2. Proiectarea aplicației
Capitolul 2. Proiectarea aplicației
Această aplicație are ca scop principal detectarea structurilor tubulare alcătuite din linii și
muchii în imagini medicale ce conțin vase de sânge utilizând filtre în cuadratură și metode de
segmentare Level Set.
2.1. Tehnologii utilizate
Aplicația este realizată utilizând limbajul de programare C++ în mediul de dezvoltare
Microsoft Visual Studio 2015.Aceasta cuprinde o interfață grafică ce permite interacțiunea cu
utilizatorul.
Pentru implementarea interfeței s-a ales mediul de dezvoltare Qt, deoarece este un sistem
multi-platformă, ce permite rularea aplicației pe mai multe platforme. Pe langă acest avantaj, Qt
conține o bibliotecă specială pentru elementele de control, fapt ce permite dezvoltarea
interfețelor într-o manieră simplă și implementarea evenimentele asupra acesteia.
Pentru prelucrarea imaginilor, s-a ales biblioteca open source OpenCV . Această bibliotecă
este gratuită atât pentru utilizarea comercială, cât și pentru cea necomercială. Este destinată în
principal procesării în timp real și are încorporate câteva sute de funcții care implementează
algoritmi de procesare a imaginilor, ceea de duce la o dezvoltare usoară și eficientă a aplicațiilor.
2.2. Specificațiile sistemului harware
Sistemul hardware folosit pentru implementarea aplicație este un laptop ASUS G55VW.
Acesta prezintă următoarele specificații:
•Intel® Core™ i7 CPU 3610QM: Un procesor quad-core bazat pe Bridge Ivy,
tactat la 2.3 GHz, cu suport Turbo Boost de până la 3.3 GHz. Oferă un grafic
integrat HD Graphics 4000 ce rulează la 650-1100 MHz pe un controler de
memorie dual-channel DDR3;
•NVIDIA GeForce GTX 660M: Soluție grafică de ultimă generație, ca parte a
seriei 600M, acesta oferă performanțe grafice mari, capabile de dezvoltarea
aplicațiilor ce necesită resurse grafice considerabile;
•Solid State Drive (SSD) 128GB: capabil de viteze de transfer superioare unei
unități de stocare standard;
•Memorie RAM 16 Gb: permite utilizarea mai multor aplicații simultan.
2.3. Prezentarea generală a aplicației
Aplicația este structurată în trei etape, dependente una de cealaltă, și anume:
•îmbunătățirea calității imaginii;
•aplicarea filtrelor în cuadratură;
•segmentarea.
Pentru o prezentare mai bună a evenimentelor, în Figura 2.1 este prezentată diagrama de
activități a aplicației. Această aplicație primește ca parametru de intrare o imagine care este
supusă unor operații de procesare și oferă ca rezultat o altă imagine ce cuprinde proprietățile
dorite.
19
Adelina Ghiuzan
2.3.1. Îmbunătățirea calității imaginii
Prima etapă a acestei aplicații constă în transformarea imaginii de intrare într-o imagine
cu niveluri de gri (grayscale) și aplicarea filtrului Butterworth trece-jos pentru îmbunătațirea
calității și reducerea zgomotului în imaginea inițială.
Filtrul butterworth trece-jos este aplicat în domeniul frecvențelor, de aceea imaginea
inițială trebuie transformată din domeniul spațial în domeniul frecvențelor folosind transformata
Fourier Discretă. Filtrul este aplicat asupra imaginii noi obținute în urma transformării. Pașii
esențiali în aplicarea filtrului Butterworth trece-jos sunt prezentați în Figura 2.2.
20
Figura 2.1: Diagrama de activități a aplicației
Capitolul 2. Proiectarea aplicației
În urma aplicării transformatei Fourier asupra unei imagini este necesară operația de
shiftare a spectrului, pentru a grupa pixelii de frecvențe înalte în centrul imaginii. Această
operație este necesară și în urma aplicării unui filtru, deoarece rezultatul obținut este unul
complex. Vizualizarea rezultatului este posibilă după aplicarea inversei transformatei Fourier.
2.3.2. Aplicarea filtrelor în cuadratură
Filtrele în cuadratură sunt utilizate pentru a detecta structurile tubulare pe diferite direcții
și de diferite dimensiuni. Principiul de aplicare al acestui filtru este asemănător cu cel al filtrului
Butterworth trece-jos, diferența facând-o parametrul de intrare în funcția de filtrare, exemplificat
în Figura 2.3. În cazul filtrului Butterworth trece-jos parametrul de intrare este imaginea initială
transformată într-o imagine grayscale, iar în cazul filtrelor în cuadratură, parametrul de intrare
este rezultatul obținut în urma aplicării filtrului Butterworth trece-jos.
2.3.3. Segmentarea
Segmentarea se realizează utilizând metoda Level Set. Această metodă presupune
segmentarea imaginii prin rezolvarea unei metode numerice pentru a urmări evoluția unei curbe
sau a unei suprafețe. Pentru a aplica metoda de segmentare este nevoie ca utilizatorul să realizeze
un contur inițial care va reprezenta pasul de început în detectarea structurilor tubulare. Pe langă
conturul realizat de utilizator, metoda Level Set, mai are nevoie ca parametru de intrare și de
partea reală a rezultatului obținut în urma aplicării filtrelor în cuadratură. Pașii principali sunt
prezentați în Figura 2.4.
21
Figura 2.2: Aplicarea filtrului Butterworth trece-jos
Figura 2.3: Aplicarea filtrelor în cuadratură
Adelina Ghiuzan
Metoda Level Set se aplică pentru un număr dat de iterații, prezentându-i utilizatorului,
rezultatul la fiecare iterație.
22
Figura 2.4: Aplicarea metodei Level Set
Capitolul 3. Implementarea aplicației
Capitolul 3. Implementarea aplicației
3.1. Descriere generală
Această aplicație permite interacțiunea cu utilizatorul și posibilitatea de a-i prezenta
acestuia rezultatele obținute în urma aplicării oricărei operații. Utilizatorul are drepturi de a
introduce o imagine la alegere ce urmează a fi procesată și de a modifica parametri de care
funcțiile de filtrare depind. De asemenea utilizatorul poate salva rezultatul segmentării, indiferent
dacă criteriul de stop s-a îndeplinit sau nu. Operațiile de transformare și aplicare a filtrelor se
realizează în mod automat, după introducerea imaginii care se dorește a fi procesată, utilizatorul
neavând drepturi de a alege momentele de aplicare a modificărilor asupra imaginii, pentru
evitarea nerespectării ordinii operațiilor, aceste fiind succesive și dependente între ele.
Aplicația este alcătuită din 4 clase principale, și anume:
•MainWindow – conține implementarea funcțiilor specifice fiecărui buton și
afișarea tuturor rezultatelor pe ecran, conexiunile între parametri filtrelor setați în
interfață și apelul acestora.
•CButterworthFilter – conține funcția de creare a filtrului Butterworth trece-jos și
funcția de aplicare a acestuia asupra transformatei Fourier.
•CQuadratureFilter – conține funcțiile de creare a filtrelor de direcție și a filtrului
radial, funcția de aplicare a acestora asupra transformatei Fourier și integrarea
filtrelor pentru cele 4 scări.
•ClevelSetMethod – conține metodele de creare a funcției de evoluție a conturului
în jurul vaselor de sânge.
3.2. Procesarea imaginilor
Pentru aplicarea operațiilor de procesare asupra imaginilor, s-au folosit funcțiile din
OpenCV pentru a calcula transformata Fourier și de aplicare asupra unui filtru în domeniul
frecvențelor.
3.2.1. Transformata Fourier
Transformata Fourier se calculează în momentul în care este aplicat un filtru asupra
imaginii, precum filtrul Butterworth trece-jos sau filtrul în cuadratură. Pentru implementarea
acestei operații s-a folosit funcția existentă în openCV:
void cv::dft(InputArray src, OutputArray dst, int flags = 0, int nonzeroRows =
0)
unde src este parametrul de intrare, dst este parametrul de ieșire, nonzeroRows este un parametru
care dacă este setat, specifică faptul că doar primul rând din parametrul de intrare care conține
valori diferite de zero este semnificativ, iar flags este un câmp ce poate fi setat pentru a specifica
tipul operației: DFT_INVERSE, DFT_ROWS, DFT_SCALE, DFT_COMPLEX_OUTPUT,
DFT_REAL_OUPUT.
•DFT_INVERSE – specifică operația de transformare inversă a transformatei
Fourier;
23
Adelina Ghiuzan
•DFT_ROWS – dacă parametrul de intrare este o structură bidimensională de
dimensiuni nxm, el va fi tratat ca n vectori unidimensionali distincți de lungimi m,
transformata Fourier aplicându-se pentru fiecare vector în parte;
•DFT_SCALE – normalizează rezultatele în funcție de numărul elementelor
parametrului de intrare;
•DFT_COMPLEX_OUTPUT – se folosește pentru a forța parametrul de ieșire să
conțină valori complexe;
•DFT_REAL_OUTPUT – deoarece rezultatul transformatei Fourier este în
domeniul complex, acest parametru oferă posibilitatea de a produce ca rezultat un
vectori ce conține valorile reale ale rezultatului complex.
cv::Mat ComputeDFT(cv:: Mat image) {
Mat padded;
int m = getOptimalDFTSize( image.rows);
int n = getOptimalDFTSize( image.cols);
copyMakeBorder(image, padded, 0, m – image.rows, 0, n – image.cols,
BORDER_CONSTANT, Scalar::all(0));
Mat planes[] = { Mat_< float>(padded), Mat::zeros(padded.size (), CV_32F) };
Mat complex;
merge(planes, 2, complex);
dft(complex, complex);
return complex;
}
Pentru a afișa spectrul transformatei Fourier sunt necesare operațiile de calcul a
magnitudinii conform (6) și shiftarea spectrului pentru a grupa frecvențele înalte în centrul
imaginii. Pentru calculul magnitudinii, logaritmarea și normalizarea acesteia s-au folosit funcțiile
exitente în openCV . Putem observa rezultatele obținute în urma aplicării transformatei Fourier în
figurile Figura 3.2 și Figura 3.3.
cv::Mat UpdateMag(cv::Mat complex, int x)
{
cv::Mat magI;
cv::Mat planes[] = {
Mat::zeros(complex.size(), CV_32F),
Mat::zeros(complex.size(), CV_32F)
};
cv::split(complex, planes);
cv::magnitude(planes[0], planes[1], magI);
magI += Scalar::all(1);
cv::log(magI, magI);
Shift(magI);
cv::normalize(magI, magI, 1, 0, NORM_INF);
return magI;
}
24
Capitolul 3. Implementarea aplicației
void Shift(cv::Mat& magI)
{
magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));
int cx = magI.cols / 2;
int cy = magI.rows / 2;
Mat q0(magI, Rect(0, 0, cx, cy));
Mat q1(magI, Rect(cx, 0, cx, cy));
Mat q2(magI, Rect(0, cy, cx, cy));
Mat q3(magI, Rect(cx, cy, cx, cy));
Mat tmp;
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
}
Atât modalitatea de aplicare a transformatei Fourier asupra unei imagini, cât și afișarea și
shifarea spectrului transformatei Fourier sunt prezentate în documentația oferită de OpenCV [8].
3.2.2. Filtru Butterworth trece-jos
Pentru implementarea filtrului Buterworth trece-jos s-a utilizat formula (13). Această
funcție are nevoie de trei parametri, și anume: rezultatul transformatei Fourier, frecvența de
tăiere și ordinul filtrului. În funcție de calitatea imaginii introduse, utilizatorul poate modifica
parametrii care corespund cu ordinul și frecvența de tăiere ale filtrului. Pentru a calcula distanța
dintre oricare punct și centrul imaginii s-a utilizat formula (25).
void CreateButterworthLowPass(cv:: Mat &dft_Filter, int DL, int n)
{
25
Figura 3.1: Imagine inițială
Figura 3.2: Spectrul
transformatei Fourier
Figura 3.3: Spectrul
transformatei Fourier shiftat
Adelina Ghiuzan
cv::Mat filter = cv::Mat(dft_Filter.rows, dft_Filter.cols, CV_32F);
cv::Point centre = cv::Point(dft_Filter.rows / 2, dft_Filter.cols / 2);
double distance;
for (int i = 0; i < dft_Filter.rows; i++)
{
for (int j = 0; j < dft_Filter.cols; j++)
{
distance = (double)sqrt(pow((i – centre.x), 2.0) + pow(( double)(j –
centre.y), 2.0));
filter.at<float>(i, j) = (float)(1 / (1 + pow(( double)(distance/ DL),
(double)(2*n))));
}
}
cv::Mat toMerge[] = { filter, filter };
merge(toMerge, 2, dft_Filter);
}
Pentru aplicarea filtrului asupra imaginii, este necesară operația de multiplicare a
rezultatului transformatei Fourier cu filtrul nou creat și aplicarea inversei transformatei Fourier
pentru a vizualiza rezultatul filtrului Butterworth în someniul spațial.
cv::Mat ApplyButterworthLowPass(cv:: Mat m, int order, int DL)
{
cv::Mat myPlanes[2], filter, filterOutput;
cv::Mat complex;
complex = ComputeDFT( m);
filter = complex.clone();
CreateButterworthLowPass(filter, DL,order);
ShiftDFT(complex);
mulSpectrums(complex, filter, complex, 0);
ShiftDFT(complex);
cv::idft(complex, complex);
Mat myplanes[] = {
Mat::zeros(complex.size (), CV_32F),
Mat::zeros(complex.size (), CV_32F) };
split(complex, myplanes);
normalize(myplanes[0], filterOutput, 0, 1, NORM_MINMAX);
return filterOutput;
}
Rezultatele aplicării filtrului Butterworth trece-jos cu ordinul n = 1 și frecvența de tăiere
DL = 10 asupra imaginii din Figura 3.1 sunt reprezentate în figurile următoare:
26
Capitolul 3. Implementarea aplicației
3.2.3. Filtre în cuadratură
În construirea filtelor în cuadratură sunt necesare cele două funcții descrise în (18) și (19)
pentru a realiza filtrarea pentru cele 4 direcții prezentate în (20) și filtrarea radială. Pentru
înmulțirea a doi vectori, Qt pune la dispoziție funcția „dotProduct” ce primește ca parametri doi
vectori și returnează produsul scalar dintre aceștia. Astfel, utilizând această formulă, putem
realiza produsul vectorilor „u” care reprezintă coordonatele în domeniul frecvențelor și „n k” care
reprezintă direcția.
float Qvector2D::dotProduct(const Qvector2D &v1, const Qvector2D &v2)
cv::Mat DirectionalFunction(cv:: Mat img, QVector2D nk)
{
int rows = img.rows;
int cols = img.cols;
cv::Mat direction(rows, cols, CV_32FC1);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
QVector2D u((float)(j – cols / 2) / (cols / 2), -( float)(i – rows /
2) / (rows / 2));
u.normalize();
if (QVector2D::dotProduct(u, nk) > 0)
direction.at<float>(i, j) = QVector2D::dotProduct(u, nk);
else
direction.at<float>(i, j) = 0.0;
}
}
return direction;
27
Figura 3.4: Filtrul
Butterworth trece-jos
Figura 3.5: Spectrul
transformatei Fourier în
urma aplicării filtrului
Figura 3.6: Spectrul
shiftat
Figura 3.7: Imaginea
obținută în urma
aplicării inversei
transformatei Fourier
Adelina Ghiuzan
}
cv::Mat RadialFunction(cv:: Mat img, int bw)
{
int cols = img.cols;
int rows = img.rows;
float ro_i = M_PI / (double)4;
float B = bw;
float norma_vect;
float calcul_fractie = ( float)-4.0 / (B*B*log(2));
cv::Mat radial(rows, cols, CV_32FC1);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
{
QVector2D u((float)(j – cols / 2) / (cols / 2), ( float)(i – rows / 2) /
(rows / 2));
norma_vect = (float)sqrtf(u.x()*u.x() + u.y()*u.y());
float ro = norma_vect;
radial.at<float>(i,j) = exp(calcul_fractie *log(ro / ro_i)*log(ro /
ro_i));
}
return radial;
}
Rezultatele filtrelor în cuadratură reprezintă produsul dintre filtrul direcției și filtrul radial
pentru fiecare direcție în parte, rezultatul final reprezentând suma celor patru filtre pentru o
anumită scară, scara fiind dată de valoarea lățimii de bandă.
cv::Mat CuadratureFilter(cv:: Mat m, int direction)
{
int w = m.cols;
int h = m.rows;
QVector2D nk1(1.0, 0.0);
QVector2D nk2(1.0 / sqrtf(2), 1.0 / sqrtf(2));
QVector2D nk3(0.0, 1.0);
QVector2D nk4(-1.0 / sqrtf(2), 1.0 / sqrtf(2));
int nk = 4;
cv::Mat d1 = DirectionalFunction( m, nk1);
cv::Mat d2 = DirectionalFunction( m, nk2);
cv::Mat d3 = DirectionalFunction( m, nk3);
cv::Mat d4 = DirectionalFunction( m, nk4);
cv::Mat q1(h, w, CV_32F);
28
Capitolul 3. Implementarea aplicației
cv::Mat q2(h, w, CV_32F);
cv::Mat q3(h, w, CV_32F);
cv::Mat q4(h, w, CV_32F);
cv::Mat radial = RadialFunction( m, GetBandWidth());
cv::Mat q(h, w, CV_32F);
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
q1.at<float>(i, j) = radial.at< float>(i, j) * d1.at< float>(i, j);
q2.at<float>(i, j) = radial.at< float>(i, j) * d2.at< float>(i, j);
q3.at<float>(i, j) = radial.at< float>(i, j) * d3.at< float>(i, j);
q4.at<float>(i, j) = radial.at< float>(i, j) * d4.at< float>(i, j);
float sum = q1.at<float>(i, j) + q2.at< float>(i, j) + q3.at< float>(i,
j) + q4.at<float>(i, j);
q.at<float>(i, j) = (sum > 255) ? 255 : sum;
}
}
return q;
}
Pentru lațimea de bandă a filtrului radial egală cu 2, putem vizualiza rezultatele filtrelor
în Figura 3.8, Figura 3.11, Figura 3.14, Figura 3.17. În urma aplicarii acestor filtre asupra
transformatei Fourier obținem Figura 3.9, Figura 3.12, Figura 3.15, Figura 3.18. Rezultatele în
urma aplicării inversei transformate Fourier sunt reprezentate în Figura 3.10, Figura 3.13, Figura
3.16, Figura 3.19.
29
Figura 3.8: Filtru în
cuadratură pe direcția 1
Figura 3.9: Aplicarea filtrului
1 asupra transformatei
Fourier
Figura 3.10: Rezultatul pe
direcția 1 în urma aplicării
inversei transformate Fourier
Adelina Ghiuzan
30
Figura 3.12: Aplicarea
filtrului 2 asupra
transformatei Fourier
Figura 3.11: Filtru în
cuadratură pe direcția 2
Figura 3.13: Rezultatul pe
direcția 2 în urma aplicării
inversei transformate Fourier
Figura 3.14: Filtru în
cuadratură pe direcția 3
Figura 3.15: Aplicarea
filtrului 3 asupra
transformatei Fourier
Figura 3.16: Rezultatul pe
direcția 3 în urma aplicării
inversei transformate Fourier
Figura 3.17: Filtru în
cuadratură pe direcția 4
Figura 3.18: Aplicarea
filtrului 4 asupra
transformatei Fourier
Figura 3.19: Rezultatul pe
direcția 4 în urma aplicării
inversei transformate Fourier
Capitolul 3. Implementarea aplicației
Am ales prezentarea filtrelor pe 4 scări, modificând lățimea de bandă cu o unitate la
fiecare scară. Filtrele în cuadratură trebuie aplicate asupra fiecărei scări, deoarece filtrul radial
este dependent de lățimea de bandă. Dat fiind faptul că rezultatele sunt structuri complexe,
integrarea acestora se realizează separat, atât pentru partea reală cât și pentru partea imaginară
conform formulei (21); în segmentare fiind semnificativă doar integrarea părților reale.
Rezultatele obținute pentru cele 4 scări sunt reprezentate în Figura 3.24 și Figura 3.25.
QImage MultiScaleIntegration( vector<cv::Mat> plane, int N, int beta,int part)
{
cv::Mat result(plane[0].rows, plane[0].cols, CV_32F);
QImage resultImg;
if (part == 0)
{
for (int i = 0; i < plane[0].rows; i++)
{
for (int j = 0; j < plane[0].cols; j++)
{
float numarator = 0;
float numitor = 0;
for (int l = 0; l < N; l++)
{
numarator += (double)pow(abs(plane[l].at<float>(i, j)),
beta) * plane[l].at<float>(i, j);
numitor += (double)pow(abs(plane[l].at<float>(i, j)),
beta);
}
if (numitor == 0) numitor = 1;
float aux = (float)(numarator / numitor);
result.at<float>(i, j) = aux;
}
}
resultImg = ConvertMatToQImage(result);
m_realPart = result;
}
m_result = result;
return resultImg;
}
31
Adelina Ghiuzan
3.3. Segmentarea imaginilor
3.3.1. Metoda Level Set
Metoda Level Set se bazează pe 6 operații principale:
1.Calculul funcției de evoluție la momentul zero: (x, t = 0), reprezentând distanța
oricărui punct față de conturul desenat de utilizator și în funcție de poziția
acestuia se calculează distanța euclidiană care primește ca parametri de intrare
coordonatele punctului curent (x 1, y1) și coordonatele conturului inițial (x 2, y2):
float ComputeEuclideanDistance( int x1, int y1, int x2, int y2)
{
return sqrtf((x1 – x2)*(x1 – x2) + (y1 – y2)*(y1 – y2));
}
2.Calculul gradientului funcției de evoluție și a curburii la momentul curent.
Gradientul este un element important în această metodă, deoarece curba va evolua
până când se va alinea cu structurile de intensități mari ale gradientului. Astfel,
curba va fi dirijată de intensitățile gradientului. Gradientul se calculează folosind
32
Figura 3.20: Rezultatul
filtrului pentru lățimea
de bandă egală cu 2
Figura 3.21: Rezultatul
filtrului pentru lățimea
de bandă egală cu 3
Figura 3.22: Rezultatul
filtrului pentru lățimea
de bandă egală cu 4
Figura 3.23: Rezultatul
filtrului pentru lățimea
de bandă egală cu 5
Figura 3.24: Partea reală
în urma integrării
Figura 3.25: Partea
imaginră în urma
integrării
Capitolul 3. Implementarea aplicației
algoritmul Sobel, utilizând funcțiile existente în openCV , iar curbura conform
(27).
void ComputeGradient(cv:: Mat m, cv::Mat &grad, cv::Mat &gradX,
cv::Mat &gradY)
{
Mat abs_grad_x, abs_grad_y;
Mat src, src_gray;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
GaussianBlur(m, src, Size(3, 3), 0, 0, BORDER_DEFAULT);
if (m.channels() == 3)
cvtColor(m, src_gray, CV_BGR2GRAY);
else if (m.channels() == 4)
cvtColor(m, src_gray, CV_BGRA2GRAY);
else
src_gray = m;
Sobel(src_gray, gradX, ddepth, 1, 0, 3, scale, delta,
BORDER_DEFAULT);
convertScaleAbs( gradX, abs_grad_x);
Sobel(src_gray, gradY, ddepth, 0, 1, 3, scale, delta,
BORDER_DEFAULT);
convertScaleAbs( gradY, abs_grad_y);
addWeighted(gradX, 0.5, gradY, 0.5, 0, grad);
}
cv::Mat CLevelSetMethod::ComputeCurvature(cv:: Mat grad, cv::Mat
gradX, cv::Mat gradY){
cv::Mat curvature(grad.rows, grad.cols, CV_32F);
cv::Mat grad_x, grad_y;
cv::Mat n(grad.rows, grad.cols, CV_32F);
int rows = grad.rows;
int cols = grad.cols;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
n.at<float>(i, j) = (float)(grad.at<float>(i, j) /
(ComputeGradientNorm( gradX.at<float>(i, j), gradY.at<float>(i,
j))));
}
}
33
Adelina Ghiuzan
ComputeGradient(n, curvature, grad_x, grad_y);
return curvature;
}
3.Calculul funcției intermediare de evoluție aplicând formulele (26) și (31).
Metoda Level Set funcționează implementând doar această funcție, însă nu va fi o
metodă optimizată și va converge mai greu.
//calculul funcției de evoluție intermediară
for (int i = 0; i < m.rows – 1; i++)
for (int j = 0; j < m.cols – 1; j++)
{
float gradNorm = ComputeGradientNorm(gradX.at< float>(i,
j), gradY.at<float>(i, j));
float regularTerm = -filterRealPart.at< float>(i, j) *
gradNorm + alpha * curvature.at< float>(i, j) * gradNorm;
newPhi.at<float>(i, j) = m_phi.at(it).at< float>(i, j) +
(float)(step / deltaT) *regularTerm;
}
4.Calculul gradientului E și a pasului s conform formulelor (29) și (30).
Aproximarea gradientului E prin diferențe finite este utilizat în calculul pasului s
care are rolul de a modifica direcția gradientului în funcție de impulsul .
Deoarece pasul s se construiește pe baza pasului anterior, am ales sa păstrez
calculele într-o listă pentru a putea accesa elementul oricărei iterații.
//clculul gradientului E
if (it == 0)
{
T = 1;
}
for (int i = 0; i < m.rows; i++)
{
for (int j = 0; j < m.cols; j++)
{
E.at<float>(i, j) = (float)(newPhi.at<float>(i, j)
– m_phi.at(it).at< float>(i, j))/T;
}
}
//calculul pasului s
cv::Mat s(m.rows, m.cols, CV_32FC1);
if (it == 0)
{
for (int i = 0; i < m.rows; i++)
{
for (int j = 0; j < m.cols; j++)
{
s.at<float>(i, j) = -learnRate*(1 –
momentum)*E.at<float>(i, j) + momentum;
34
Capitolul 3. Implementarea aplicației
}
}
sk.push_back(s);
}
else
{
for (int i = 0; i < m.rows; i++)
{
for (int j = 0; j < m.cols; j++)
{
s.at<float>(i, j) = -learnRate *(1 –
momentum)*E.at<float>(i, j) + momentum * sk.at(it –
1).at<float>(i,j);
}
}
sk.push_back(s);
}
5.Actualizarea funcției de evoluție aplicând formula (32) dependentă de impusul .
//calcul funcție de evoluție
cv::Mat finalPhi(m.rows, m.cols, CV_32F);
for (int i = 0; i < m.rows; i++)
{
for (int j = 0; j < m.cols; j++)
{
finalPhi.at<float>(i, j) = m_phi.at(it).at< float>(i, j) +
it * sk.at(it).at< float>(i, j);
}
}
m_phi.push_back(finalPhi);
3.4. Interfața cu utilizatorul
Implementarea interfeței grafice s-a realizat utilizând elemente de control din mediul de
dezvoltare Qt. Acesta conține o fereastră principală care oferă un cadru pentru construirea
interfețelor cu utilizatorul și anume „QMainWindow”, utilizată împreună cu clasele asociate
acesteia pentru gestionarea ferestrelor. Astfel, clasa specifică interfeței noastre „MainWindow”,
mostenește clasa de bază din Qt, „QMainWindow”, pentru a putea manipula fereastra principală
a aplicației, popularea acesteia realizându-se direct din Qt Designer.
3.4.1. Meniuri
În interfața grafică există două meniuri: un meniu ce oferă posibilitatea de a încărca o
imagine și de a salva rezultatul, și un meniu pentru afișarea filtrelor implementate (filtrul
Butterworth trece-jos și filtrul în cuadratură).
35
Adelina Ghiuzan
3.4.2. Butoane
Pentru realizarea butoanelor s-a utilizat clasa „QPushButton”, fiind cel mai utilizat
element de control pentru efectuarea acțiunilor la semnalul „clicked()”. Un buton emite
semnalul atunci când este activat de mouse sau de o comandă rapidă de la tastatură. Pentru a
putea efectua acțiunile destinate butoanelor, este necesară conectarea fiecărui buton la semnalul
respectiv. Există mai multe tipuri de semnale ce pot fi folosite în lucrul cu butoane și anume:
„clicked()” când este activat de mouse și este cel mai utilizat, „pressed()” și „released()” sunt
semnalele care se emit după apăsarea mouse-ului și eliberarea acestuia, fiind mai puțin
utilizate.Pentru fiecare buton existent în interfață, există o funcție implementată numită „slot” ce
realizează acțiunea destinată butonului.
connect(ui->openImagePb, SIGNAL(clicked()), this, SLOT(OpenImage()));
connect(ui->saveImagePb, SIGNAL(clicked()), this, SLOT(SaveImage()));
connect(ui->processPb, SIGNAL(clicked(bool)), this, SLOT(Process()));
connect(ui->ClearContourPb, SIGNAL(clicked(bool)), this, SLOT(ClearContour()));
connect(ui->rectanglePb, SIGNAL(clicked(bool)), this, SLOT(ActivateRectangle()));
connect(ui->circlePb, SIGNAL(clicked(bool)), this, SLOT(ActivateCircle()));
connect(ui->refreshPb, SIGNAL(clicked(bool)), this, SLOT(Refresh()));
connect(ui->showComponentsPb, SIGNAL(clicked(bool)), this,
SLOT(ShowComponents()));
Astfel, interfața grafică cuprinde următoarele butoane, reprezentate în figurile Figura 3.28
și Figura 3.29:
•Deschidere – permite utilizatorul încărcarea unei imagini;
•Salvare – permite slvarea imaginii în urma segmentării;
•Desenare și – permit utilizatorului desenarea conturului inițial;
•Stergerea conturului – ștergerea conturului realizat de utilizator;
•Refresh – se actualizează rezultatele filtrelor vizualizate în interfață în
cazul modificărilor realizate asupra parametrilor;
•Aplicarea segmentării – se poate aplica metoda Level Set după
încărcarea imaginii și obținerea rezultatelor în urma aplicării filtrelor;
•Oprirea segmentării – se oprește metoda Level Set, rezultatul afișat fiind
rezultatul obținut la iterația curentă;
36
Figura 3.26: Meniu
pentru încărcarea
imaginii și salvarea
rezultatului
Figura 3.27: Meniu pentru
afișarea filtrelor
Clear Contour
Refresh
Process
Stop
Capitolul 3. Implementarea aplicației
•Vizualizarea componentelor metodei Level Set – permite
vizualizarea elementelor ce ajută la evoluția conturului (funcția de evoluție și
gradientul).
3.4.3. Vizualizarea imaginilor
Pentru vizualizarea imaginilor și a textului, s-au utilizat obiecte de tip „QLabel”. Aceste
obiecte nu oferă nicio funcție de interacțiune cu utilizatorul și poate cuprinde mai multe tipuri de
conținut: text, pixmap, video. Qt oferă 4 clase pentru gestionarea imaginilor: „QImage”,
„QPixmap”, „QBitmap” și „QPicture”, în lucrarea aceasta utilizându-se doar primele două clase
menționate.
„QImage” este utilizat pentru manipularea și accesarea directă a pixelilor, iar „QPixmap”
este utilizat pentru afișarea imaginilor pe ecran, de aceea pentru afișarea unei imagini într-un
„QLabel” este necesară salvarea imaginii dorite într-un obiect de tipul „QImage”, preluarea
pixmap-ului imaginii și salvat într-un obiect de tipul „QPixmap” și setarea acestuia în „QLabel”-
ul de pe interfață.
m_initialImage.load(m_ImagePath, "JP2");
m_initialPixmap = QPixmap::fromImage(m_initialImage);
ui->imageLabel->setPixmap(m_initialPixmap);
ui->imageLabel->setMask(m_initialPixmap.mask());
ui->imageLabel->show();
3.4.4. Parametri
Deoarece funcțiile de filtrare și metoda de segmentare Level Set sunt dependente de
parametri care nu sunt constanți, am creat secțiuni pentru fiecare metodă, oferindu-i utilizatorului
posibilitatea de a modifica valorile în funcție de imaginea inserată, prezentate în Figura 3.30,
Figura 3.31 și Figura 3.32.
37
Figura 3.28: Butoane pentru încărcarea, salvarea
, actualizarea imaginilor și desenarea conturului
Figura 3.29: Butoane necesare segmentării
imaginiiShow components
Adelina Ghiuzan
38
Figura 3.30: Parametri
necesari filtrului
Butterworth trece-jos
Figura 3.31: Parametri
necesari filtrului în
cuadratură
Figura 3.32: Parametri
necesari metodei Level
Set
Capitolul 4. Testarea aplicației și rezultate experimentale
Capitolul 4. Testarea aplicației și rezultate experimentale
4.1. Testarea aplicației
Testarea aplicației presupune încărcarea unei imagini de către utilizator, imagine asupra
căreia se aplică automat filtrul Butterworth trece-jos și filtrul în cuadratură. Așa cum s-a
menționat în 3.1, utilizatorul nu are dreptul de a alege ordinea aplicării filtrelor, deoarece ordinea
este esențială, iar operațiile se realizează succesiv. Utilizatorul are dreptul de a modifica
parametrii de care depind filtrele, fiind necesară apasarea butonului „Refresh” pentru a actualiza
datele de pe interfață.
Al doilea pas, după încărcarea imaginii, utilizatorului îi revine sarcina de a efectua
conturul inițial asupra imaginii, care reprezintă pasul de pornire al metodei Level Set.
Segmentarea imaginii se aplică doar în urma apăsării butonului „Process”. Deoarece metoda
Level Set se aplică pentru un număr specificat de iterații, utilizatorului îi este prezentată o bară
de progresie pentru a vizualiza stadiul segmentării la momentul curent.
4.2. Rezultate experimentale
Scopul principal al acestei lucrări este detectarea vaselor de sînge în imagini medicale
utilizând metoda de segmentare Level Set. Pentru a vizualiza rezultatele fiecărei etape, s-a ales o
imagine medicală ce conține vase de sânge, de dimensiuni 319×312 reprezentată în .
Prima etapă a acestei lucrări constă în aplicarea transformatei Fourier asupra imaginii
originale pentru a transforma imaginea din domeniul spațial în domeniul frecvențelor.
Rezultatele în urma transformării sunt reprezentate astfel: în Figura 4.2 este prezentat spectrul
transformatei Fourier, iar în Figura 4.3 este prezentat spectrul shiftat pentru a grupa frecvențele
înalte în centrul spectrului.
39
Figura 4.1: Imaginea inițială
Adelina Ghiuzan
4.2.1. Rezultatele filtrului Butterworth trece-jos
După aplicarea transformatei Fourier, se poate aplica filtrul Butterworth trece-jos
înmultind rezultatul transformatei Fourier cu filtrul implementat.
În Figura 4.4 este prezentat filtrul Butterwoth trece-jos creat, Figura 4.5 reprezintă
specturl transformatei Fourier în urma aplicării filtrului, iar Figura 4.6 este rezultatul spectrului
transformatei Fourier în urma shiftării. Pentru a vizualiza orice rezultat din domeniul
frecvențelor, în domeniul spațial, este necesară aplicarea inversei transformatei Fourier,
rezultatul fiind reprezentat în Figura 4.7.
4.2.2. Rezultatele filtrului în cuadratură
A doua etapă a lucrării constă în aplicarea filtrului în cuadratură asupra imaginii rezultate
în urma aplicării filtrului Butterworth trece-jos.
În cele ce urmează, se vor prezenta rezultatele filtrelor pe cele 4 direcții aplicate asupra
transformatei Fourier. Filtrul radial pentru lățimea de bandă egală cu 2 este reprezentat în Figura
4.8.
40
Figura 4.2: Spectrul transformatei Fourier
Figura 4.3: Spectrul shiftat al transformatei
Fourier
Figura 4.4: Filtrul
Butteworth trece-jos cu
frecvența de tăiere egală
cu 10 și ordinul egal cu 1
Figura 4.5: Spectrul
transformatei Fourier
Figura 4.6: Spectrul
shiftat al transformatei
Fourier
Figura 4.7: Rezultatul în
urma aplicării inversei
transformatei Fourier
Capitolul 4. Testarea aplicației și rezultate experimentale
Rezultatele filtrului în cuadratură pe direcția 1 sunt:
Rezultatele filtrului în cuadratură pe direcția 2 sunt:
41
Figura 4.9: Rezultatul aplicării
filtrului 1 asupra transformatei
Fourier
Figura 4.10: Rezultatul în urma
shiftării spectrului transformatei
Fourier
Figura 4.11: Rezultatul aplicarii
inversei transformate Fourier
Figura 4.12: Rezultatul aplicării
filtrului 2 asupra transformatei
Fourier
Figura 4.13: Rezultatul în urma
shiftării spectrului transformatei
Fourier
Figura 4.14: Rezultatul aplicarii
inversei transformate Fourier
Figura 4.8: Filtrul radial
pentru lățimea de bandă
egală cu 2
Adelina Ghiuzan
Rezultatele filtrului în cuadratură pe direcția 3 sunt:
Rezultatele filtrului în cuadratură pe direcția 4 sunt:
Rezultatul în urma efectuării sumei dintre cele patru filtre, este următorul:
42
Figura 4.15: Rezultatul aplicării
filtrului 3 asupra transformatei
Fourier
Figura 4.16: Rezultatul în urma
shiftării spectrului transformatei
Fourier
Figura 4.17: Rezultatul aplicarii
inversei transformate Fourier
Figura 4.18: Rezultatul aplicării
filtrului 4 asupra transformatei
Fourier
Figura 4.19: Rezultatul în urma
shiftării spectrului transformatei
Fourier
Figura 4.20: Rezultatul aplicarii
inversei transformate Fourier
Figura 4.21: Rezultatul final
Capitolul 4. Testarea aplicației și rezultate experimentale
Filtrele în cuadratură pot fi reprezentate pe mai multe scări. Această reprezentare se
realizează prin modificarea lățimii de bandă, adaugând o unitate la fiecare scară. Modificarea
lățimii de bandă nu afectează crearea filtrului pe cele 4 direcții, ci doar filtrul radial. Astfel, în
urma modificării filtrului radial există diferențe de la un rezultat la altul.
V om prezenta rezultatele finale pentru lățimea de bandă egală cu 3, 4 și 5.
43
Figura 4.23: Rezultatul filtrului în
cuadratură
Figura 4.22: Filtrul radial cu lățimea de
bandă egală cu 3
Figura 4.24: Filtrul radial cu lățimea de
bandă egală cu 4
Figura 4.25: Rezultatul filtrului în
cuadratură
Adelina Ghiuzan
Pentru a putea utiliza rezultatul filtrului în cuadratură pe mai multe scări în procesul de
segmentare, este necesară o integrare a acestora, conform (21) cu parametrul egal cu 3.
Deoarece în metoda Level Set, este semnificativă doar partea reală a rezultatului integrării, am
ales afișarea componentelor separat.
44
Figura 4.26: Filtrul radial cu lățimea de
bandă egală cu 5
Figura 4.27: Rezultatul filtrului în
cuadratură
Figura 4.28: Partea reală după integrarea
filtrelor în cuadratură
Figura 4.29: Partea imaginară după
integrarea filtrelor în cuadratură
Capitolul 4. Testarea aplicației și rezultate experimentale
4.2.3. Rezultatele metodei Level Set
Primul pas în etapa de segmentare este realizarea conturului inițial de către utilizator.
Pentru reprezentarea rezultatelor, s-a realizat conturul din Figura 4.30 și se folosesc parametrii
din Figura 4.31
Conturul inițial este esențial, deoarece metoda Level Set are ca scop evoluția conturului,
astfel încât să contureze toate vasele de sânge din imagine.
Factorul care este cel mai utilizat în evoluția conturului este gradientul, de aceea pe langă
evoluția conturului la o anumită iterație, vom prezenta și rezultatele gradientului.
Rezultatele metodei Level Set sunt următoarele:
45
Figura 4.31: Parametri
necesari metodei Level
Set
Figura 4.30:
Figura 4.36:
Aplicarea metodei
Level Set asupra
imaginii inițiale
Figura 4.35:
Gradientul funcției
de evoluție pe
direcția Y
Figura 4.34:
Gradientul funcției
de evoluție pe
direcția X
Figura 4.33:
Gradientul funcției
de evoluție
Figura 4.32:
Rezultatul metodei
Level Set la iterația
0
Adelina Ghiuzan
46
Figura 4.37:
Rezultatul metodei
Level Set la iterația
4
Figura 4.38:
Gradientul funcției
de evoluție
Figura 4.39:
Gradientul funcției
de evoluție pe
direcția X
Figura 4.40:
Gradientul funcției
de evoluție pe
direcția Y
Figura 4.41:
Aplicarea metodei
Level Set asupra
imaginii inițiale
Figura 4.42:
Rezultatul metodei
Level Set la iterația
7
Figura 4.43:
Gradientul funcției
de evoluție
Figura 4.44:
Gradientul funcției
de evoluție pe
direcția X
Figura
4.45:Gradientul
funcției de evoluție
pe direcția Y
Figura 4.46:
Aplicarea metodei
Level Set asupra
imaginii inițiale
Figura 4.47:
Rezultatul metodei
Level Set la iterația
12
Figura 4.48:
Gradientul funcției
de evoluție
Figura 4.49:
Gradientul funcției
de evoluție pe
direcția X
Figura 4.50:
Gradientul funcției
de evoluție pe
direcția Y
Figura 4.51:
Aplicarea metodei
Level Set asupra
imaginii inițiale
Figura 4.52:
Rezultatul metodei
Level Set la iterația
23
Figura 4.53:
Gradientul funcției
de evoluție
Figura 4.54:
Gradientul funcției
de evoluție pe
direcția X
Figura 4.55:
Gradientul funcției
de evoluție pe
direcția Y
Figura 4.56:
Aplicarea metodei
Level Set asupra
imaginii inițiale
Capitolul 4. Testarea aplicației și rezultate experimentale
Pentru a observa funcționalitatea metodei Level Set, algoritmul s-a aplicat și asupra
imaginilor următoare:
47
Figura 4.57: Rezultatul final
Figura 4.59: Rezultatul în urma
aplicării metodei Level Set
Figura 4.58: Imagine inițială
Figura 4.60: Imagine inițială
Figura 4.61: Rezultatul în urma
aplicării metodei Level Set
Adelina Ghiuzan
48
Figura 4.62: Imagine inițială
Figura 4.63: Rezultatul în
urma aplicării metodei Level
Set
Concluzii și direcții viitoare de dezvoltare
Concluzii și direcții viitoare de dezvoltare
Scopul acestei lucrări a fost detectarea vaselor de sânge dintr-o imagine medicală
folosind filtre pentru îmbunătățirea calității imaginilor ,evidențierea anumitor trăsaturi pentru o
detecție cât mai bună și segmentarea imaginii folosind o metodă numerică. Lucrarea prezintă o
abordare bazată pe filtrul în cuadratură combinată cu tehnica Level Set de optimizare a unei
funcții de viteză pentru segmentare.
Am ales prelucrarea imaginilor medicale, deoarece acest domeniu este în continuă
cercetare și dezvoltare. În momentul de față, diagnosticul asistat de calculator a devenit o parte
importantă în rutina medicală, dorindu-se în permanență dezvoltarea de noi tehnologii pentru
îmbunătățirea metodelor de procesare a volumelor mari de date, astfel încât să se poată produce
informații de înaltă calitate pentru diagnosticarea bolilor și tratamente.
În urma aplicării filtrelor asupra unei imagini în domeniul frecvențelor, s-au obținut
rezultatele dorite. Filtrul Butterworth trece-jos utilizat pentru îmbunătățirea calității imaginii, a
redus cantitatea de zgomot conținut de imaginea inițială, iar filtrul în cuadratură aplicat pe cele 4
direcții, cu diferite valori pentru lățimea de bandă, a scos în evidență vasele de sânge orientate pe
diferite direcții și de dimensiuni diferite.
Metoda Level Set utilizată, oferă rezultate bune pentru imaginile care nu sunt afectate de
zgomot, reușind detectarea structurilor tubulare existente în imaginea inițială. Această metodă
are urmatoarele avantaje: ca și condiție inițială, soluția depinde doar de inițializarea conturului
realizat în mod arbitrar în imagine, iar calitatea soluției depinde de parametrii ce controlează
evoluția conturului.
Ca și direcții viitoare de dezvoltare, aplicația poate fi îmbunătățită prin implementarea
unor metode de optimizare a numarului de iterații, deoarece în acest moment aplicația nu are o
condiție de stop, efectuând segmentarea pentru numărul de iterații specificat de utilizator. De
asemenea se pot studia mai în detaliu, imaginile afectate de zgomot și imbunătățirea calității
acestora fără a pierde detalii semnificative.
În concluzie, consider că aplicația implementată și-a atins obiectivele și reprezintă un
prim pas în dezvoltarea aplicațiilor utilizate în domeniul medical, urmând pe viitor aprofundarea
noțiunilor medicale și implicațiile necesare în dezvoltarea unei aplicații reale.
49
Adelina Ghiuzan
Bibliografie
[1]Bernd Jähne, „Digital Image Processing”, Springer Berlin Heidelberg New York, 2005.
[2]Rafael C. Gonzalez, Richard E. Woods, „Digital ImageProcessing”, Pearson Education, Inc., 2008.
[3]Carrie Cousins, Vector vs. Raster [Online], Disponibil la adresa:
https://designshack.net/articles/layouts/vector-vs-raster-what-do-i-use/, Accesat: 2018.
[4]Catalina Neghina, Transformări simple ale imaginilor [Online], Disponibil la adresa:
http://web.ulbsibiu.ro/catalina.neghina/Resurse/PI/pdf_PI/L1.pdf, Accesat: 2018.
[5]Automatică și calculatoare, „Procesarea imaginilor”, Laboratoare, , pp. , anul III.
[6]Automatică și Calculatoare, Iași, „Procesarea imaginilor”, Cursuri, , pp. , anul III.
[7]Gunnar Läthén, „Level Set segmentation and volume visualization of vascular trees”, , , pp. , 2013.
[8]OpenCV 2.4.13.6 documentation , Discrete Fourier Transform [Online], Disponibil la adresa:
https://docs.opencv.org/2.4/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transfor
m.html, Accesat: 2018.
[9]Leonardo O Iheme, Frequency Domain Bandpass Filtering for Image Processing [Online],
Disponibil la adresa: https://www.scribd.com/doc/51981950/Frequency-Domain-Bandpass-
Filtering-for-Image-Processing, Accesat: 2018.
[10]Techopedia, C++ Programming Language [Online], Disponibil la adresa:
https://www.techopedia.com/definition/26184/c-programming-language, Accesat: 2018.
[11]The Qt Company, Qt Creator Manual [Online], Disponibil la adresa: http://doc.qt.io/qtcreator/,
Accesat: 2018.
50
Anexe.
Anexe.
Anexa 1.
51
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 [603298] (ID: 603298)
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.
