# 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 ![Exemplo miniO](docs/image-1.png) --- ### ✅ `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 ![benchmark_Figure.png](docs/benchmark_Figure.png) ### 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..