208 lines
5.4 KiB
Markdown
208 lines
5.4 KiB
Markdown
# Face Recognition API 🧠
|
|
|
|
API para comparar duas imagens faciais e verificar se são da mesma pessoa.
|
|
### Estrutura de pastas
|
|
```plain text
|
|
face-api/
|
|
├── app.py # Flask e registra rotas
|
|
├── failed_faces/
|
|
├── imgs/ # imagens de teste
|
|
├── routes/
|
|
│ └── face_routes.py # Define rotas (separado)
|
|
├── services/
|
|
│ └── face_service.py # Comparação de rostos
|
|
├── config/
|
|
│ └── settings.py # Threshold
|
|
├── Dockerfile
|
|
├── docker-compose.yaml
|
|
├── Makefile
|
|
├── requirements.txt
|
|
└── README.md
|
|
```
|
|
|
|
# 🧠 API de Reconhecimento Facial com DeepFace Dlib
|
|
|
|
Esta é uma API minimalista de verificação facial utilizando o modelo `deepface_dlib`, selecionado após benchmark de desempenho e precisão. Ela oferece endpoints simples e eficientes para **registrar imagens** e **comparar faces** com alta acurácia e baixo tempo de resposta.
|
|
|
|
---
|
|
|
|
## 📦 Tecnologias utilizadas
|
|
|
|
- [Python 3.11](https://www.python.org/)
|
|
- [Flask](https://flask.palletsprojects.com/)
|
|
- [DeepFace](https://github.com/serengil/deepface) com backend Dlib
|
|
- [MinIO](https://min.io/) para armazenamento de imagens
|
|
- [face_recognition](https://github.com/ageitgey/face_recognition) para validação facial
|
|
|
|
---
|
|
|
|
## 🚀 Como rodar com Docker
|
|
|
|
```bash
|
|
make devup
|
|
```
|
|
|
|
---
|
|
|
|
## 🌐 Endpoints disponíveis
|
|
|
|
### ✅ `POST /register_face`
|
|
|
|
Registra uma imagem de uma pessoa e salva os metadados (como as posições das faces detectadas) no MinIO.
|
|
|
|
**Parâmetros:**
|
|
- `person_id`: identificador da pessoa
|
|
- `image`: arquivo de imagem (formato `.jpg`, `.png`, etc.)
|
|
|
|
**Exemplo:**
|
|
|
|
```bash
|
|
curl -X POST http://localhost:5006/register_face \
|
|
-F "person_id=fulano" \
|
|
-F "image=@imgs/aa.jpg"
|
|
```
|
|
|
|
**Resposta:**
|
|
|
|
```json
|
|
{
|
|
"image_path": "fulano/20250501-145258.jpg",
|
|
"person_id": "fulano",
|
|
"status": "Face cropped and saved",
|
|
"timestamp": "20250501-145258"
|
|
}
|
|
```
|
|
Exemplo miniO
|
|

|
|
|
|
---
|
|
|
|
### ✅ `POST /checkin`
|
|
|
|
Compara duas imagens e retorna se é a mesma pessoa com base no modelo `deepface_dlib`. Uma imagem está no storage ([aa.jpg](imgs/aa.png)) e a outra é passada pro endpoint ([bb.jpg](imgs/bb.png)).
|
|
|
|
**Parâmetros:**
|
|
- `person_id`: fulano
|
|
- `image`: bb.jpg
|
|
|
|
**Exemplo:**
|
|
|
|
```bash
|
|
curl -X POST http://localhost:5006/checkin \
|
|
-F "person_id=fulano" \
|
|
-F "image=@imgs/bb.jpg"
|
|
```
|
|
|
|
**Resposta:**
|
|
|
|
```json
|
|
{
|
|
"confidence": "high",
|
|
"duration_sec": 0.7338,
|
|
"match": true,
|
|
"person_id": "fulano",
|
|
"similarity_score": 0.9643,
|
|
"threshold": 0.6
|
|
}
|
|
```
|
|
**Ou Resposta com medium score:**
|
|
```json
|
|
{
|
|
"confidence": "medium",
|
|
"duration_sec": 0.4199,
|
|
"match": false,
|
|
"person_id": "fulano",
|
|
"similarity_score": 0.9136,
|
|
"threshold": 0.6
|
|
}
|
|
```
|
|
---
|
|
### ✅ Se houver `match = True`, ele:
|
|
|
|
* ⏱ Salva a data/hora do registro
|
|
|
|
* 📷 Salva a imagem original
|
|
|
|
* 😁 Recorta e salva o rosto detectado
|
|
|
|
* 📝 Gera e salva um .json com:
|
|
Pessoa, IP, tempo de resposta, similaridade, confiança e status do match
|
|
|
|
* * OBS: É interessante, para a vida útil do modelo, que eventualmente seja salvo uma imagem da face nova após realizar um checkin para compor a pasta de faces registradas do indivíduo para garantir mudanças de aparência e garantir assertividade do ponto eletrônico.
|
|
|
|
**Se houver match = False:**
|
|
|
|
* Nada acontece, se quiser pode ser salvo as imagens de tentativa de utilização do ponto para verificar fraudes
|
|
---
|
|
|
|
## 📁 Estrutura esperada no MinIO
|
|
|
|
Ao registrar imagens com `person_id = fulano`, os arquivos são salvos na pasta registred_faces.
|
|
|
|
Ao realizar checkin é salvo arquivos na pasta checkins conforme:
|
|
|
|
```
|
|
data/
|
|
├── registred_faces/
|
|
│ └── ciclano/
|
|
│ └── 20240501-180123.jpg
|
|
│ └── fulano/
|
|
│ └── 20240501-180143.jpg
|
|
├── checkins/
|
|
│ └── fulano
|
|
│ └── data
|
|
│ └── hora
|
|
│ └── metadata.json
|
|
│ └── face.jpg
|
|
│ └── original.jpg
|
|
|
|
```
|
|
|
|
---
|
|
|
|
|
|
## ⚙️ Variáveis de ambiente `.env`
|
|
|
|
```env
|
|
DEBUG=True
|
|
THRESHOLD=0.93
|
|
MINIO_ENDPOINT=minio:9000
|
|
MINIO_BUCKET=data
|
|
MINIO_ACCESS_KEY=admin
|
|
MINIO_SECRET_KEY=password
|
|
|
|
# Faixas de confiança para verificação facial
|
|
CONFIDENCE_HIGH=0.95
|
|
CONFIDENCE_MEDIUM=0.85
|
|
```
|
|
|
|
---
|
|
|
|
## 🛠️ Comandos Makefile
|
|
|
|
```bash
|
|
make devup # Sobe com docker-compose.dev.yaml
|
|
make devdown # Para os containers
|
|
make logs # Logs ao vivo
|
|
```
|
|
|
|
---
|
|
|
|
## 👨🔬 Benchmark e decisão de arquitetura
|
|
|
|
O modelo `deepface_dlib` foi escolhido após benchmarks comparando:
|
|
- Tempo médio por verificação
|
|
- Similaridade média
|
|
- Taxa de acerto
|
|
|
|
Veja o gráfico da média dos resultados comparando 7 imagens diferentes, a linha verde é a acurácia
|
|
|
|

|
|
|
|
### Próximos passos
|
|
* Atualmente o checkin utiliza a ultima imagem registrada, é possível fazer com que ele utilize todas e faça uma média, ou pegue a de melhor score ( é um detalhe complicado de lidar pois pode gerar falsos positivos)
|
|
* Colocar uma etapa de treinamento de modelo após um número de checkins positivo, mapeando o escore de similaridade para que fique sempre acima de 0.95.
|
|
* Colocar um sistema para funcionar offline
|
|
* Colocar um aviso de tentativa de fraude
|
|
* implementar um método que identifica alguém tentando realizar o ponto com uma foto do rosto da pessoa..
|