Executar inferência em vídeo
Execute YOLO26 em arquivos de vídeo e câmeras ao vivo com uso de memória limitado, rastreie objetos para contar cada um apenas uma vez e verifique se o modelo acompanha a taxa de quadros.
A maioria dos sistemas de visão implantados analisa vídeos: câmeras sobre esteiras, portas e estradas. O vídeo traz dois problemas que não existem em imagens individuais. Memória: não é possível manter uma gravação longa na RAM. Identidade: um detector vê a mesma pessoa em 60 quadros e informa 60 pessoas.
Nesta lição, você transmitirá vídeo quadro a quadro com o modo Predict, adicionará o rastreamento de objetos para contar cada pessoa uma única vez, escreverá seu próprio loop de câmera e medirá se o modelo acompanha a taxa de quadros.
Prático
Exemplo prático: fazer previsões em um arquivo de vídeo#
Os vídeos usam o mesmo modo Predict que as imagens. Este clipe de 62 quadros mostra pessoas atravessando um átrio:
yolo predict model=yolo26n.pt source=https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4video 1/1 (frame 1/62) solutions_ci_demo.mp4: 384x640 22 persons, 27.3ms
...
video 1/1 (frame 62/62) solutions_ci_demo.mp4: 384x640 22 persons, 54.8ms
Results saved to runs/detect/predictframe 1/62: Ultralytics decodifica o vídeo e processa cada quadro como uma imagem.22 persons: detecções naquele quadro. As mesmas pessoas são contadas novamente em cada quadro.27.3ms...54.8ms: o tempo por quadro varia conforme as outras tarefas executadas pela máquina.
O vídeo anotado é runs/detect/predict/solutions_ci_demo.mp4. Seu próprio modelo funciona da mesma maneira: substitua yolo26n.pt por runs/detect/pills_v1/weights/best.pt.
Transmitir fontes longas e ao vivo#
Para executar código que atua sobre as detecções, percorra um fluxo. Cada iteração gera o Results de um quadro e depois o descarta:
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
source = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"
frames, people = 0, 0
for result in model(source, stream=True, classes=[0], verbose=False): # one Results object per frame
frames += 1
people += len(result.boxes)
print(f"{frames} frames, {people / frames:.1f} people per frame")62 frames, 22.2 people per frameO mesmo loop aceita o índice de uma webcam (source=0) ou uma URL de câmera, como rtsp://camera.local/stream, e é executado até o fim do fluxo ou até você interrompê-lo. Adicione vid_stride=2 para processar um quadro a cada dois. Para criar uma interface de navegador em torno desse loop, o guia Inferência ao vivo com Streamlit o encapsula em um app.
Exemplo prático: contar cada pessoa uma única vez#
"22 pessoas por quadro" não é o número que alguém quer saber; a pergunta é "quantas pessoas passaram por aqui". O rastreamento de múltiplos objetos associa caixas entre quadros, e o modo Track atribui a cada objeto um ID em boxes.id:
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
source = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"
seen = set()
for result in model.track(source, stream=True, persist=True, classes=[0], tracker="bytetrack.yaml", verbose=False):
if result.boxes.is_track:
seen.update(result.boxes.id.int().tolist())
print(f"{len(seen)} unique people tracked")32 unique people trackedis_track é False nos quadros anteriores à confirmação de qualquer rastreamento, quando boxes.id é None. Use os IDs para contagem, trajetórias ou lógica do tipo "este objeto está aqui há 3 segundos".

| Rastreador | Velocidade | Robustez |
|---|---|---|
bytetrack.yaml | Mais rápido e simples | Perde IDs com mais frequência quando os objetos desaparecem por alguns instantes |
botsort.yaml | Mais lento | Mantém os IDs com mais eficiência quando a câmera se move (compensação de movimento; ReID por aparência é opcional via with_reid) |
Se você não especificar tracker, Ultralytics usa tracktrack.yaml, o padrão atual; o modo Track também inclui ocsort.yaml, deepocsort.yaml e fasttrack.yaml. A escolha e o ajuste de rastreadores, além da criação de contagem de objetos, mapas de calor e estimativa de velocidade com base neles, são abordados em Rastrear objetos com ByteTrack, BoT-SORT e TrackTrack.
Exemplo prático: seu próprio loop de câmera#
Muitas vezes, aplicações reais leem os quadros diretamente — para redimensionar, recortar, adicionar carimbos de data/hora ou compartilhar uma câmera com outro código — e os passam ao modelo. Nesse caso, persist=True mantém o rastreador ativo entre as chamadas:
import cv2
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
cap = cv2.VideoCapture("solutions_ci_demo.mp4") # saved locally by the commands above; or 0, or an rtsp:// URL
seen = set()
while cap.isOpened():
ok, frame = cap.read()
if not ok:
break
result = model.track(frame, persist=True, classes=[0], tracker="bytetrack.yaml", verbose=False)[0]
if result.boxes.is_track:
seen.update(result.boxes.id.int().tolist())
cap.release()
print(f"{len(seen)} unique people, highest ID {max(seen)}")32 unique people, highest ID 67A mesma contagem de 32 pessoas de track.py. Observe que o maior ID é 67, não 32: o rastreador também atribui IDs a rastreamentos provisórios que nunca são confirmados, por isso há lacunas nos IDs.
Acompanhar a fonte#
Uma câmera de 30 FPS fornece um quadro a cada 33 ms, e a taxa efetiva é limitada pela etapa mais lenta entre decodificação, inferência e gravação. Na CPU do nosso laptop, yolo26n levou de 26 a 46 ms por quadro de 384×640 em diferentes execuções, dependendo das outras tarefas da máquina: no limite ou acima do orçamento, sem margem. Se a sua máquina não acompanhar, ajuste estes parâmetros nesta ordem:
| Ajuste | Efeito |
|---|---|
Modelo menor (n em vez de s) | Em geral, 2–3× mais rápido |
Reduza imgsz (480 em vez de 640) | Menos pixels e menos processamento; objetos pequenos são os primeiros a sofrer |
vid_stride=2 | Reduz o trabalho pela metade; adequado para cenas com movimento lento |
| Uma GPU ou uma exportação otimizada | Os maiores ganhos — um mecanismo TensorRT em NVIDIA ou INT8; veja a próxima lição |
O uso simultâneo de várias câmeras e o encadeamento de threads necessário são abordados em Inferência de múltiplos fluxos.
Evita estes erros#
Sintoma: a memória aumenta até o processo falhar durante uma gravação longa, ou uma chamada à câmara em direto nunca retorna. Causa: sem isso, a chamada Python recolhe um objeto Results por cada fotograma antes de retornar. Solução: passa stream=True e percorre o gerador — este não faz nada até ser iterado.
Sintoma: em cv2_loop.py sem persist=True, a contagem caiu para 27 e o ID mais alto também era 27: os IDs reiniciavam em cada fotograma, por isso a contagem "única" correspondia apenas ao fotograma com mais objetos. Solução: passa persist=True sempre que chamares track uma vez por fotograma.
Sintoma: uma contagem de 67 para 32 pessoas. Causa: há lacunas nos IDs devido a rastreios não confirmados. Solução: conta o número de elementos num conjunto de IDs, como em track.py.
O rastreador predefinido pode mudar entre versões. Passa tracker="bytetrack.yaml" (ou o que preferires) para que as contagens continuem comparáveis entre versões.
Mostrar solução
import sys
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
seen, times = set(), []
for result in model.track(sys.argv[1], stream=True, persist=True, tracker="bytetrack.yaml", verbose=False):
times.append(result.speed["inference"])
if result.boxes.is_track:
seen.update(result.boxes.id.int().tolist())
print(f"{len(seen)} unique objects, {sum(times) / len(times):.1f} ms inference per frame")Execute com python track_any.py your_video.mp4.
32 unique objects, 30.5 ms inference per frame (26-46 ms across runs on a laptop CPU)
Source is 30 FPS -> 33 ms budget: fits only on a quiet machine, with no headroom
First lever: export to OpenVINO or ONNX for this CPU, then vid_stride=2 if still short