AWS REKOGNITION - Compare Faces (Comparação de Rostos)
O que é esta operação?
A operação compareFaces do AWS Rekognition é responsável por comparar rostos entre duas imagens e determinar se pertencem à mesma pessoa com base em similaridade facial.
Por que esta operação existe?
Verificação manual de identidade é lenta e propensa a erros. O Rekognition compareFaces existe para:
- Verificação de Identidade: Confirmar se foto enviada corresponde à foto cadastrada
- Controle de Acesso: Validar identidade antes de permitir entrada
- Prevenção de Fraude: Detectar tentativas de usar fotos de outras pessoas
- Onboarding Digital: Automatizar verificação KYC (Know Your Customer)
- Autenticação Biométrica: Substituir senhas por reconhecimento facial
Como funciona internamente?
Código interno (aws-rekognition.executor.ts:118-153):
private async compareFaces(client: RekognitionClient, data: any, context: ExecutionContext): Promise<any> {
const sourceImage = data.sourceS3Bucket && data.sourceS3Key
? {
S3Object: {
Bucket: this.replaceVariables(data.sourceS3Bucket, context.variables),
Name: this.replaceVariables(data.sourceS3Key, context.variables),
},
}
: {
Bytes: Buffer.from(this.replaceVariables(data.sourceImageBytes, context.variables), 'base64'),
};
const targetImage = data.targetS3Bucket && data.targetS3Key
? {
S3Object: {
Bucket: this.replaceVariables(data.targetS3Bucket, context.variables),
Name: this.replaceVariables(data.targetS3Key, context.variables),
},
}
: {
Bytes: Buffer.from(this.replaceVariables(data.targetImageBytes, context.variables), 'base64'),
};
const command = new CompareFacesCommand({
SourceImage: sourceImage,
TargetImage: targetImage,
SimilarityThreshold: data.similarityThreshold || 80,
});
const response = await client.send(command);
return {
faceMatches: response.FaceMatches || [],
unmatchedFaces: response.UnmatchedFaces || [],
matchCount: response.FaceMatches?.length || 0,
};
}
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| operation | string | Sim | Deve ser "compareFaces" |
| config | object | Sim | Credenciais AWS |
| sourceS3Bucket | string | Condicional | Bucket da imagem de referência |
| sourceS3Key | string | Condicional | Chave da imagem de referência |
| sourceImageBytes | string | Condicional | Base64 da imagem de referência |
| targetS3Bucket | string | Condicional | Bucket da imagem para comparar |
| targetS3Key | string | Condicional | Chave da imagem para comparar |
| targetImageBytes | string | Condicional | Base64 da imagem para comparar |
| similarityThreshold | number | Não | Limiar de similaridade 0-100 (padrão: 80) |
| responseVariable | string | Sim | Variável para armazenar resultado |
Exemplo: Verificação de Identidade KYC
{
"name": "Verificação KYC - Comparação Facial",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Instrução",
"parameters": {
"message": "🔐 Verificação de Identidade\n\nTire uma selfie para confirmar sua identidade."
}
}
},
{
"id": "media_1",
"type": "media",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Capturar Selfie",
"parameters": {
"message": "📸 Envie sua selfie:",
"variableName": "currentPhoto",
"mediaType": "image"
}
}
},
{
"id": "rekognition_1",
"type": "aws_rekognition",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Comparar com Cadastro",
"operation": "compareFaces",
"config": {
"region": "us-east-1",
"accessKeyId": "YOUR_ACCESS_KEY_ID",
"secretAccessKey": "YOUR_SECRET_ACCESS_KEY"
},
"sourceS3Bucket": "kyc-documents",
"sourceS3Key": "users/{{userId}}/id-photo.jpg",
"targetImageBytes": "{{currentPhoto}}",
"similarityThreshold": 90,
"responseVariable": "comparison"
}
},
{
"id": "condition_1",
"type": "condition",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Verificar Match",
"parameters": {
"variableA": "{{comparison.matchCount}}",
"operator": "greaterThan",
"variableB": "0"
}
}
},
{
"id": "message_success",
"type": "message",
"position": { "x": 1100, "y": 50 },
"data": {
"label": "Identidade Confirmada",
"parameters": {
"message": "✅ IDENTIDADE VERIFICADA!\n\nVocê foi autenticado com sucesso.\nBem-vindo de volta!"
}
}
},
{
"id": "message_fail",
"type": "message",
"position": { "x": 1100, "y": 150 },
"data": {
"label": "Falha na Verificação",
"parameters": {
"message": "❌ VERIFICAÇÃO FALHOU\n\nNão foi possível confirmar sua identidade.\n\nPor favor:\n• Certifique-se de boa iluminação\n• Remova óculos/máscara\n• Tente novamente"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1300, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "media_1" },
{ "source": "media_1", "target": "rekognition_1" },
{ "source": "rekognition_1", "target": "condition_1" },
{ "source": "condition_1", "target": "message_success", "label": "true" },
{ "source": "condition_1", "target": "message_fail", "label": "false" },
{ "source": "message_success", "target": "end_1" },
{ "source": "message_fail", "target": "end_1" }
]
}
Resposta do Node
{
"faceMatches": [
{
"Similarity": 95.7832,
"Face": {
"BoundingBox": {},
"Confidence": 99.9
}
}
],
"unmatchedFaces": [],
"matchCount": 1
}
Boas Práticas
✅ SIM:
- Use similarityThreshold: 90+ para verificações de segurança
- Use similarityThreshold: 80-85 para uso geral
- Verifique matchCount > 0 para confirmar match
- Armazene imagem de referência no S3 para performance
- Combine com detectFaces para validar qualidade antes
❌ NÃO: - Não use threshold muito baixo (<70) - alto risco de falsos positivos - Não compare imagens de baixa qualidade - Não assuma 100% de precisão - sempre permita recurso manual
Dicas
💡 Dica 1: Similaridade >95% indica forte probabilidade de ser a mesma pessoa.
💡 Dica 2: Valores 80-90% exigem validação adicional (segunda foto, documento).
💡 Dica 3: Para máxima segurança, combine com liveness detection (piscar olhos).