BOX DE FACTOS

  • Nome da solução: Vigilant Guard.
  • Objectivo: detectar humanos em eventos do ZoneMinder usando IA local.
  • Motor principal: YOLOv8, em execução CPU.
  • Integração: filtro ZoneMinder → script shell → socket UNIX → serviço Python.
  • Alertas: ntfy para telemóvel ou outros clientes compatíveis.
  • Reconhecimento facial: opcional, com base de dados MySQL/MariaDB.
  • Filosofia: sem cloud obrigatória, sem dependência externa, controlo local.

Vigilant Guard: dar olhos de IA ao ZoneMinder sem entregar a casa à nuvem

Há soluções tecnológicas que nascem de grandes planos estratégicos. Outras nascem de uma necessidade muito simples: uma câmara vê movimento, mas o sistema precisa de saber se aquilo é uma pessoa, uma sombra, um gato, uma folha ao vento ou apenas mais um falso positivo com pretensões dramáticas.

O Vigilant Guard nasceu dessa necessidade prática: acrescentar ao ZoneMinder uma camada local de inteligência artificial capaz de analisar eventos de movimento, detectar humanos e enviar alertas úteis para o telemóvel, sem depender de serviços externos, plataformas fechadas ou vigilância em nuvem.

A ideia é simples, mas poderosa: o ZoneMinder continua a fazer aquilo que sabe fazer bem — capturar vídeo, detectar movimento e criar eventos. O Vigilant Guard entra depois, como um segundo observador, mais selectivo, mais atento e menos impressionável perante sombras nocturnas.

1. O problema clássico da videovigilância doméstica

Quem usa sistemas de videovigilância conhece bem o dilema: se a sensibilidade é baixa, o sistema falha eventos importantes; se a sensibilidade é alta, começa a disparar alertas por tudo e por nada. Uma nuvem passa diante da luz, uma árvore mexe, um insecto atravessa a lente, e o sistema entra em modo apocalipse.

O ZoneMinder é uma ferramenta robusta e flexível, mas a detecção tradicional de movimento baseia-se sobretudo em alterações de imagem. Isso é suficiente para perceber que "algo mudou", mas não para perceber o que mudou.

É precisamente aí que entra o Vigilant Guard: ele não substitui o ZoneMinder; acrescenta-lhe discernimento.

2. Arquitectura geral da solução

A arquitectura foi desenhada para ser simples, local e auditável. Nada de magia nebulosa em servidores distantes. Tudo corre dentro da própria infra-estrutura do utilizador.

ZoneMinder
   ↓
Filtro de evento
   ↓
notify-image.sh
   ↓
Socket UNIX /tmp/humans_socket
   ↓
Vigilant Guard
   ↓
YOLOv8
   ↓
face_recognition opcional
   ↓
MySQL/MariaDB opcional
   ↓
ntfy / recortes / alertas

O ZoneMinder cria o evento. Um filtro executa o script notify-image.sh. Esse script envia o caminho do evento para um socket UNIX. O serviço Python Vigilant Guard recebe esse caminho, analisa imagens críticas como alarm.jpg e snapshot.jpg, detecta presença humana com YOLOv8 e envia alerta via ntfy.

A cadeia é curta, clara e depurável. E, como todos os bons sistemas UNIX, quando falha, deixa pistas — desde que tenhamos logs suficientes e paciência de artesão.

3. O papel do socket UNIX

Uma das decisões mais importantes foi usar um socket UNIX local em vez de HTTP, API REST ou outro mecanismo mais pesado. O socket é rápido, simples e adequado para comunicação entre processos na mesma máquina.

O caminho usado é:

/tmp/humans_socket

Houve, porém, um detalhe crítico: o ZoneMinder executa o filtro como utilizador www-data, enquanto o serviço Python corre como root. Se o socket for criado como root:root com permissões restritivas, o script do ZoneMinder não consegue entregar eventos.

A solução foi criar o socket com grupo www-data:

srw-rw---- 1 root www-data ... /tmp/humans_socket

Este pequeno pormenor é o tipo de detalhe que separa um sistema "quase a funcionar" de um sistema realmente operacional. A informática, como a vida, também se perde muitas vezes numa porta fechada por permissões.

4. Detecção humana com YOLOv8

O motor principal de detecção é o YOLOv8, usando o modelo leve yolov8n.pt. Esta escolha foi deliberada: o sistema corre numa máquina virtual sem processador gráfico dedicado, pelo que a solução tinha de funcionar em CPU.

A configuração típica usada foi:

HUMANS_YOLO_MODEL=/opt/VigilantGuard/models/yolov8n.pt
HUMANS_MAX_EVENT_FRAMES=4
HUMANS_MAX_IMAGE_WIDTH=960
HUMANS_PERSON_CONF=0.35
HUMANS_MIN_PERSON_AREA_RATIO=0.003

O parâmetro HUMANS_PERSON_CONF controla o grau de confiança mínimo exigido ao modelo. Valores mais baixos aumentam a sensibilidade, mas também podem aumentar falsos positivos. Valores mais altos reduzem ruído, mas podem falhar pessoas em imagens escuras, parciais ou distantes.

A solução procura um equilíbrio: detectar suficientemente bem sem transformar cada sombra numa emergência doméstica.

5. Porque analisar alarm.jpg e snapshot.jpg

Num evento do ZoneMinder, nem todas as imagens têm o mesmo valor. Algumas podem estar vazias, atrasadas ou capturadas antes de a pessoa estar claramente visível. Por isso, o Vigilant Guard dá prioridade a duas imagens essenciais:

  • alarm.jpg — normalmente a imagem associada ao momento de alarme.
  • snapshot.jpg — imagem de referência do evento.

A lógica foi ajustada para garantir que ambas são analisadas sempre que existirem. Só depois são escolhidas imagens adicionais do evento, distribuídas ao longo da sequência.

Este detalhe melhora a probabilidade de detectar a pessoa, sobretudo quando a passagem pela câmara é rápida.

6. Reconhecimento facial opcional

Depois de detectar uma pessoa, o sistema pode tentar identificar o rosto através da biblioteca face_recognition, comparando os encodings faciais com uma base de dados MySQL ou MariaDB.

A tabela pode ter uma estrutura simples:

CREATE TABLE faces (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    encoding MEDIUMTEXT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

O reconhecimento facial é, contudo, opcional. A solução continua útil mesmo sem ele: detecta humanos, recorta a figura e envia alerta. A identificação nominal só acontece quando há rosto visível, com qualidade suficiente e previamente registado.

Na prática, o YOLO responde à pergunta: "há uma pessoa?". O reconhecimento facial tenta responder à pergunta seguinte: "quem é?".

7. Alertas via ntfy

O envio de alertas é feito através de ntfy, uma solução simples, leve e muito adequada para notificações em sistemas próprios.

Uma mensagem típica pode indicar:

👤 Figura humana detectada — http://servidor/uploads/humano_20260529_xxxxx.jpg

Ou, quando o rosto é reconhecido:

🧑 Rosto identificado: Nome — http://servidor/uploads/rosto_nome_xxxxx.jpg

O resultado é uma cadeia de vigilância muito prática: a câmara vê, o ZoneMinder cria evento, o Vigilant Guard confirma se há humano, e o telemóvel recebe apenas aquilo que interessa.

8. Serviço systemd: transformar script em sentinela

Para funcionar de forma contínua, o Vigilant Guard corre como serviço systemd:

sudo systemctl status Vigilant-Guard.service
sudo journalctl -u Vigilant-Guard.service -f

O serviço cria o socket, carrega os rostos conhecidos, inicializa o modelo YOLO e fica à espera de caminhos de eventos enviados pelo script do ZoneMinder.

A utilização de systemd permite reinício automático, limites de CPU, prioridade reduzida e integração limpa no arranque do sistema.

9. Limites e afinação

O Vigilant Guard não resolve sozinho todos os problemas de videovigilância. Se o ZoneMinder não criar evento, o Vigilant Guard não será chamado. O primeiro elo da cadeia continua a ser a configuração das zonas, sensibilidade, área mínima e critérios de movimento no próprio ZoneMinder.

A afinação divide-se em dois níveis:

  • No ZoneMinder: zonas de detecção, sensibilidade, áreas ignoradas, contagem mínima de frames em alarme.
  • No Vigilant Guard: confiança YOLO, área mínima da pessoa, número de imagens analisadas por evento, largura máxima da imagem.

Se o sistema detectar pessoas a mais — por exemplo, transeuntes na rua — a primeira solução deve ser ajustar as zonas no ZoneMinder. É melhor evitar que o evento seja criado do que pedir à IA que corrija uma má geometria de vigilância.

10. Um projecto local, simples e publicável

O Vigilant Guard nasceu de uma necessidade concreta, mas tem potencial para ser útil a outros utilizadores de ZoneMinder. Muitos querem acrescentar detecção humana às suas câmaras, mas não querem depender de plataformas fechadas, subscrições, cloud obrigatória ou caixas negras comerciais.

Esta solução segue outra filosofia: software local, configuração explícita, logs legíveis, integração simples e controlo total pelo utilizador.

Não pretende ser uma plataforma universal de vigilância inteligente. Pretende ser uma ferramenta clara, pequena e eficaz: recebe eventos, analisa imagens, detecta humanos e avisa.

Conclusão: um vigia digital com olhos novos

O Vigilant Guard representa uma forma pragmática de acrescentar inteligência artificial ao ZoneMinder sem desmontar a arquitectura existente. Em vez de substituir o sistema de videovigilância, acrescenta-lhe uma camada de interpretação.

O resultado é um vigia digital mais atento: não apenas vê movimento, mas tenta perceber se esse movimento corresponde a uma pessoa.

E talvez seja essa a melhor definição desta pequena solução: um vigilante nocturno bem acordado, alimentado por Python, YOLO, UNIX sockets e alguma teimosia técnica. Daquela teimosia boa, artesanal, que transforma pequenos problemas em sistemas úteis.

Autor: Francisco Gonçalves

Co-autoria técnica e editorial: Augustus Veritas.

Artigo técnico publicado no âmbito dos projectos de experimentação tecnológica, software livre, inteligência artificial local e infra-estruturas independentes do Fragmentos do Caos.

Projecto brevemente a publicar em repositório no github.

🌌 Fragmentos do Caos: Blogue Ebooks Carrossel
👁️ Esta página foi visitada ... vezes.