Face SDK

Documentação técnica para desenvolvedores

🚀 Instalação e Setup

1. Instalação do Pacote

npm install @letmeinbr/face-sdk

2. Compatibilidade

  • Chrome 90+ ✅
  • Firefox 88+ ✅
  • Safari 14+ ✅
  • Edge 90+ ✅

3. Importação

import { FaceSDK } from '@letmeinbr/face-sdk';

// Inicialização básica
const sdk = new FaceSDK();

// Com configurações
const sdk = new FaceSDK({
  language: 'pt-BR',
  debug: true,
  cacheEnabled: true
});

⚙️ Inicialização

Setup Básico

import { FaceSDK } from '@letmeinbr/face-sdk';

// 1. Criar instância
const faceSDK = new FaceSDK({
  language: 'pt-BR',
  debug: false
});

// 2. Aguardar carregamento do modelo
await faceSDK.initialize();

// 3. Pronto para usar
console.log('SDK inicializado!');

Com Cache

💡 Cache Automático: O modelo (30MB) é automaticamente cachado no IndexedDB para carregamento instantâneo nas próximas utilizações.

// O modelo é automaticamente cachado
const faceSDK = new FaceSDK({
  cacheEnabled: true  // Padrão: true
});

// Primeira execução: baixa modelo
// Próximas execuções: carrega do cache

Eventos de Inicialização

faceSDK.on('model:loading', (progress) => {
  console.log(`Carregando: ${progress}%`);
});

faceSDK.on('model:cached', () => {
  console.log('Modelo carregado do cache');
});

faceSDK.on('model:loaded', () => {
  console.log('Modelo pronto para uso');
});

🔧 Configuração

Opções do Constructor

Opção Tipo Padrão Descrição
language string 'pt-BR' Idioma das mensagens (pt-BR, en-US, es-ES)
debug boolean false Ativar logs detalhados
cacheEnabled boolean true Cachear modelo no IndexedDB
modelUrl string CDN padrão URL customizada para o modelo

Configuração Dinâmica

// Alterar idioma
faceSDK.setLanguage('en-US');

// Ativar debug
faceSDK.setDebug(true);

// Configurar callbacks
faceSDK.setConfig({
  onProgress: (progress) => updateUI(progress),
  onError: (error) => handleError(error)
});

🎯 Presets de Validação

O SDK inclui 4 presets otimizados para diferentes cenários:

📱 Selfie (Padrão)

Uso: Fotos tiradas pelo usuário

  • Tolerância média a qualidade
  • Aceita pequenos borrados
  • Iluminação flexível
faceSDK.setPreset('selfie');

📄 Document

Uso: Fotos de documentos oficiais

  • Alta exigência de qualidade
  • Fundo neutro obrigatório
  • Iluminação uniforme
faceSDK.setPreset('document');

🔒 High Security

Uso: Aplicações de alta segurança

  • Máxima exigência
  • Anti-spoofing rigoroso
  • Múltiplas validações
faceSDK.setPreset('highSecurity');

😊 Relaxed

Uso: Testes e desenvolvimento

  • Baixa exigência
  • Aceita qualidade inferior
  • Boa para testes
faceSDK.setPreset('relaxed');

Preset Personalizado

faceSDK.setCustomPreset({
  minFaceSize: 100,
  maxFaceSize: 800,
  minBrightness: 50,
  maxBrightness: 200,
  minSharpness: 30,
  requireEyesOpen: true,
  allowGlasses: false,
  allowMask: false,
  backgroundAnalysis: true,
  antiSpoofing: true
});

✅ Validação de Imagens

Validação Básica

// De arquivo
const file = document.getElementById('input').files[0];
const result = await faceSDK.validateFile(file);

// De Canvas
const canvas = document.getElementById('canvas');
const result = await faceSDK.validateCanvas(canvas);

// De URL
const result = await faceSDK.validateImage('path/to/image.jpg');

Resultado da Validação

interface ValidationResult {
  isValid: boolean;           // Passou na validação?
  score: number;             // Score 0-100
  confidence: number;        // Confiança 0-100
  
  // Métricas detalhadas
  metrics: {
    faceDetected: boolean;
    faceCount: number;
    faceSize: number;
    brightness: number;
    sharpness: number;
    eyesOpen: boolean;
    // ... 15+ métricas
  };
  
  // Problemas encontrados
  issues: string[];
  
  // Sugestões de melhoria
  suggestions: string[];
  
  // Processamento
  processingTime: number;
  modelVersion: string;
}

Exemplo Completo

async function validatePhoto(file) {
  try {
    // Aplicar preset
    faceSDK.setPreset('document');
    
    // Validar
    const result = await faceSDK.validateFile(file);
    
    if (result.isValid) {
      console.log(`✅ Foto válida! Score: ${result.score}`);
      
      // Gerar recorte
      const crop = await faceSDK.generateCrop(file, 512);
      
      // Download
      downloadCrop(crop);
    } else {
      console.log('❌ Problemas encontrados:');
      result.issues.forEach(issue => console.log(`- ${issue}`));
      
      console.log('💡 Sugestões:');
      result.suggestions.forEach(tip => console.log(`- ${tip}`));
    }
  } catch (error) {
    console.error('Erro na validação:', error);
  }
}

🖼️ Remoção de Fundo

O Face SDK inclui um sistema avançado de remoção de fundo usando MediaPipe Image Segmenter, permitindo substituir ou remover o fundo de imagens mantendo apenas a pessoa.

Ativação

// Ativar remoção de fundo
faceSDK.setBackgroundRemovalEnabled(true);

// Verificar se está ativado
const isEnabled = faceSDK.isBackgroundRemovalEnabled();

Tipos de Background

// Background transparente
faceSDK.setBackgroundConfig({
  type: 'transparent'
});

// Background com desfoque
faceSDK.setBackgroundConfig({
  type: 'blur',
  blurIntensity: 10  // 1-20px
});

// Background cor sólida
faceSDK.setBackgroundConfig({
  type: 'solid',
  solidColor: '#00ff00'  // Verde chroma key
});

// Background com imagem personalizada
faceSDK.setBackgroundConfig({
  type: 'image',
  backgroundImage: 'data:image/jpeg;base64,/9j/4AAQ...'
});

// Background com gradiente
faceSDK.setBackgroundConfig({
  type: 'gradient',
  gradientType: 'linear', // ou 'radial'
  gradientColors: ['#4facfe', '#00f2fe']
});

Validação com Remoção de Fundo

// Validar imagem com remoção de fundo
const result = await faceSDK.validateWithBackground(file);

if (result.backgroundRemoval?.enabled) {
  const bgResult = result.backgroundRemoval.result;
  
  // Canvas com fundo removido
  const processedCanvas = bgResult.canvas;
  
  // Configuração aplicada
  console.log('Tipo:', bgResult.config.type);
  
  // Métricas da segmentação
  const metrics = bgResult.segmentation;
  console.log('Tempo:', metrics.processingTime + 'ms');
  console.log('Confiança:', metrics.confidence);
}

Remoção Direta

// Remover fundo de qualquer imagem
const bgResult = await faceSDK.removeBackground(image);

// Usar o canvas processado
const canvas = bgResult.canvas;
document.body.appendChild(canvas);

// Baixar como imagem
const link = document.createElement('a');
link.download = 'foto-sem-fundo.png';
link.href = canvas.toDataURL();
link.click();

Tempo Real na Câmera

// A remoção de fundo funciona automaticamente
// durante a validação em tempo real na câmera
// quando ativada

// Usar validação contínua
startRealTimeValidation();

// O overlay da câmera mostrará o fundo removido
// automaticamente quando habilitado

✨ Recursos Avançados

  • Cache Inteligente: Modelo baixado apenas uma vez (~15MB)
  • Alta Precisão: MediaPipe Image Segmenter profissional
  • Tempo Real: Preview instantâneo na câmera
  • Múltiplos Formatos: File, Canvas, Image, Video
  • Personalização: 5 tipos diferentes de background
  • Performance: +50-150ms por imagem

📡 Sistema de Eventos

Eventos Disponíveis

Evento Quando Dispara Dados
model:loading Durante carregamento do modelo progress (0-100)
model:loaded Modelo carregado -
model:cached Modelo carregado do cache -
validation:start Início da validação -
validation:complete Validação finalizada result
face:detected Face detectada count
realtime:feedback Feedback em tempo real feedback

Usando Eventos

// Registrar listeners
faceSDK.on('validation:start', () => {
  showLoader('Validando...');
});

faceSDK.on('validation:complete', (result) => {
  hideLoader();
  displayResult(result);
});

faceSDK.on('face:detected', (count) => {
  updateFaceCount(count);
});

// Remover listener
const handler = (result) => console.log(result);
faceSDK.on('validation:complete', handler);
faceSDK.off('validation:complete', handler);

Validação em Tempo Real

// Iniciar validação contínua na câmera
const video = document.getElementById('camera');

faceSDK.startRealTimeValidation(video);

faceSDK.on('realtime:feedback', (feedback) => {
  // feedback: 'excellent', 'good', 'fair', 'poor'
  updateCameraFeedback(feedback);
});

// Parar validação
faceSDK.stopRealTimeValidation();

📊 Métricas Detalhadas

O SDK analisa 15+ métricas de qualidade facial:

🎯 Detecção e Posição

  • faceDetected: Face detectada na imagem
  • faceCount: Número de faces encontradas
  • faceSize: Tamanho da face em pixels
  • facePosition: Centralização da face
  • faceBounds: Área ocupada pela face

📷 Qualidade da Imagem

  • brightness: Brilho geral (0-255)
  • contrast: Contraste da imagem
  • sharpness: Nitidez/foco
  • blur: Detecção de borrado
  • noise: Ruído/granulosidade

👁️ Características Faciais

  • eyesOpen: Olhos abertos
  • eyesVisible: Olhos claramente visíveis
  • mouthClosed: Boca fechada
  • frontFacing: Face voltada para frente
  • headPose: Ângulo da cabeça

🔍 Detecção de Objetos

  • hasGlasses: Uso de óculos
  • hasMask: Uso de máscara
  • hasHat: Uso de chapéu/boné
  • accessories: Outros acessórios

📈 Interpretação de Scores

90-100 Excelente - Qualidade profissional
75-89 Boa - Adequada para maioria dos usos
60-74 Regular - Pode precisar de melhorias
0-59 Ruim - Não recomendada

📚 API Reference

Constructor

new FaceSDK(options?: FaceSDKOptions)

Métodos Principais

initialize(): Promise<void>

Inicializa o SDK e carrega o modelo

validateFile(file: File): Promise<ValidationResult>

Valida arquivo de imagem

validateCanvas(canvas: HTMLCanvasElement): Promise<ValidationResult>

Valida conteúdo de um canvas

generateCrop(source: File|Canvas, size: number): Promise<Blob>

Gera recorte facial da imagem

setPreset(preset: string): void

Define preset de validação

startRealTimeValidation(video: HTMLVideoElement): void

Inicia validação em tempo real

generateReport(result: ValidationResult): string

Gera relatório JSON da validação

Sistema de Eventos

on(event: string, handler: Function): void

Registra listener para evento

off(event: string, handler: Function): void

Remove listener de evento

emit(event: string, ...args): void

Dispara evento (uso interno)

💡 Exemplos Práticos

📱 Validação de Selfie

async function validateSelfie(file) {
  const faceSDK = new FaceSDK({ language: 'pt-BR' });
  await faceSDK.initialize();
  
  // Configurar para selfies
  faceSDK.setPreset('selfie');
  
  const result = await faceSDK.validateFile(file);
  
  return {
    approved: result.isValid && result.score >= 70,
    score: result.score,
    issues: result.issues,
    suggestions: result.suggestions
  };
}

📄 Validação de Documento

async function validateDocument(file) {
  const faceSDK = new FaceSDK();
  await faceSDK.initialize();
  
  // Configurar para documentos
  faceSDK.setPreset('document');
  
  const result = await faceSDK.validateFile(file);
  
  if (result.isValid) {
    // Gerar recorte padrão 512x512
    const crop = await faceSDK.generateCrop(file, 512);
    
    return {
      valid: true,
      crop: crop,
      metrics: result.metrics
    };
  }
  
  return {
    valid: false,
    errors: result.issues
  };
}

📹 Captura com Câmera

class CameraCapture {
  constructor() {
    this.faceSDK = new FaceSDK();
    this.stream = null;
  }
  
  async init() {
    await this.faceSDK.initialize();
    
    this.faceSDK.on('realtime:feedback', (feedback) => {
      this.updateFeedback(feedback);
    });
  }
  
  async startCamera() {
    this.stream = await navigator.mediaDevices.getUserMedia({
      video: { width: 640, height: 480 }
    });
    
    const video = document.getElementById('video');
    video.srcObject = this.stream;
    
    // Iniciar validação em tempo real
    this.faceSDK.startRealTimeValidation(video);
  }
  
  async capturePhoto() {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const video = document.getElementById('video');
    
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    ctx.drawImage(video, 0, 0);
    
    // Validar captura
    const result = await this.faceSDK.validateCanvas(canvas);
    
    return {
      image: canvas.toDataURL(),
      validation: result
    };
  }
  
  updateFeedback(feedback) {
    const messages = {
      excellent: '✅ Excelente! Posição perfeita.',
      good: '👍 Boa posição. Pode capturar.',
      fair: '⚠️ Ajuste a posição ligeiramente.',
      poor: '❌ Reposicione o rosto.'
    };
    
    document.getElementById('feedback').textContent = messages[feedback];
  }
}

🐛 Troubleshooting

❌ Modelo não carrega

Sintomas: Timeout ou erro de rede

Soluções:

  • Verificar conexão com internet
  • Testar acesso ao CDN do MediaPipe
  • Configurar URL customizada do modelo
// URL customizada
const faceSDK = new FaceSDK({
  modelUrl: 'https://seu-cdn.com/face_landmarker.task'
});

📷 Câmera não funciona

Sintomas: getUserMedia falha

Soluções:

  • Verificar permissões de câmera
  • Usar HTTPS (obrigatório para câmera)
  • Testar em diferentes navegadores

⚡ Performance ruim

Sintomas: Validação muito lenta

Soluções:

  • Reduzir tamanho das imagens antes da validação
  • Usar cache do modelo (padrão)
  • Processar em Web Workers (para grandes volumes)

🔍 Debug

// Ativar modo debug
const faceSDK = new FaceSDK({ debug: true });

// Logs detalhados serão exibidos no console
// Inclui: carregamento, validação, métricas, etc.

📊 Verificar Suporte

// Verificar suporte do navegador
if (!navigator.mediaDevices) {
  console.error('Camera API não suportada');
}

if (!window.MediaSource) {
  console.error('MediaSource não suportada');
}

// Testar WebGL (necessário para MediaPipe)
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
if (!gl) {
  console.error('WebGL não suportado');
}

📞 Suporte

Para problemas não listados aqui:

  • Verifique a documentação do MediaPipe
  • Teste com diferentes imagens/câmeras
  • Ative o modo debug para mais informações
  • Verifique o console do navegador para erros