Conteúdo detalhado
🔍 O que é detecção de objetos
Um detector de objetos recebe uma imagem e devolve uma lista: para cada coisa que reconheceu, uma caixa (onde está), uma classe (o que é) e uma confiança (de 0 a 1, o quanto o modelo acredita naquilo). O YOLO ("you only look once") faz isso olhando a imagem uma vez só, por isso é rápido o bastante para robôs. Os modelos prontos da Ultralytics já reconhecem as 80 classes do conjunto COCO, como pessoa, carro, cachorro, garrafa e cadeira.
🌱 Novo aqui?
Uma rede neural é um programa com milhões de números ajustáveis (os pesos) que aprende padrões a partir de exemplos. Treinar é ajustar esses pesos mostrando milhares de imagens já marcadas. Inferência é usar o modelo pronto numa imagem nova, que é o que o robô faz. O arquivo yolo26n.pt guarda esses pesos; o "n" é de nano, a versão menor e mais rápida.
Como ler: cada caixa colorida é um objeto encontrado, com a etiqueta "classe confiança". O quadro roxo à direita é o que chega ao seu programa para a pessoa: só números. A garrafa tem confiança menor (0,67) porque está pequena e parcialmente escura; é aí que surgem os erros (tópico 6).
"Esta foto tem um gato." Uma resposta por imagem, sem dizer onde.
"Gato aqui, pessoa ali." Caixa + classe + confiança. É o que o robô precisa para mirar.
O contorno exato, pixel a pixel. Mais preciso e mais pesado; útil para pegar objetos com o braço.
Por que aprender
A máscara de cor falha com objetos de cor comum ou quando a luz muda. O detector reconhece a forma, então segue uma pessoa de camiseta de qualquer cor. Em troca, gasta muito mais processamento. Saber o que cada saída significa é o que permite usá-la no controle do robô.
Conceitos-chave
🚀 YOLO26 no Pi 5 com Ultralytics
O YOLO26 é a geração atual da família YOLO da Ultralytics, sucessora do YOLO11. Tutoriais com versões antigas ainda circulam, mas o caminho de hoje é o pacote ultralytics com os pesos yolo26n.pt. Ele vem em tamanhos n, s, m, l e x: cada degrau acerta um pouco mais e roda bem mais devagar. No Pi 5, comece sempre pelo n. Em PyTorch, com imagem de 640 px, ele leva na ordem de 130 ms por quadro, ou seja, perto de 7 quadros por segundo no máximo.
Como ler: cada degrau é um tamanho do YOLO26. O "n", em destaque, é o único que mantém o robô reagindo em tempo útil só com o processador do Pi. Os maiores servem para treinar comparações no PC ou para rodar com acelerador.
Objetivo: instalar a Ultralytics no venv e detectar objetos ao vivo pela câmera, imprimindo classe, confiança e tempo de cada quadro. A instalação baixa bastante coisa: use cartão com espaço livre e paciência.
source ~/robo-venv/bin/activate
pip install ultralytics # instala também o PyTorch para ARM
yolo predict model=yolo26n.pt source="https://ultralytics.com/images/bus.jpg" # teste rápido
# YOLO26 ao vivo na Camera Module 3: imprime o que vê e o tempo de cada quadro
import sys, time
from picamera2 import Picamera2
from ultralytics import YOLO
MODELO = sys.argv[1] if len(sys.argv) > 1 else "yolo26n.pt" # troque pelo NCNN no tópico 3
modelo = YOLO(MODELO)
picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration(main={"size": (640, 480), "format": "RGB888"}))
picam2.start(); time.sleep(1)
print(f"Modelo {MODELO} carregado. Ctrl+C para sair.")
try:
while True:
quadro = picam2.capture_array() # BGR, como a Ultralytics espera
t0 = time.perf_counter()
r = modelo(quadro, imgsz=640, conf=0.5, verbose=False)[0]
ms = (time.perf_counter() - t0) * 1000
achados = [f"{r.names[int(c)]} {float(p):.2f}" for c, p in zip(r.boxes.cls, r.boxes.conf)]
print(f"{ms:6.0f} ms | {1000 / ms:4.1f} FPS | {', '.join(achados) or 'nada'}")
except KeyboardInterrupt:
picam2.stop()
Como verificar
- ✓O teste do ônibus cria uma pasta runs/detect/predict com a foto marcada (bus, person).
- ✓Ao vivo, você aparece como person 0.8x e o tempo fica na faixa de 100–200 ms por quadro.
- ✗"Illegal instruction" ou erro no PyTorch? Confira se o sistema é 64-bit (uname -m = aarch64) e o venv está ativo.
💡 Primeira execução mais lenta
Na primeira vez, a Ultralytics baixa os pesos yolo26n.pt da internet e o primeiro quadro demora bem mais que os seguintes. Meça a velocidade só depois de uns dez quadros.
Por que aprender
Com umas vinte linhas você tem um robô que reconhece pessoas e objetos do dia a dia. Esse mesmo laço (capturar, inferir, ler as caixas) é a base do projeto 3.6 e reaparece na Trilha 5, quando o braço precisa achar o objeto antes de pegar.
Conceitos-chave
⚡ Exportar para NCNN e medir velocidade
O formato .pt é ótimo para treinar, mas não é o mais rápido para rodar num processador ARM. A Ultralytics exporta o mesmo modelo para outros formatos; segundo o guia oficial para Raspberry Pi, o NCNN é o mais rápido na CPU do Pi. As caixas e classes continuam as mesmas; muda só o "motor" que faz as contas. A outra alavanca é o tamanho de entrada: imgsz=320 processa um quarto dos pixels de 640, e perde precisão em objetos pequenos.
🌱 Novo aqui?
NCNN é um motor de inferência aberto, feito para celulares e placas ARM. Exportar é converter os pesos de um formato para outro sem treinar de novo. O imgsz é o tamanho em que a imagem é redimensionada antes de entrar na rede; precisa ser múltiplo de 32 (320, 416, 640).
Como ler: só a barra de cima tem número de referência (o guia da Ultralytics para o Pi 5). As outras mostram a direção do ganho; o tamanho exato você descobre rodando o script abaixo no seu Pi, com o seu cooler e a sua câmera.
Objetivo: exportar o yolo26n para NCNN e comparar os dois formatos na mesma imagem, com números.
cd ~/robo && source ~/robo-venv/bin/activate
yolo export model=yolo26n.pt format=ncnn # cria a pasta yolo26n_ncnn_model/
python yolo_camera.py yolo26n_ncnn_model # o mesmo script do tópico 2, agora com NCNN
# Compara PyTorch x NCNN (640 e 320) na mesma imagem: média de 20 inferências
import time
from ultralytics import YOLO
IMAGEM = "https://ultralytics.com/images/bus.jpg" # ou o caminho de uma foto sua
testes = [("yolo26n.pt", 640), ("yolo26n_ncnn_model", 640), ("yolo26n_ncnn_model", 320)]
for caminho, tamanho in testes:
modelo = YOLO(caminho, task="detect")
for _ in range(3): # aquecimento: não conta
modelo(IMAGEM, imgsz=tamanho, verbose=False)
tempos = []
for _ in range(20):
r = modelo(IMAGEM, imgsz=tamanho, verbose=False)[0]
tempos.append(r.speed["inference"]) # ms, só a rede
media = sum(tempos) / len(tempos)
print(f"{caminho:22s} imgsz={tamanho}: {media:6.1f} ms ({1000 / media:4.1f} FPS) objetos={len(r.boxes)}")
Como verificar
- ✓Existe a pasta yolo26n_ncnn_model/ e o script imprime três linhas.
- ✓A linha do NCNN 640 tem tempo menor que a do .pt, com quantidade parecida de objetos.
- ✓Com 320, o tempo cai mais e podem sumir objetos pequenos (as pessoas ao fundo).
✓ Faça
- ✓Exportar no próprio Pi e guardar a pasta NCNN junto do código.
- ✓Medir depois do aquecimento e com o cooler ligado.
- ✓Escolher o imgsz pelo tamanho do objeto que importa.
✗ Não faça
- ✗Comparar formatos usando o primeiro quadro (inclui carregar o modelo).
- ✗Trocar para um modelo maior antes de esgotar NCNN e imgsz.
- ✗Acreditar em FPS de vídeo da internet: meça no seu Pi.
Por que aprender
Dobrar o FPS sem gastar nada é a diferença entre um robô que segue a pessoa e um que perde ela a cada curva. E o hábito de medir antes e depois vale para qualquer otimização que você fizer daqui em diante.
Conceitos-chave
🧩 Acelerar com AI HAT+ (Hailo)
Quando NCNN e imgsz não bastam, o próximo passo é tirar a rede neural do processador. O AI HAT+ é uma placa que encaixa sobre o Pi 5 e se liga pelo conector PCIe; ela leva um chip Hailo feito só para inferência. Existem duas gerações: o AI HAT+ com Hailo-8L (13 TOPS) ou Hailo-8 (26 TOPS), voltado à visão, e o AI HAT+ 2 com Hailo-10H (40 TOPS em INT4) e 8 GB de memória própria, que também roda modelos de linguagem e de visão-linguagem pequenos. Os dois funcionam só no Pi 5; o antigo "AI Kit" saiu de linha.
🌱 Novo aqui?
Uma NPU (unidade de processamento neural) é um chip especializado nas contas de redes neurais. TOPS são trilhões de operações por segundo: dão ideia de capacidade, mas só valem para comparar chips parecidos. INT4/INT8 quer dizer que os números do modelo são guardados com poucos bits; isso deixa tudo mais rápido, com pequena perda de precisão. O modelo precisa ser compilado para o formato do chip (no Hailo, arquivos .hef).
Como ler: à esquerda, a CPU faz as três tarefas e a do meio (vermelha) domina. À direita, a parte pesada vai para a NPU pelo PCIe e volta só o resultado. A CPU fica livre para o resto do robô: servidor de vídeo, comunicação com o ESP32, logs.
| Opção | Para quê | Custo e esforço |
|---|---|---|
| CPU + NCNN | Começar; seguir uma pessoa devagar | Zero; só exportar |
| AI HAT+ (Hailo-8L/8) | Detecção em tempo real, vários objetos | Placa extra; modelo compilado para Hailo |
| AI HAT+ 2 (Hailo-10H) | Visão + modelos de linguagem pequenos (Trilha 5) | Cerca de US$ 130 no varejo dos EUA (2026); confira no Brasil |
| AI Camera (Sony IMX500) | Inferência dentro da própria câmera | Câmera específica; modelos no formato dela |
Passo a passo (visão geral)
Monte com o Pi desligado
Encaixe o cabo flat do PCIe, os espaçadores e a placa sobre o Pi 5. O cooler ativo continua por baixo.
Instale o software indicado na doc
Atualize o sistema e instale os pacotes Hailo do modelo exato da sua placa, seguindo a página "AI" da documentação oficial do Raspberry Pi. Os nomes mudam entre gerações: copie de lá, não de tutorial antigo.
Confirme e rode um exemplo pronto
Verifique a placa com o comando abaixo e rode os exemplos de detecção da própria doc. Modelos seus precisam ser compilados para .hef com as ferramentas da Hailo, num PC.
lspci | grep -i hailo # a placa aparece no barramento PCIe?
vcgencmd get_throttled # 0x0: a fonte aguenta o conjunto Pi + HAT + câmera
Como verificar
- ✓O lspci mostra uma linha com "Hailo"; sem ela, revise o cabo PCIe e o encaixe.
- ✓O exemplo de detecção da doc roda com FPS bem acima do seu teste em CPU.
Por que aprender
O acelerador não é obrigatório para esta trilha: o projeto 3.6 funciona com CPU e NCNN. Mas entender quando ele vale (muitos objetos, FPS alto, IA de linguagem no mesmo robô) evita comprar cedo demais ou insistir tarde demais na CPU.
Conceitos-chave
🏷️ Treinar com suas próprias imagens
O COCO não tem "minha caneca", "cone laranja da pista" ou "peça da competição". Para isso você faz um ajuste fino: parte do yolo26n, que já sabe ver formas, e mostra algumas centenas de fotos suas com as caixas marcadas. O treino roda num PC com GPU NVIDIA ou no Google Colab (GPU gratuita no navegador); o Pi só recebe o resultado pronto. Treinar no Pi até funciona, mas é lento demais para valer a pena.
🌱 Novo aqui?
Rotular é desenhar a caixa em volta de cada objeto em cada foto e dizer a classe. O conjunto de fotos rotuladas é o dataset; ele se divide em treino (o modelo aprende com elas) e validação (fotos que o modelo nunca viu, usadas para medir se aprendeu de verdade). Uma época é uma passada completa por todas as fotos de treino.
Como ler: os passos roxos acontecem fora do robô; o ciano é o robô usando o modelo. A volta tracejada é o segredo: o primeiro modelo sempre erra em algum caso, e cada erro fotografado e rotulado melhora o próximo treino.
Passo a passo
Fotografe com a câmera do robô
Comece com 150 a 300 fotos por classe, tiradas pela própria Camera Module 3, no lugar e na luz em que o robô vai trabalhar: perto, longe, de lado, parcialmente escondido, com fundos diferentes.
Rotule e exporte no formato YOLO
Use uma ferramenta de rotulagem como Label Studio, CVAT ou Roboflow e exporte no formato YOLO: uma pasta de imagens e um .txt por imagem, com uma linha por objeto (classe, centro x, centro y, largura, altura, tudo de 0 a 1). Separe cerca de 20% para validação.
Treine, leve o best.pt e exporte
Rode o treino abaixo no PC ou no Colab, copie best.pt para o Pi com scp e exporte para NCNN como no tópico 3.
Objetivo: descrever o dataset e treinar um detector de duas classes a partir do yolo26n. Troque o caminho e os nomes das classes pelos seus.
# Estrutura esperada:
# meu_dataset/images/train/*.jpg meu_dataset/labels/train/*.txt
# meu_dataset/images/val/*.jpg meu_dataset/labels/val/*.txt
path: /caminho/para/meu_dataset
train: images/train
val: images/val
names:
0: caneca
1: cone
pip install ultralytics
yolo detect train data=meu_dataset/data.yaml model=yolo26n.pt epochs=100 imgsz=640 batch=16
# ao final: runs/detect/train/weights/best.pt (o melhor modelo na validação)
yolo detect val model=runs/detect/train/weights/best.pt data=meu_dataset/data.yaml
# depois, no Pi:
# scp best.pt <seu_usuario>@robo.local:~/robo/
# yolo export model=best.pt format=ncnn → python yolo_camera.py best_ncnn_model
Como verificar
- ✓O val mostra a métrica mAP50 por classe; acima de 0,8 é um bom começo para objetos simples.
- ✓No Pi, o yolo_camera.py com o seu modelo imprime "caneca" e "cone" ao vivo.
- ✗Nota alta no treino e erro no robô? As fotos de validação eram parecidas demais com as de treino: fotografe em outro dia e lugar.
Por que aprender
É aqui que a visão do robô passa a servir ao seu projeto, e não ao contrário: competição, separação de peças, robô que busca um objeto específico. E o processo (coletar, rotular, treinar, testar, voltar) é o mesmo que você usa na Trilha 5 para ensinar o braço por demonstração.
Conceitos-chave
⚠️ Limites: luz, distância, falsos positivos
Um detector não "vê" como você: ele dá um palpite estatístico a cada quadro. Com pouca luz, o objeto fica escuro e borrado; longe, ocupa poucos pixels depois do redimensionamento; e às vezes uma mochila vira "pessoa" por um quadro. O limiar de confiança é o botão que você controla: alto demais e o robô perde o alvo; baixo demais e ele persegue fantasmas. Por isso o código do robô nunca reage a um quadro só.
🌱 Novo aqui?
Um falso positivo é o modelo achar algo que não está lá. Um falso negativo é não achar algo que está. Baixar o limiar troca falsos negativos por falsos positivos, e subir faz o contrário: não existe valor que zere os dois. Persistência é exigir que o objeto apareça em vários quadros seguidos antes de agir.
Como ler: a régua é o valor de conf. À esquerda (vermelho) o robô reage a tudo; à direita (ciano) só a objetos muito nítidos. A moldura roxa é um ponto de partida razoável, que fica muito mais estável quando você exige que o objeto apareça em alguns quadros seguidos.
Objetivo: transformar as detecções brutas numa decisão estável: só a classe que interessa, só caixas grandes o bastante e só depois de 3 quadros seguidos. O resultado é o erro horizontal, igual ao do módulo 3.2.
# Decisão estável a partir do YOLO26: classe, tamanho mínimo e persistência
import time
from picamera2 import Picamera2
from ultralytics import YOLO
ALVO = "person" # nome da classe no modelo (COCO usa nomes em inglês)
CONF_MIN = 0.5
AREA_MIN = 0.02 # caixa ocupa pelo menos 2% da imagem
QUADROS_SEGUIDOS = 3
LARGURA, ALTURA = 640, 480
modelo = YOLO("yolo26n_ncnn_model", task="detect")
picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration(main={"size": (LARGURA, ALTURA), "format": "RGB888"}))
picam2.start(); time.sleep(1)
contador = 0
try:
while True:
r = modelo(picam2.capture_array(), imgsz=640, conf=CONF_MIN, verbose=False)[0]
melhor = None
for (x1, y1, x2, y2), c in zip(r.boxes.xyxy.tolist(), r.boxes.cls.tolist()):
area = (x2 - x1) * (y2 - y1) / (LARGURA * ALTURA)
if r.names[int(c)] == ALVO and area >= AREA_MIN:
if melhor is None or area > melhor[1]:
melhor = ((x1 + x2) / 2, area) # centro x e tamanho
contador = contador + 1 if melhor else 0
if contador >= QUADROS_SEGUIDOS:
cx, area = melhor
print(f"ALVO firme erro={cx - LARGURA / 2:+5.0f} tamanho={area:.2f}")
else:
print(f"sem alvo firme ({contador}/{QUADROS_SEGUIDOS}) → robô parado")
except KeyboardInterrupt:
picam2.stop()
Como verificar
- ✓Ao entrar na frente da câmera, aparecem 1/3, 2/3 e então "ALVO firme" com o erro mudando de sinal conforme você anda.
- ✓Uma detecção falsa de um quadro só não chega a virar "ALVO firme".
- ✗Some quando você se afasta uns metros? Baixe AREA_MIN ou aceite que essa é a distância útil da sua câmera.
✓ Faça
- ✓Robô para quando perde o alvo, em vez de continuar o último comando.
- ✓Ultrassom ou bumper continuam ligados para não bater em nada.
- ✓Testar com luz de manhã, de tarde e à noite.
✗ Não faça
- ✗Confiar só na câmera para parar antes de uma pessoa ou de uma escada.
- ✗Reagir a um único quadro com confiança alta.
- ✗Filmar ou seguir pessoas sem que elas saibam e concordem.
Por que aprender
Robô que segue pessoa é o projeto da trilha, e ele só é seguro se você souber onde a visão falha. Limiar, tamanho mínimo, persistência e parada ao perder o alvo são as quatro proteções que separam uma demonstração bonita de um robô em que dá para confiar.
Conceitos-chave
✅ Resumo do módulo
Para ir além
- Ultralytics no Raspberry Pi — instalação, NCNN e números de referência
- Treinar com a Ultralytics — parâmetros do treino e do dataset
- Exportar para NCNN — detalhes do formato
- IA no Raspberry Pi (AI HAT+) — instalação e exemplos oficiais da Hailo
- Documentação do OpenCV — para desenhar e processar em volta do detector
Próximo módulo
3.4 · IA dentro do microcontrolador: modelos pequenos, quantizados, rodando no próprio ESP32-S3.