Documente Academic
Documente Profesional
Documente Cultură
2023
CUPRINS
CAPITOLUL 7. CONCLUZII...................................................................... 17
BIBLIOGRAFIE ............................................................................................ 18
ANEXA 1 ........................................................................................................ 19
i
Capitolul 1. Introducere
2
Capitolul 2. Obiectivele proiectului
3
Capitolul 4. Analiză și fundamentare Teoretică
Toate regiunile pielii (cum ar fi fața, mâinile și brațele) vor apărea mai luminoase decât
regiunea non-piele. Cu toate acestea, este important de reținut că regiunile detectate pot
să nu corespundă neapărat pielii. Singura concluzie certă este că regiunea detectată are
aceeași culoare ca cea a pielii. Deoarece regiunile pielii sunt mai luminoase decât
celelalte părți ale imaginilor, regiunile pielii pot fi separate(segmentate) de restul
imaginii prin utilizarea unui prag. Pentru a procesa imagini ale unor persoane cu piele
diferită, nu putem utiliza un prag cu o valoare fixă. În acest caz este necesar un proces
adaptiv pentru a obține valoarea pragului optim pentru fiecare rulare.
Limitarea adaptivă se bazează pe observația că scăderea valorii pragului poate crește în
mod intuitiv regiunea segmentată. Cu toate acestea, creșterea regiunii segmentate va
scădea treptat (pe măsură ce procentul regiunilor cutanate detectate se apropie de
4
Capitolul 4. Analiză și fundamentare Teoretică
100%), dar va crește brusc atunci când valoarea pragului este considerabil prea mică
pentru a fi incluse și alte regiuni care nu sunt piele. Valoarea prag la care se observă
creșterea minimă a dimensiunii regiunii, în timp ce scade valoarea pragului, va fi pragul
optim. De exemplu valoarea pragului poate fi redusă de la 0,65 la 0,05 în pași de 0,1.
Dacă creșterea minimă are loc atunci când valoarea pragului a fost modificată de la 0,45
la 0,35, atunci pragul optim va fi considerat 0,4.
Eroziunea și dilatarea sunt două operații morfologice opuse care sunt folosite în
procesul de subțiere și lărgire a regiunilor. Eroziunea presupune eliminarea pixelilor
marginali dintr-o regiune, ceea ce permite conturarea mai precisă a unei structuri, cum
ar fi marginile feței, în timp ce dilatarea implică adăugarea de pixeli în jurul unei
regiuni, pentru a o extinde. Aceste operații pot fi utilizate pentru a îmbunătăți
identificarea și delimitarea feței în imagini.
Pentru a determina câte regiuni avem într-o imagine binară se trece la etichetarea
acestor regiuni. O etichetă este o valoare întreagă. Se poate stabili că o vecinătate cu 8
conexiuni (adică toți vecinii unui pixel) determină etichetarea unui pixel. Dacă vreunul
dintre vecini avea o etichetă, etichetăm pixelul curent cu acea etichetă. Dacă nu, atunci
5
Capitolul 4. Analiză și fundamentare Teoretică
𝑏= ∑ 𝑥 ′ 𝑖𝑗 𝑦 ′ 𝑖𝑗 𝐵(𝑖, 𝑗),
𝑖=1,𝑛,𝑗=1,𝑚
𝑐= ∑ (𝑦 ′ 𝑖𝑗 ) 2 𝐵(𝑖, 𝑗)
𝑖=1,𝑛,𝑗=1,𝑚
𝑥 ′ = 𝑥 − 𝑥𝐶 , 𝑦 ′ = 𝑦 − 𝑦𝐶 , iar 𝑥 ′ 𝑖𝑗 , 𝑦 ′ 𝑖𝑗 reprezintă coordonatele pixelului (i,j) al
regiunii.
Prin calculele de mai sus s-a determinat centrul regiunii și înclinația acesteia. Încă
trebuie să determinăm lățimea și înălțimea regiunii pentru a redimensiona fața
șablonului, astfel încât aceasta să aibă aceeași lățime și înălțime ca regiunea noastră.
Imaginea este rotită cu unghiul 𝜃 astfel încât să fie verticală. Acum procedăm la
determinarea înălțimii și lățimii prin deplasarea a 4 indicatori: unul din stânga, dreapta,
sus și jos a imaginii. Dacă găsim o valoare a pixelului diferită de 0, ne oprim și aceasta
este coordonata unei frontiere. Când avem cele 4 valori, calculăm înălțimea (lungimea
axei majore) scăzând valorile de jos și de sus și lățimea (lungimea axei minore) scăzând
valorile din dreapta și din stânga.
Se determinp AR = lg. axa majoră / lg. axa minoră și se rețin doar regiunile pentru care
raportul AR ia valori între 3.5 și 1. Se procedează astfel pentru că, deși raportul
înălțime/lățime al fețelor umane este de aproximativ 1, pentru a se evita eliminările
eronate de fețe în situațiile în care persoana nu are cămașă sau este îmbrăcată în așa fel
încât o parte a gâtului și dedesubt să fie descoperită, s-a stabilit că raportul 3.5 este
potrivit.
6
Capitolul 5. Proiectare de detaliu și implementare
În ultimul pas se potrivește o imagine șablon peste regiunea decisă ca fiind față în
etapele precedente și se obțin coordonatele ce marchează fața.
Astfel, pentru imaginea corespunzătoare regiunii pielii, umplem găurile din regiune și
înmulțim această imagine cu cea originală. Se redimensioneaza fața frontală a
șablonului în funcție de înălțimea și lățimea regiunii calculate în secțiunea anterioară.
Se rotește fața șablonului redimensionat cu unghiul theta, astfel încât fața șablonului să
fie aliniată în aceeași direcție în care este regiunea pielii.
Se calculează centrul feței șablonului, rotit așa cum se arată mai sus.
Se calculează valoarea corelației încrucișate între partea din imagine corespunzătoare
regiunii pielii și fața șablonului procesată și centrată corespunzător.
În mod empiric s-a stabilit că o valoare prag bună pentru clasificarea unei regiuni ca
față este dacă valoarea de autocorelare rezultată este mai mare decât 0,6.
După ce sistemul a decis că regiunea pielii corespunde unei fețe, se marchează fața în
imaginea dată.
2. Segmentarea zonelor
După calcularea medie și a deviației standard putem obține matricea likelihood-
ului: pentru fiecare pixel se calculează distanța euclidiană la media distribuției gausiene
antrenate, se realizează o normalizare și se obține “skin likelihood” și reprezentarea ca
o imagine grayscale.
3. Binarizare
Imaginea rezultată este trimisă la funcția de binarizare adaptivă „Binarizare” ,
care returnează o imagine binarizată a imaginii sursă.
Mat dst = Mat(src.rows, src.cols, CV_8UC1); - Se creează o nouă imagine dst
cu aceleași dimensiuni ca și imaginea de intrare src, dar având un singur canal și pixeli
de tip 8-bit uchar (CV_8UC1). Se determină valorile maxime (imax) și minime (imin)
de intensitate ale pixelilor din imaginea de intrare.
7
Capitolul 5. Proiectare de detaliu și implementare
4. Operatii morfologice
La pasul următor sunt aplicate diferite operații morfologice. In urma rezultatelor
experimentale am ajuns la crearea unei structuri de dimensiune 3x3 și aplicarea a două
dilatări și a 3 eroziunii. Aceste operații sunt implementate in OpenCV ca dilate și erode.
5. Etichetare
Pasul al cincilea constă în etichetarea obiectelor din imagine (colorate în alb).
Funcția se numește LabelingBreadthFirstTraversal și am utilizat Traversarea în lățime.
Aceasta este o metodă directă pentru etichetare, care se bazează pe traversarea în lățime
a grafului format de imaginea binară. Primul pas este inițializarea matricei de etichete
cu valoarea zero pentru toți pixelii, indicând faptul că inițial totul este neetichetat. Apoi,
algoritmul va căuta un pixel de tip obiect care este neetichetat. Dacă acest punct este
găsit, el va primi o etichetă nouă, pe care o va propaga vecinilor lui. Vom repeta acest
proces până când toți pixelii obiect vor primi o etichetă.
Algoritmul este descris de următorul pseudocod:
Structura de date de tip coadă menține lista punctelor care trebuie etichetate cu eticheta
curentă ”label”. Deoarece este o structură FIFO, se va obține traversarea în lățime. Vom
marca nodurile vizitate setând eticheta pentru poziția lor, în matricea de etichete. Dacă
structura de date se schimbă într-o stivă, se va obține o traversare în adâncime. Pentru
afișarea etichetării asociem fiecărei etichete câte o culoare și colorăm imaginea.
Rezultatul este salvat în matricea de întregi globală labels, fiecare pixel din imaginea
sursă are asociat în această imagine câte un label. Variabila globala label memorează
numărul de componente găsite.
8
Capitolul 5. Proiectare de detaliu și implementare
9
Capitolul 5. Proiectare de detaliu și implementare
În imaginea de mai sus este explicat procesul de template Matching după rotirea și
alungirea template-ului reprezentat de pătratul roșu cu centrul în (height/2,height/2).
Imaginea este reprezentata de dreptunghiul negru și punctul (ri,ci) reprezintă centrul
componentei detectate ca față. Astfel putem începe procesul de matching:
Iterăm în șablon începând de la punctul (0,0) pana la punct (height, height) și
comparăm fiecare pixel cu cel de sub el în imaginea originală. Acest pixel poate fi
calculat folosind punctele centrale astfel:
Punct(0,0) în șablon <=> Punct(ri – centru, ci-centru) in imagine
Punct (0,1) în șablon <=> Punct(ri – centru, ci+1 - centru) in imagine
Punctul (1,1) în șablon <=> Punct(ri + 1 – centru, ci+1 - centru) in imagine
10
Capitolul 6. Testare și validare
Testarea v-a fi realizata pe mai multe tipuri de imagini cu mai multe sau mai
puține persoane de diferite etnii, în mai multe condiții de iluminare.
11
Capitolul 6. Testare și validare
Prima imagine de test conține o singura persoana. După construirea unui model
de culoare pentru piele in spațiul Lab obținem a doua imagine în care se poate observa
că pielea are o probabilitate mai mare de fi piele, apoi urmează părul persoanei și umbra
sa, iar cu o probabilitate mica se afla bluza și fundalul. În imaginea a treia se află
imaginea după binarizarea adaptivă, toate zonele cu piele au rămas, dar și o parte din
zona marginală a părului a fost păstrata. În consolă au fost afișate media și deviația
standard calculate împreuna cu distanțele maxime și minime.
12
Capitolul 6. Testare și validare
Funcția template
Matching selectează
fiecare componentă pe
rând și modifică template-
ul în funcție de aceasta.
Putem observa
măsurătorile componentei
în consolă, aceasta are o
lungime de 234 de pixeli și
o lățime de 105 pixeli. Cu Figură 10
Figură 10
un aspect ratio de 2.2 (care
aparține intervalului căutat 1- Figură 10
3.5) și un unghi de -17 grade. Template-ul
modificat poate fi observat in Figura 10.
Template-ul este suprapus peste
imaginea originală și, pentru a observa zona
analizată, am înlocuit pixelii în imaginea
originală cu pixeli albi. Astfel, putem observa
eroarea în contextul imaginii actuale: din cauza
bluzei fără gat, gatul este considerat parte din
față, ceea ce rezultă într-o diferență a pixelilor
prea mare, deci nu este detectată nici o față.
A doua imagine de test conține doua persoane (Figura 11). Figura 10 reprezintă
likelihood-ul. În Figura 9 se află imaginea după binarizarea adaptivă, unde se observă
că toate zonele cu piele au rămas.
13
Capitolul 6. Testare și validare
14
Capitolul 6. Testare și validare
15
Capitolul 6. Testare și validare
16
Capitolul 7. Concluzii
Detectarea feței este un proces non-invaziv și rapid, care permite identificarea unei
fețe dintr-o imagine și localizarea acesteia. În plus, sistemul pe care l-am dezvoltat
poate detecta mai multe fețe în același timp. Beneficiile aduse de dezvoltarea acestei
aplicații sunt multiple, câteva dintre ele fiind următoarele:
-Identificarea automată a fețelor într-o imagine, ceea ce poate fi util în domenii
precum securitatea, monitorizarea și recunoașterea facială.
-Eficientizarea procesului de căutare a fețelor, prin eliminarea nevoii de a căuta
manual într-o imagine.
-Oportunitatea de a îmbunătăți performanța aplicațiilor de realitate augmentată
și de îmbunătățire a imaginii, prin detectarea precisă a fețelor.
Prin urmare, proiectul de detectare a feței bazat pe modelul LAB are potențialul
de a aduce contribuții semnificative în domeniul detecției feței și în domeniile conexe,
ajutând la îmbunătățirea eficienței și preciziei procesului de detecție facială.
17
BIBLIOGRAFIE
[1] http://www-cs-students.stanford.edu/~robles/ee368/skinsegment.html.
[3] Cai, J., & Goshtasby, A. (1999). Detecting human faces in color images. Image and
Vision Computing, 18(1), 63-75.
[4] Cotton, S., Claridge, E., & Hall, P. (1999, July). A skin imaging method based on a
colour formation model and its application to the diagnosis of pigmented skin lesions.
In Proceedings of Medical Image Understanding and Analysis (Vol. 99, pp. 49-52).
Oxford: BMVA.
[5] P. Viola and M. Jones. Rapid object detection using a boosted cascade of simple
features. In Proceed-ings of the 2001 IEEE Computer Society Conference on Computer
Vision and Pattern Recognition.CVPR 2001, volume 1, pages 511–518 vol.1, 20(14)
[6] Hjelmås, E., & Low, B. K. (2001). Face detection: A survey. Computer vision and
image understanding, 83(3), 236-274.
[7] Wang, T., Bu, J. J., & Chen, C. (2003). A color based face detection system using
multiple templates. Journal of Zhejiang University-SCIENCE A, 4(2), 162-165
[8] J. Cai & A. Goshtasby & C. Yu, Detecting Human Faces in Color Images, Wright
State University, U. of Illinois.
18
Anexa 1
Anexa 1
// -----------------------------------PROIECT----------------------------
int histGlobabalaA[260] = { 0 };
int histGlobabalaB[260] = { 0 };
19
Anexa 1
// 2. compute the expection (miu) for both channels for all the samples'
pixels:
double ma = 0;
for (int i = 1; i <= numSamples; i++) {
for (int k = 0; k < 16; k++) {
for (int l = 0; l < 16; l++) {
ma += a_channel[i].at<uchar>(k, l);}}}
ma = ma / (numSamples * 16 * 16);
double mb = 0;
for (int i = 1; i <= numSamples; i++) {
for (int k = 0; k < 16; k++) {
for (int l = 0; l < 16; l++) {
mb += b_channel[i].at<uchar>(k, l);}}}
mb = mb / (numSamples * 16 * 16);
// 3. DEviatia standard:
double devA = 0, devB = 0;
for (int g = 0; g <= 255; g++) {
devA += (g- meanA)*(g-
meanA)*histGlobabalaA[g]/(numSamples * 16 * 16);
}
double devA2 = devA;
devA = sqrt(devA);
20
Anexa 1
double sum = 0;
for (int i = 1; i <= numSamples; i++) {
for (int k = 0; k < 16; k++) {
for (int l = 0; l < 16; l++) {
int x = a_channel[i].at<uchar>(k, l);
sum += (x - ma) * (x - ma);
}
}
}
sum = sum / 16 / 16 / numSamples;
C.at<double>(0, 0) = sum;
//Covariance
sum = 0;
for (int i = 1; i <= numSamples; i++) {
for (int k = 0; k < 16; k++) {
for (int l = 0; l < 16; l++) {
int x = b_channel[i].at<uchar>(k, l);
sum += (x - mb) * (x - mb);
}
}
}
sum = sum / 16 / 16 / numSamples;
C.at<double>(1, 1) = sum;
C.at<double>(0, 1) = 0;
C.at<double>(1, 0) = 0;
/*
Mat Cinv = Mat(2, 2, CV_32FC1);
float determinant = 1 / (C.at<float>(1, 1) * C.at<float>(0, 0) -
C.at<float>(0, 1) * C.at<float>(1, 0));
Cinv.at<float>(0, 0) = determinant * (C.at<float>(1, 1));
Cinv.at<float>(1, 0) = -determinant * (C.at<float>(1, 0));
Cinv.at<float>(0, 1) = -determinant * (C.at<float>(1, 0));
Cinv.at<float>(1, 1) = determinant * (C.at<float>(0, 0));
21
Anexa 1
}
}
22
Anexa 1
return dst2;
}
23
Anexa 1
}
medMin = medMin / x;
medMax = medMax / (height * width - x);
lastT = trashhold;
trashhold = (medMax + medMin) / 2;
}
return dst;
}
label = 0;
labels = (int**)calloc((height + 1), sizeof(int*)); /* GLOBAL
VARIABLE*/
for (int i = 0; i < height + 1; i++) {
labels[i] = (int*)calloc((width + 1), sizeof(int));
}
24
Anexa 1
std::queue<Point2i> Q;
labels[i][j] = label;
Q.push(Point2i(i, j));
while (!Q.empty()) {
Point2i q = Q.front();
Q.pop();
for (int k = 0; k < 8; k++) { // pt fiecare
din cei 8 vecini
Point n = Point(q.x + di[k], q.y +
dj[k]);
if (isInside(src, n.x, n.y) == true)
{
uchar neighbors =
src.at<uchar>(n.x, n.y);
if (neighbors == 255 &&
labels[n.x][n.y] == 0) { // color neighbor
labels[n.x][n.y] =
label;
Q.push(n);
}
}
}
}
}
}
}
std::vector<Vec3b> colors;
std::default_random_engine eng;
std::uniform_int_distribution<int> d(0, 255);
25
Anexa 1
bitwise_not(src, src);
bitwise_and(src, singleLevelHoles, multipleLevelHoles);
return result;
}
26
Anexa 1
/*std::stringstream ss;
ss << i;
std::string stringValue = ss.str();
imshow(stringValue, comp);*/
27
Anexa 1
//-------------------Axe:
struct ElongationResults {
double majorAxis;
double minorAxis;
double angle; // unghi aza de alongatie
int ri; //rows pentru centrul de greutate
int ci; // cols ----
};
ElongationResults result;
std::vector<std::vector<cv::Point>> contours;
cv::findContours(binaryImage, contours, cv::RETR_EXTERNAL,
cv::CHAIN_APPROX_SIMPLE);
// Find the minimum area bounding rectangle for the largest contour
(assumed to be the object)
cv::RotatedRect boundingBox = cv::minAreaRect(contours[0]);
cout << endl << "Major axis: " << majorAxis << " Minor axis: " <<
minorAxis << endl;
28
Anexa 1
// axe:
ElongationResults result = calculateElongations(src);
// SHOW:
printf("%f", slope);
29
Anexa 1
return result;
}
// -----------------TeamplateMatching:
30
Anexa 1
31
Anexa 1
if (pixelTemp != 0 &&
isInside(originalImage, i + result.ri - c, j + result.ci - c)) { // pixelTEmp !=0 => parte
din fata
uchar pixelImg =
originalImage.at<uchar>(i + result.ri - c, j + result.ci - c);
originalImage.at<uchar>(i +
result.ri - c, j + result.ci - c) = 255;
double diference = abs(pixelTemp
- pixelImg);
medie += diference;
nr++;
}
}
}
imshow("final", originalImage);
medie = (double)medie / nr;
printf("\n Diferenta intensitatilor: %f\n", medie);
if (medie < THRESHOLD_FACE) {
cout << "BUN!!";
DrawCross(color, Point(result.ci, result.ri), 9,
Scalar(0, 0, 255), 1);
}
else {
cout << "RAU!!";
}
}
}
void test() {
char fname[MAX_PATH];
while (openFileDlg(fname))
{
Mat image = imread(fname, IMREAD_COLOR);
//imshow("input image", image); // !!!!!!!!!!!!
int height = image.rows;
int width = image.cols;
Mat imgLAB = Mat(height, width, CV_8UC3);
// Post. Aplicare FTJ gaussian pt. eliminare zgomote: essential
sa il aplicati
//GaussianBlur(image, image, Size(5, 5), 0, 0);
32
Anexa 1
cv::split(imgLAB, channels);
cv::Mat L_channel = channels[0];
cv::Mat a_channel = channels[1];
cv::Mat b_channel = channels[2];
//imshow("A:", a_channel); imshow("B:", b_channel);
Mat likelihood =
processAndDisplayImages("D:\\an4\\IOC\\proiect\\sampleset\\", 13, a_channel,
b_channel);
imshow("1+2. Likelihood Image:", likelihood); // !!!!!!!!!!!!
// 3. Binarizare adaptiva
Mat binarizare = Binarizare(likelihood);
double threshold = 180;
imshow("3. Binarizare adaptiva:", binarizare); // !!!!!!!!!!!!
// 4. Operati morfologice
Mat element = getStructuringElement(MORPH_RECT, Size(3,
3));
// 5. Etichetare:
Mat etich = LabelingBreadthFirstTraversal(binarizare);
imshow("5. Etichetare: ", etich);
waitKey();
}
}
33