Esta aplicação é um Proof of Concept (POC) para um sistema de autenticação baseado em reconhecimento facial. O frontend é responsável por extrair os descritores faciais durante o registro, armazenando três descritores por indivíduo. O backend, além de salvar esses descritores no banco de dados, realiza a verificação utilizando Distância Euclidiana ou Similaridade do Cosseno para calcular a proximidade entre os pontos salvos e os pontos da tentativa de autenticação.
- Obs. os dados são retonados para o frontend somente para realizar a visualização do gráfico de similaridade, se for usar em produção vá até o componente "js/main/Main.js" e altere "const debugEnabled" para false
A precisão do reconhecimento pode ser ajustada através do parâmetro $threshold. Por padrão, um valor de 0.6 (60%) é utilizado, mas pode ser configurado para 0.9 (90%) para tornar o reconhecimento mais rigoroso e preciso.
A aplicação é composta por um cliente web e um servidor backend, que se comunicam por meio de uma API RESTful.
- Frontend:
HTML + CSS + JavaScript (ES6) Uso da biblioteca face-api.js para extração dos descritores faciais Comunicação com o backend via fetch API e JSON
- Backend:
PHP 8+ seguindo o padrão PSR-4 Banco de dados MySQL API REST estruturada para manipulação dos dados Implementação dos algoritmos Distância Euclidiana e Similaridade do Cosseno para o reconhecimento facial
- Segurança:
Os descritores faciais são criptografados antes de serem armazenados Autenticação baseada na correspondência dos descritores com um limiar de similaridade configurável
- O que são Descritores Faciais? Os descritores faciais são vetores numéricos gerados a partir dos pontos-chave do rosto de um indivíduo. Eles representam características únicas da face, permitindo que um modelo de IA compare diferentes rostos.
Durante o registro, um vetor de descritores é gerado para cada usuário e armazenado no banco de dados. Na autenticação, um novo vetor é gerado e comparado com os vetores armazenados, utilizando um dos algoritmos disponíveis:
Distância Euclidiana: Mede a proximidade entre dois vetores de descritores. Quanto menor a distância, maior a similaridade entre os rostos.\n Similaridade do Cosseno: Mede o ângulo entre dois vetores. Valores próximos de 1 indicam alta similaridade, enquanto valores próximos de 0 indicam baixa similaridade. Exemplo de um descritor facial:
[
0.123, -0.456, 0.789, -0.321, 0.654, -0.987, 0.432, -0.210, ...
]
A Distância Euclidiana recebe seu nome do matemático grego Euclides, que formulou os fundamentos da geometria euclidiana. É uma métrica para medir a "linha reta" entre dois pontos em um espaço n-dimensional.
A Distância Euclidiana é amplamente utilizada em:
- Reconhecimento Facial (comparação de descritores faciais);
- Busca de Similaridade (comparação entre imagens, textos, etc.);
- Análise de Clusters (método K-Means);
- Sistemas de Recomendação (medida de proximidade entre preferências de usuários).
A fórmula da Distância Euclidiana em um espaço n-dimensional é:
[ d(A, B) = \sqrt{ \sum_{i=1}^{n} (A_i - B_i)^2 } ]
Exemplo prático: Se tivermos dois pontos A e B no espaço 3D:
[ A(3, 4, 5), B(1, 1, 1) ]
A distância será:
[ d(A, B) = \sqrt{(3-1)^2 + (4-1)^2 + (5-1)^2} ] [ d(A, B) = \sqrt{4 + 9 + 16} = \sqrt{29} = 5.39 ]
No PHP, poderíamos calcular com:
function euclideanDistance(array $vec1, array $vec2): float {
$sum = 0.0;
for ($i = 0; $i < count($vec1); $i++) {
$sum += pow($vec1[$i] - $vec2[$i], 2);
}
return sqrt($sum);
}A Similaridade do Cosseno surgiu na área de recuperação de informações e mineração de dados. É baseada no cálculo do ângulo entre dois vetores, em vez da distância absoluta entre eles.
A Similaridade do Cosseno é útil em:
- Processamento de Linguagem Natural (reconhecimento de similaridade entre textos);
- Busca de Similaridade em Bancos de Dados;
- Sistemas de Recomendação;
- Reconhecimento Facial (como alternativa à distância euclidiana quando os dados precisam ser normalizados).
A fórmula da Similaridade do Cosseno é:
[ S(A, B) = \frac{ A \cdot B }{ ||A|| \times ||B|| } ]
Onde:
- ( A \cdot B ) é o produto escalar dos vetores;
- ( ||A|| ) e ( ||B|| ) são as normas (magnitude) dos vetores;
- O resultado varia de -1 (totalmente opostos) a 1 (idênticos).
Exemplo prático: Se tivermos os vetores:
[ A(3, 4, 5), B(1, 1, 1) ]
Primeiro, calculamos o produto escalar:
[ A \cdot B = (3 \times 1) + (4 \times 1) + (5 \times 1) = 3 + 4 + 5 = 12 ]
Agora, as magnitudes:
[ ||A|| = \sqrt{3^2 + 4^2 + 5^2} = \sqrt{50} ] [ ||B|| = \sqrt{1^2 + 1^2 + 1^2} = \sqrt{3} ]
Finalmente, a similaridade:
[ S(A, B) = \frac{12}{\sqrt{50} \times \sqrt{3}} \approx 0.98 ]
No PHP, implementamos assim:
function cosineSimilarity(array $vec1, array $vec2): float {
$dotProduct = array_sum(array_map(fn($a, $b) => $a * $b, $vec1, $vec2));
$magnitudeA = sqrt(array_sum(array_map(fn($a) => $a * $a, $vec1)));
$magnitudeB = sqrt(array_sum(array_map(fn($b) => $b * $b, $vec2)));
return ($magnitudeA * $magnitudeB) == 0 ? 0 : $dotProduct / ($magnitudeA * $magnitudeB);
}| Métrica | Distância Euclidiana | Similaridade do Cosseno |
|---|---|---|
| Base Teórica | Distância geométrica | Ângulo entre vetores |
| Valores Possíveis | ([0, \infty]) | ([-1,1]) |
| Sensível à Magnitude? | Sim | Não |
| Melhor para... | Análise espacial, clustering | NLP, recomendação |
- Use Distância Euclidiana para clustering e agrupamentos.
- Use Similaridade do Cosseno para comparação de perfis e sistemas de recomendação.
- Suporte a múltiplos algoritmos: O sistema pode alternar entre Distância Euclidiana e Similaridade do Cosseno dinamicamente.
- Criptografia dos descritores: Os dados faciais são armazenados de forma segura.
- Alta precisão configurável: O sistema pode ser ajustado para diferentes níveis de sensibilidade no reconhecimento.
- Estrutura modular e escalável: Utiliza PSR-4 no backend, facilitando a manutenção e escalabilidade.
- PHP 8+
- MySQL
- Composer (para gerenciamento de dependências)
Instalação Clone o repositório:
git clone https://github.com/faustinopsy/faceIDPHP.git
cd faceIDPHP
Instale as dependências do Composer:
composer install
Configure o arquivo .env: Copie o arquivo .env.example para .env:
cp .env.example .env
Edite o arquivo .env com as configurações desejadas, como o algoritmo de similaridade e as credenciais do banco de dados:
CHAVE_CRIPTOGRAFIA=MinhaChaveUltraSecreta123456
SIMILARIDADE=false # true para Similaridade do Cosseno, false para Distância Euclidiana
DATABASE_NAME=faceid
DATABASE_HOST=localhost
DATABASE_USER=root
DATABASE_PASSWORD=
Crie o banco de dados: Execute o seguinte script SQL para criar o banco e as tabelas:
CREATE DATABASE faceid;
USE faceid;
CREATE TABLE `users` (
`id` varchar(300) NOT NULL,
`nome` varchar(145) DEFAULT NULL,
`registro` varchar(45) DEFAULT NULL,
`email` varchar(245) DEFAULT NULL,
`senha` text,
`last_attempt` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE TABLE `faces` (
`id` varchar(300) NOT NULL,
`idusers` varchar(300) DEFAULT NULL,
`faces` longtext,
KEY `fk_faces_idx` (`idusers`)
);
o id não será auto incrementos, pois existe uma função para criar o UUID:
public function generateUUIDv4(){
$data = random_bytes(16);
$data[6] = chr((ord($data[6]) & 0x0f) | 0x40);
$data[8] = chr((ord($data[8]) & 0x3f) | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
Inicie o servidor PHP:
php -S localhost:8000
Acesse a aplicação Abra o navegador em :
http://localhost:8000
Similaridade: No arquivo .env, defina SIMILARIDADE=true para usar Similaridade do Cosseno ou false para Distância Euclidiana. Banco de Dados: Ajuste as configurações do banco no .env (nome, host, usuário e senha) conforme necessário.
