8. Reconeixement facial
1. Detecció de Cares
Si volem detectar cares hauriem de entrenar un model de yolo per a aquesta tasca, però com que ja existeixen molts models preentrenats per a aquesta tasca, podem utilitzar un d'aquests models.
Al següent repositori de GitHub podem trobar un model preentrenat per a la detecció de cares https://github.com/akanametov/yolo-face
Aquest repositori resulta molt interessant ja que ens ofereix no sols el model entrenat sinò el codi de com fer l'entrenament. A més a més te models entrenats per a detecció de persones, treballadors, jugadors de futbol, drons, etc.
2. HaarCascade
La detecció de rostres amb Haar Cascadeés un mètode eficaç utilitzat en visió artificial i processament d’imatges. Proposat per Paul Viola i Michael Jones el 2001, aquest mètode es basa en classificadors en cascada entrenats amb funcions de Haar:
- Es necessita un conjunt d’imatges positives (rostres) i negatives (sense rostres) per entrenar el classificador.
- Les característiques de Haar són com nuclis convolucionals que s’apliquen a la imatge.
- Les imatges integrals simplifiquen el càlcul de característiques.
Per sort podem trobar models de classificació entrenats ja a https://github.com/opencv/opencv/tree/master/data/haarcascades
2.1. Funcionament bàsic del Haar Cascade:
En lloc d'analitzar cada píxel individualment (el qual seria lentíssim), l'algoritme utilitza característiques de Haar. Aquestes són essencialment "finestres" amb quadrats blancs i negres que es desplacen sobre la imatge. L'algoritme busca contrastos de llum i ombra.
Exemple en una cara: La regió dels ulls sol ser més fosca que la part superior de les galta, i el pont de la nasal és més clar que els costats. L'algoritme busca aquests patrons específics.
2.2. Cascade (Cascada)?
Es diu així per eficiència. Imagina que tens una foto d'un paisatge i busques una cara:
- La imatge es divideix en milers de petites finestres.
- La Cascada: L'algoritme aplica una sèrie de filtres ràpids. Si una finestra no té res que s'assembli a un ull (fase 1), es descarta de seguida.
- Si passa la primera prova, passa a la segona, i després a la tercera... així fins a completar centenars d'etapes.
Resultat: No perd temps processant el fons (el cel, arbres, etc.) i es concentra només on realment hi ha trets humans.
3. Implementació amb OpenCV:
OpenCV proporciona un classificador preentrenat per a la detecció de rostres mitjançant Haar Cascade. Pots utilitzar-lo amb la funció cv2.CascadeClassifier.
Existeixen diferents classificadors, com a ulls, somriures i fins i tot matrícules de cotxe. Pots trobar-los a la carpeta data/haarcascades dins de la instal·lació d'OpenCV i al repositori de GitHub d'OpenCV https://github.com/opencv/opencv/tree/master/data/haarcascades.
El següent codi comentat mostra com es fa la detecció
Funcionament del classificador amb Python
Alguns paràmtres de la crida a detectMultiScale:
-
gray_image- La imatge on busquem les cares.- L'algoritme de Haar Cascade no necessita color. De fet, el color el confon i el fa més lent.
- Requisit: Ha de ser una imatge en escala de grises (8-bit).
- Per què: L'algoritme busca contrastos d'intensitat (brillantor), no matisos de blau o vermell.
-
scaleFactor(1.1) - Paràmetre de compensació d'escala.- Com una cara pot estar a prop de la càmera (gran) o lluny (petita), l'algoritme redimensiona la imatge diverses vegades per intentar trobar-la.
- Què fa l'1.1?: Indica que la imatge es redueix un 10% en cada pas d'escala.
- Valors típics:
- 1.05: Molt lent però molt precís (detecta cares a moltes distàncies).
- 1.1 a 1.3: Equilibri estàndard entre velocitat i precisió.
- 1.5+: Molt ràpid, però pot "saltar-se" cares que no encaixint exactament en aquests tamanys.
-
minNeighbors(5) - Filtre de qualitat.- Controla quants "rectangles candidats" han de detectar-se a prop d'un objecte perquè l'algoritme digui: "Sí, això és una cara".
- Funcionament: L'algoritme solen trobar moltes deteccions falses. Si poses un 5, li estàs dient: "Només confía si almenys 5 finestres diferents coincideixen que aquí hi ha una cara".
- Efecte:
- Baix (3): Detecta moltes cares, però també molts objectes que no ho són (falsos positius).
- Alt (10+): Molt selectiu. Només detecta cares molt clares, però pot ignorar-ne algunes si la il·luminació no és perfecta.
-
minSize=(40, 40)- Tamany mínim.- Estableix el tamany més petit (en píxels) en el qual una cara pot ser detectada.
- Utilitat: Si saps que l'usuari no estarà a 10 metres de la càmera, no té sentit buscar quadrets de 10x10 píxels.
- Benefici: Estalvia molta capacitat de processament i evita que el soroll del fons (punts petits) es confongui amb rostres.
4. Treball pràctic. Reconeixement facial
Anem a fer una pràctica de reconeixemnet facial. Possibles cassos d'ús d'aquest projecte serien:
- Accés a la feina, treball
- Control d'assistència
- Detecció de gent no autoritzada
5. Llibreria face-recognition
La llibreria face_recognition és una eina de reconeixement facial en Python que utilitza la tecnologia de deep learning per identificar i verificar rostres en imatges i vídeos. Aquesta llibreria es basa en el model de reconeixement facial d'OpenFace, que és un model de xarxa neuronal convolucional entrenat per reconèixer rostres amb alta precisió. Ens respon a "De qui és esta cara?".
El procés de reconeixement facial amb face_recognition es pot dividir en quatre passos principals:
- Detecció i Alineació (Pre-processat) Abans de reconèixer algú, hem de trobar la cara i "posar-la recta".
- Detecció: Es localitza la cara (normalment amb els mètodes que hem vist abans).
- Alineació: Si la persona té el cap una mica inclinat, l'algoritme busca punts de referència (ulls, nas, boca) i rota la imatge perquè els ulls estiguin sempre en la mateixa posició horitzontal. Això facilita molt la comparació posterior.
- Extracció de Característiques (Deep Metric Learning) Aquesta és la part més important. No guardem la foto de la persona, sinó una signatura digital. Es passa la imatge per una xarxa neuronal (com FaceNet o ResNet). La xarxa analitza mides: la distància entre els ulls, l'amplada del nas, la profunditat de la mandíbula, etc. El resultat: Una llista de 128 (o 512) números decimals. Això s'anomena Embedding o vector de característiques.
Concepte clau: Un embedding és una representació numèrica on cares de la mateixa persona generen números similars, i cares de persones diferents generen números molt distants.
- L'entrenament amb Triplet Loss Com sap la xarxa neuronal quins números assignar? Durant el seu entrenament s'utilitza una tècnica anomenada Triplet Loss: Es tria una foto d'una persona (Anchor). Es tria una altra foto de la mateixa persona (Positive). Es tria una foto d'una persona diferent (Negative). L'algoritme s'ajusta fins que la distància matemàtica entre Anchor i Positive és mínima, i la distància amb el Negative és màxima. (Aquesta part ja la tindrem feta, ja que utilitzarem un model preentrenat).
- Comparació (Classification) Un cop tens el vector de números de la cara desconeguda, el compares amb la teva base de dades: Es calcula la distància euclidiana (la línia recta en un espai multidimensional) entre el vector nou i els que ja tens guardats. Si la distància és menor a un llindar "És un match!".
6. Treballem amb la llibreria face_recognition:
Primer de tot, hem d'instal·lar la llibreria:
| Bash | |
|---|---|
Sols pel fet de carregar la llibreria no tenim prou, ja que necessitem els models preentrenats. Malauradament, la llibreria no els inclou, així que cal descarregar-los amb:
| Bash | |
|---|---|
Això baixarà els models al teu entorn a .venv/lib/python3.10/site-packages/face_recognition_models/models/. Què estàs instal·lant exactament?
- HOG Face Detector: El model que localitza on són les cares.
- 68-point Face Landmark Predictor: El que troba els punts dels ulls, celles, etc., per poder alinear la cara.
- Face Recognition Model: La xarxa neuronal ja entrenada que sap convertir una cara en el vector de 128 números (embedding).
- CNN Face Detector: Una versió més lenta però més precisa basada en Deep Learning.
Al nostre programa podem utilitzar la llibreria per a detectar i reconèixer cares. Aquí tens un exemple bàsic de com utilitzar-la. Veurem un bloc de codi comentat que detecta i reconeix cares en una imatge:
Anem a estudiar amb més detall els elements que ens retonene els mètodes de la llibreria per veure que podem fer amb ells:
face_locations = face_recognition.face_locations(image)aquesta línia retorna una llista de coordenades (top, right, bottom, left) per a cada cara detectada a la imatge. Aquestes coordenades indiquen la posició de cada cara dins de la imatge. Son les ja conegudes Bounding Boxes. Amb aixo podriem dibuixar rectangles al voltant de les cares detectades.known_face_encoding = face_recognition.face_encodings(known_image)[0]aquesta línia retorna un vector de 128 números (embedding) que representa les característiques úniques de la cara coneguda. Aquest vector és el que utilitzarem per comparar amb les cares detectades a la imatge.unknown_face_encodings = face_recognition.face_encodings(image, face_locations)aquesta línia retorna una llista de vectors de 128 números (embeddings) per a cada cara detectada a la imatge. Cada vector representa les característiques úniques de cada cara detectada.results = face_recognition.compare_faces([known_face_encoding], unknown_face_encoding)aquesta línia compara el vector de la cara coneguda amb el vector de la cara detectada i retorna una llista de valors booleans. Si el valor ésTrue, significa que la cara detectada coincideix amb la cara coneguda, i si ésFalse, significa que no coincideixen.
Resulta molt interessant si tenim una base de dades amb els embeddings de les cares conegudes, ja que podríem comparar cada cara detectada amb tots els embeddings de la base de dades per veure si hi ha alguna coincidència. Això ens permetria reconèixer múltiples persones en una sola imatge.
Seria una cosa com aquesta. Primerament imagina que em carregat les imatges de n persones i hem obtingut els seus embeddings. Podriem guardar aquests embeddings en un diccionari on la clau sigui el nom de la persona i el valor sigui l'embedding corresponent. Després, quan detectem cares a una nova imatge, podríem comparar cada cara detectada amb tots els embeddings del diccionari per veure si hi ha alguna coincidència.
| Python | |
|---|---|
Ara hem de llegir la imatge que volem analitar i detectar les cares que hi ha a la imatge. Un cop tenim les cares detectades, obtenim els seus embeddings i els comparem amb els embeddings de les cares conegudes per veure si hi ha alguna coincidència.