# 👁️03- Módulo de Reconhecimento e API (Core)

### ⚙️ Arquitetura e Otimizações

Para garantir que o sistema rode fluido em um Hardware Embarcado (Labrador/Raspberry Pi), utilizamos técnicas avançadas de processamento:

#### 1. Multithreading (Buffer de Vídeo)

O Python processa instruções linha por linha. Se o sistema parasse para baixar uma imagem da rede, a tela travaria.

* Solução: Criamos a classe `VideoStream` que roda em uma Thread separada.
* Funcionamento: Ela fica em *loop* infinito baixando o último frame da câmera e salvando na memória RAM. O loop principal apenas "lê" a memória, sem esperar o download.
* Recurso de Auto-Reconnect: Se a câmera cair ou o Wi-Fi oscilar, a thread entra em modo de espera e tenta reconectar automaticamente a cada 2 segundos, evitando o crash do software.

#### 2. Downscaling (Redução de Resolução para IA)

Processar uma imagem Full HD (1920x1080) na rede neural levaria cerca de 2 a 3 segundos por frame.

* Solução: O vídeo é exibido em alta qualidade para o usuário, mas para a IA, reduzimos a imagem em 80% (`fx=0.2`).
* Resultado: O reconhecimento acontece em milissegundos sem perder precisão significativa.

#### 3. API Non-Blocking

Utilizamos o Flask rodando em paralelo (`threaded=True` por padrão) para aceitar requisições HTTP. Isso permite cadastrar um usuário remotamente (do PC ou celular) enquanto o totem continua reconhecendo pessoas na tela.

***

### 🛠️ Configuração do Código

No início do script, existem constantes que devem ser ajustadas conforme o ambiente de instalação:

Python

```
# IP da ESP32-CAM (Deve ser fixo ou atualizado se o roteador reiniciar)
URL_CAMERA = "http://192.168.18.159/stream" 

# Tempo (em segundos) que o sistema espera antes de liberar a mesma pessoa novamente
DELAY_RECONHECIMENTO = 10

# Intervalo entre checagens da IA (1.0s economiza MUITA CPU)
INTERVALO_SCAN_IA = 1.0

# Resolução de Saída (Deve casar com a resolução nativa do monitor LCD)
# Exemplos comuns: 1024x600 (LCD 7") ou 1920x1080 (Monitor PC)
LARGURA_TELA = 1920
ALTURA_TELA = 1080
```

***

### 🔌 Referência da API

O sistema expõe endpoints REST na porta `5000` para integração externa.

#### 1. Cadastrar Usuário (Remoto)

Permite enviar uma foto e um nome para o banco de dados do Totem via rede. O sistema calcula o *embedding* (código facial), salva no arquivo `.pickle` e descarta a imagem para economizar espaço.

* Endpoint: `POST /api/cadastrar_direto`
* Content-Type: `multipart/form-data`
* Parâmetros:
  * `foto`: Arquivo de imagem (.jpg, .png).
  * `nome`: Texto com o nome da pessoa.
* Retorno Sucesso (201):

  JSON

  ```
  { "mensagem": "Sucesso! Victor cadastrado." }
  ```

#### 2. Listar Usuários

Retorna a lista de todas as pessoas cadastradas no banco de dados.

* Endpoint: `GET /usuarios`
* Retorno (200):

  JSON

  ```
  {
    "total": 3,
    "nomes": ["Victor", "Yasmin", "Administrador"]
  }
  ```

#### 3. Video Feed (Debug)

Permite ver o que a câmera do Totem está vendo através de um navegador web.

* Endpoint: `GET /video_feed`
* Uso: Abra `http://IP_DO_LABRADOR:5000/video_feed` no navegador.

***

### 💻 Como Executar

O script foi projetado para rodar automaticamente no boot, mas pode ser iniciado manualmente para testes:

1. Ative o ambiente virtual:

   Bash

   ```
   source venv/bin/activate
   ```
2. Execute o script:

   Bash

   ```
   python 03_reconhecer.py
   ```

#### Comportamento Esperado

1. O terminal exibirá `[VIDEO] Iniciando sistema...`.
2. Uma janela abrirá ocupando 100% da tela (modo Kiosk).
3. Ao reconhecer um rosto cadastrado:
   * Uma borda verde aparecerá.
   * A mensagem "BEM-VINDO \[NOME]" será exibida.
   * O sistema entrará em "Cooldown" por 10 segundos (barra cinza).

***

### 🧩 Estrutura de Classes

#### `class VideoStream`

Gerencia a conexão HTTP com a ESP32. Implementa um buffer circular simples para garantir que sempre tenhamos o frame mais recente disponível, descartando frames antigos que causariam latência (lag).

#### `loop_reconhecimento()`

Função principal que roda na Thread de interface gráfica. É responsável por:

1. Ler o frame do `VideoStream`.
2. Redimensionar para o tamanho do monitor (`LARGURA_TELA`).
3. Gerenciar o relógio da IA (`INTERVALO_SCAN_IA`).
4. Desenhar a interface (retângulos e textos) sobre o vídeo.

***

### ⚠️ Solução de Problemas Comuns

| **Sintoma**                | **Causa Provável**                             | **Solução**                                                               |
| -------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------- |
| Tela Preta / Conectando... | O IP da ESP32 mudou ou ela está desligada.     | Verifique o IP no Monitor Serial da Arduino IDE e atualize `URL_CAMERA`.  |
| Janela Pequena no Canto    | A resolução configurada é menor que o monitor. | Ajuste `LARGURA_TELA` e `ALTURA_TELA` para a resolução nativa do display. |
| Lag / Atraso no Vídeo      | Processamento de IA muito frequente.           | Aumente o `INTERVALO_SCAN_IA` para `1.5` ou `2.0`.                        |
| Erro "No route to host"    | Labrador e ESP32 em redes diferentes.          | Garanta que ambos estejam no mesmo Wi-Fi (2.4GHz).                        |
