Câmera que avisa só quando aparece uma pessoa
A ESP32-CAM (ou uma webcam USB) manda a imagem pelo Wi-Fi. No seu computador, um modelo de IA chamado YOLO procura pessoas na imagem e ignora gato, carro e galho balançando. Quando alguém entra na zona que você marcou, ele salva a foto e avisa. Tudo roda na sua casa, sem nuvem.
Como funciona
A câmera filma, o computador decide
Um sensor de movimento comum dispara com qualquer coisa que esquenta ou mexe. O YOLO foi treinado para reconhecer objetos e devolve uma caixa em volta de cada pessoa que encontra. O programa só considera a pessoa que está dentro da zona que você marcou, e só dispara se ela continuar lá por alguns quadros. Isso corta a maioria dos alarmes falsos.
Peças
Lista de compras
| Peça | Para que serve | Preço aprox. |
|---|---|---|
| ESP32-CAM AI-Thinker com câmera OV2640 | Filma e manda a imagem pelo Wi-Fi | R$ 40–70 |
| Placa ESP32-CAM-MB ou adaptador FTDI (FT232RL) | Grava o programa na ESP32-CAM pelo USB | R$ 15–30 |
| Fonte 5 V de pelo menos 1 A (carregador de celular serve) | Alimenta a câmera. Fonte fraca é a causa nº 1 de travamento | R$ 0–30 |
| Jumpers fêmea-fêmea | Ligação com o FTDI | R$ 5–10 |
| Total por câmera | R$ 60–150 | |
| Alternativa: webcam USB | Ligada direto no computador, sem ESP32-CAM | R$ 60–120 |
| Computador ou mini PC | Roda o YOLO. Qualquer notebook recente serve para começar | fora do kit |
Preços aproximados de loja online brasileira em outubro de 2026, a conferir antes de comprar. Não inclui caixa de acabamento nem suporte de parede.
Ligação
Gravar o programa na ESP32-CAM
A ESP32-CAM não tem entrada USB. Para gravar o programa, você liga um adaptador FTDI nos pinos da placa. Depois de gravada, ela só precisa de 5 V e GND.
| Adaptador FTDI | ESP32-CAM | Quando |
|---|---|---|
| VCC (jumper em 5 V) | 5V | sempre |
| GND | GND | sempre |
| TX | U0R (GPIO 3) | só para gravar |
| RX | U0T (GPIO 1) | só para gravar |
| fio entre IO0 (GPIO 0) e GND da câmera | só durante a gravação |
Passo a passo
Da caixa ao primeiro alerta
- Prepare a Arduino IDE. Instale a Arduino IDE 2 e, em Gerenciador de Placas, o pacote "esp32" (Espressif). Escolha a placa "AI Thinker ESP32-CAM".
- Abra o exemplo pronto. Em Arquivo › Exemplos › ESP32 › Camera, abra "CameraWebServer". No arquivo principal, deixe ativa só a linha
#define CAMERA_MODEL_AI_THINKERe escreva o nome e a senha da sua rede. - Grave. Ligue o FTDI como no diagrama, com IO0 no GND. Aperte RST, clique em Carregar e espere o "Done uploading". Tire o fio do IO0 e aperte RST de novo.
- Ache o endereço. No Monitor Serial (115200) aparece "Camera Ready! Use http://192.168.0.60". Abra no navegador, clique em Start Stream e ajuste a resolução (VGA é um bom começo).
- Feche o navegador. A ESP32-CAM manda o vídeo para um cliente por vez. O endereço do vídeo é o mesmo IP com
:81/streamno fim. - Prepare o Python no computador. Instale o Python 3 e rode
pip install ultralytics opencv-python. Na primeira execução o programa baixa o modeloyolov8n.pt(cerca de 6 MB). Depois disso a detecção roda sem internet. - Rode o vigia. Troque o IP no código, rode
python vigia.pye passe na frente da câmera. A janela mostra a zona em vermelho e a caixa em volta de você. Aperte Q para sair.
Código
Python + YOLO no computador
Salve como vigia.py. A zona é marcada em frações da imagem (0 a 1), então funciona em qualquer resolução. Para usar webcam USB, troque FONTE por 0.
# vigia.py — avisa quando aparece pessoa
# Instale com:
# pip install ultralytics opencv-python
import os, time
from datetime import datetime
import cv2
from ultralytics import YOLO
# ESP32-CAM pelo Wi-Fi (troque o IP)
FONTE = "http://192.168.0.60:81/stream"
# webcam USB: FONTE = 0
# Zona: (esquerda, topo, direita,
# base)
# em frações da imagem, de 0 a 1
ZONA = (0.2, 0.2, 0.9, 1.0)
# quadros seguidos com pessoa
QUADROS = 5
# segundos mínimos entre dois alertas
INTERVALO = 60
PASTA = "alertas"
os.makedirs(PASTA, exist_ok=True)
# baixa o modelo na 1ª vez; roda local
modelo = YOLO("yolov8n.pt")
cam = cv2.VideoCapture(FONTE)
seguidos, ultimo = 0, 0.0
def na_zona(caixa, larg, alt):
# o centro da pessoa está na zona?
x1, y1, x2, y2 = caixa
cx = (x1 + x2) / 2 / larg
cy = (y1 + y2) / 2 / alt
e, t, d, b = ZONA
return e <= cx <= d and t <= cy <= b
def avisar(foto):
# Para o celular, use um bot SEU.
# Leia o token com os.environ,
# nunca escreva o token aqui.
print("ALERTA: pessoa", foto)
while True:
ok, quadro = cam.read()
if not ok:
# caiu: espera e reconecta
time.sleep(2)
cam = cv2.VideoCapture(FONTE)
continue
alt, larg = quadro.shape[:2]
# classe 0 = pessoa; confiança 0,5
res = modelo(quadro, classes=[0],
conf=0.5,
verbose=False)[0]
caixas = res.boxes.xyxy.tolist()
achou = any(na_zona(c, larg, alt)
for c in caixas)
if achou:
seguidos += 1
else:
seguidos = 0
tela = res.plot()
e, t, d, b = ZONA
p1 = (int(e * larg), int(t * alt))
p2 = (int(d * larg), int(b * alt))
# zona em vermelho
cv2.rectangle(tela, p1, p2,
(0, 0, 255), 2)
agora = time.time()
espera = agora - ultimo > INTERVALO
if seguidos >= QUADROS and espera:
ultimo = agora
# nome = AAAAMMDD-HHMMSS
f_ = "%Y%m%d-%H%M%S"
nome = datetime.now().strftime(f_)
foto = f"{PASTA}/{nome}.jpg"
cv2.imwrite(foto, tela)
# registro para o resumo do dia
reg = PASTA + "/registro.csv"
with open(reg, "a") as f:
f.write(nome + "\n")
avisar(foto)
cv2.imshow("vigia", tela)
if cv2.waitKey(1) == ord("q"):
break
cam.release()
cv2.destroyAllWindows()
Limpeza do fim do dia. Agende para rodar às 23h59 (cron no Linux e no Mac, Agendador de Tarefas no Windows):
# limpa.py — apaga as fotos do dia
import glob, os
for f in glob.glob("alertas/*.jpg"):
os.remove(f)
print("fotos apagadas")
A camada de IA
O que a IA faz neste projeto
Detecção de pessoa, local
O YOLO roda no seu computador. A imagem não sai da sua rede e você não paga nada por mês.
Zonas proibidas
Você marca a área que importa (portão, porta dos fundos, depósito). Quem passa na calçada fora da zona não dispara alerta.
Resumo do dia
Um script conta os alertas por hora e pede a um modelo de IA um resumo em português: "três alertas, todos entre 7 h e 8 h, horário de entrega".
Resumo do dia. Só os números saem do programa, nunca as fotos:
# resumo.py — alertas por hora, em texto
import collections, datetime
hoje = datetime.date.today()
hoje = hoje.strftime("%Y%m%d")
por_hora = collections.Counter()
for linha in open("alertas/registro.csv"):
nome = linha.strip()
if nome.startswith(hoje):
# nome = AAAAMMDD-HHMMSS
por_hora[nome[9:11] + "h"] += 1
prompt = (
"Alertas de pessoa por hora, hoje: "
+ str(dict(sorted(por_hora.items())))
+ ". Escreva um resumo do dia em "
"português, em até 4 frases, e aponte "
"horários fora do comum."
)
print(prompt)
# Mande só este texto ao modelo:
# - de preferência um modelo local no PC,
# sem chave nenhuma; ou
# - o serviço de IA da sua conta, com a
# SUA chave numa variável de ambiente.
# Nunca envie as fotos para fora.
Teste e melhore
Confira antes de mostrar para alguém
- Você entra na zona e o alerta sai uma vez só, com a foto na pasta
alertas. - Você fica parado na zona e o segundo alerta só sai depois de 60 s.
- Um gato, um carro ou uma árvore na imagem não disparam nada.
- Quem passa fora da zona vermelha não dispara nada.
- O
limpa.pyapaga as fotos e a placa de aviso está visível.
| Erro comum | Causa provável | Como resolver |
|---|---|---|
| "Brownout detector was triggered" | Fonte fraca ou cabo fino e comprido | Fonte 5 V de pelo menos 1 A, cabo curto, ligada no pino 5V (não no 3V3) |
| "Failed to connect" ao gravar | IO0 sem ligar no GND, ou TX e RX sem cruzar | Ligue IO0 no GND, aperte RST, confira TX → U0R e RX → U0T |
| Python não abre o vídeo | Navegador ainda aberto no stream | Feche a aba: a câmera atende um cliente por vez |
| Imagem lenta, poucos quadros | Resolução alta ou computador fraco | Baixe para VGA ou QVGA na página da câmera |
| Alerta com foto de cartaz ou TV | O YOLO vê pessoa em imagem também | Tire a TV da zona ou suba conf para 0,6 |
| Não detecta nada à noite | A ESP32-CAM não enxerga no escuro | Deixe uma luz acesa na área ou use câmera com infravermelho |
Caderno de testes. Cada vez que mudar alguma coisa, anote numa linha. Conte alarmes falsos e alarmes perdidos: esse número é o seu argumento de venda.
| Data | Versão | O que mudou | Resultado |
|---|---|---|---|
| 20/10 | v1 | Imagem inteira, 1 quadro basta | Alerta com cada pessoa que passou na calçada |
| 21/10 | v2 | Zona só no portão, 5 quadros seguidos | Só alertas de quem entrou de verdade |
| … | v3 | Resumo do dia com IA | Anote aqui |
Privacidade e segurança
Regras da câmera
limpa.py todo dia. A LGPD (Lei Geral de Proteção de Dados) trata imagem de rosto como dado pessoal, e quem instala responde pelo uso.Ficha de negócio
Como vender a câmera
| Quem compra | Comércio pequeno (depósito, fundos da loja), condomínio (portão, garagem), sítio e chácara (galpão, porteira) |
| Custo do kit | R$ 60–150 por câmera (lista acima, a conferir). O computador pode ser um notebook antigo do cliente |
| Preço sugerido | R$ 200–350 por câmera instalada e configurada (sugestão) |
| Mão de obra | 2 a 3 horas: instalar, marcar as zonas com o cliente, configurar o alerta e a limpeza diária |
| Assinatura opcional | R$ 20–40 por mês: ajuste das zonas, manutenção e resumo semanal (sugestão) |
| Argumento de economia | Sem mensalidade de nuvem e menos alarme falso. Prove: deixe um sensor de movimento comum e a câmera com YOLO lado a lado por uma semana e conte os alertas falsos de cada um |
vigia.py para cada uma, com IP e pasta diferentes, e venda por ponto vigiado.Para ir além
Próximos passos
Para entender como um modelo enxerga e decide, siga o curso Visão e ação (VLA). Para a base de IA, comece pelo IA do zero. Todos os cursos são abertos e gratuitos no INEMA.CLUB.