Ultralytics YOLO27: Inscreve-te na lista de espera.
Get Started
Fundamentos de visão computacional·Define o problema·Aula 1/10
Aulainiciante

Define o problema

Transforma uma ideia vaga de produto numa especificação de tarefa de três linhas e mantém a regra de negócio no código, onde podes alterá-la sem voltar a treinar.

Cruzamento urbano ensolarado visto de cima, com caixas do Ultralytics YOLO em peões, ciclistas, um autocarro e carros

A maioria dos projetos de visão computacional que ficam pelo caminho nunca teve uma pergunta clara. «Detetar comportamentos inseguros» parece um requisito, mas um anotador não consegue rotulá-lo, um modelo não consegue aprendê-lo e ninguém consegue determinar quando funciona. Uma especificação de três linhas resolve isso numa tarde — e determina que tarefa vais treinar, o que vais rotular e que métrica vais comunicar.

Resultado

Escreve uma especificação de tarefa de três linhas (entrada, saída, decisão) e implementa a decisão em código que lê a saída do YOLO26.

Via rápida
Se já sabes orientar-te, aqui está a versão resumida.
  1. Entrada: origem, resolução, frequência de fotogramas e cena.

  2. Saída: um tipo de dados — rótulo, caixas, máscaras, pontos-chave ou um mapa por píxel — nunca um verbo.

  3. Decisão: quem age, quando e segundo que regra.

  4. O modelo é responsável pela linha da saída. A linha da decisão é código que podes alterar sem voltar a treinar.

  5. Testa a regra com uma saída real antes de confiares nela: a sobreposição na imagem não equivale à proximidade física.

Prático

Porque é que a especificação vem primeiro#

Etapas 0 a 4 de um projeto de visão computacional: preparação dos alicerces, recolha e preparação dos dados, engenharia de atributos e desenvolvimento do modelo, implementação do modelo e monitorização do modelo

Cada etapa de um projeto de visão computacional herda o seu objetivo da etapa 0. Uma pergunta vaga produz um conjunto de dados vago, anotadores que discordam e uma métrica que mede a coisa errada — e nenhum treino na etapa 2 consegue corrigir isso.

As três linhas#

Uma especificação de tarefa consiste em três frases, uma por linha. Cada uma responde a uma pergunta que uma pessoa diferente do projeto fará:

LinhaPergunta a que respondeFracaForte
EntradaO que vê o modelo?«Imagens de câmaras»«Fotogramas de 1920×1080 a 5 fps, de 12 câmaras instaladas no teto»
SaídaQue dados são devolvidos?«Detetar problemas de segurança»«Caixas para forklift e person, cada uma com uma pontuação de confiança»
DecisãoQuem age e quando?«Melhorar a segurança»«Notificar o supervisor do turno quando um empilhador e uma pessoa estiverem a menos de 2 m durante 2 s»

A linha da saída exige mais atenção, porque o tipo de dados determina a tarefa:

Saídas das sete tarefas do Ultralytics YOLO lado a lado: deteção, pose, segmentação, classificação, OBB, segmentação semântica e profundidade

Um rótulo para a imagem inteira significa classificação; caixas significam deteção; contornos significam segmentação; articulações significam pose; caixas rodadas significam OBB; uma classe ou uma distância por píxel significa segmentação semântica ou profundidade. A próxima lição aborda as sete tarefas.

Exemplo trabalhado: mantém o modelo e a regra separados#

«Queremos saber quando os empilhadores estão a fazer algo perigoso no armazém.»

Essa frase descreve um projeto, não uma tarefa. Mistura duas funções: encontrar empilhadores e pessoas, o que diz respeito aos píxeis, e decidir o que é perigoso, o que diz respeito à política. Separa-as:

Só o detetor é o modelo. O losango é apenas código. Podes testar esta separação agora: bus.jpg não tem empilhadores, mas um autocarro e quatro pessoas permitem fazer o mesmo teste. Uma primeira regra diz «alertar quando mais de 30% da caixa de uma pessoa se sobrepõe à caixa de um veículo»:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
result = model("https://ultralytics.com/images/bus.jpg", verbose=False)[0]

# The model's job ends here: a class, a box, and a confidence per object.
people = [b.xyxy[0].tolist() for b in result.boxes if result.names[int(b.cls)] == "person"]
vehicles = [b.xyxy[0].tolist() for b in result.boxes if result.names[int(b.cls)] == "bus"]

def share_inside(a, b):
    """Fraction of box a's area that lies inside box b."""
    w = max(0, min(a[2], b[2]) - max(a[0], b[0]))
    h = max(0, min(a[3], b[3]) - max(a[1], b[1]))
    return w * h / ((a[2] - a[0]) * (a[3] - a[1]))

# The decision rule is plain code: change the policy without retraining.
ALERT_SHARE = 0.30
for person in people:
    share = max(share_inside(person, v) for v in vehicles)
    print(f"person at x={person[0]:3.0f}: {share:4.0%} inside the bus box -> {'ALERT' if share > ALERT_SHARE else 'ok'}")
person at x= 49:  70% inside the bus box -> ALERT
person at x=223:  76% inside the bus box -> ALERT
person at x=670:  70% inside the bus box -> ALERT
person at x=  0:  62% inside the bus box -> ALERT

Quatro alertas, todos falsos: as pessoas estão no passeio, à frente de um autocarro estacionado. O detetor está certo em relação a todas as caixas; a regra está errada, porque a sobreposição numa imagem 2D não significa que duas coisas estejam próximas no mundo real. Como a regra é código, a correção também é código. Compara o ponto onde os pés de cada pessoa tocam no chão com a linha das rodas do autocarro:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
result = model("https://ultralytics.com/images/bus.jpg", verbose=False)[0]
people = [b.xyxy[0].tolist() for b in result.boxes if result.names[int(b.cls)] == "person"]
vehicles = [b.xyxy[0].tolist() for b in result.boxes if result.names[int(b.cls)] == "bus"]

def same_ground_line(person, vehicle, tolerance=40):
    """True when the person's feet are level with the vehicle's wheels and inside its width."""
    feet_x, feet_y = (person[0] + person[2]) / 2, person[3]
    return vehicle[0] < feet_x < vehicle[2] and abs(feet_y - vehicle[3]) < tolerance

for person in people:
    alert = any(same_ground_line(person, v) for v in vehicles)
    print(f"person at x={person[0]:3.0f}: feet y={person[3]:.0f}, bus wheels y={vehicles[0][3]:.0f} -> {'ALERT' if alert else 'ok'}")
person at x= 49: feet y=902, bus wheels y=751 -> ok
person at x=223: feet y=861, bus wheels y=751 -> ok
person at x=670: feet y=880, bus wheels y=751 -> ok
person at x=  0: feet y=871, bus wheels y=751 -> ok

Os pés de todas as pessoas estão 110–150 píxeis abaixo da linha das rodas, por isso estão mais perto da câmara do que o autocarro. Sem voltar a treinar nem a rotular: a equipa de segurança pode iterar na regra enquanto o detetor permanece fixo. Uma versão de produção mapearia os pés para coordenadas do chão com uma câmara calibrada e acrescentaria a persistência de 2 segundos através do rastreamento de objetos — ainda seria código sobre as mesmas caixas.

Tira a política do modelo

Palavras subjetivas — "inseguro", "defeituoso", "suspeito", "VIP" — pertencem ao código que lê a saída do modelo. Um modelo responde a perguntas sobre pixels. Se dois especialistas discutiriam sobre um rótulo, a discussão pertence a uma regra que você pode versionar, testar e alterar.

Armadilhas#

A linha de saída é uma ação

Sintoma: a especificação diz "detectar problemas de segurança" ou "entender a cena", e os anotadores perguntam o que devem desenhar. Solução: reescreva a saída como um tipo de dado com classes nomeadas: "caixas para forklift e person".

Uma classe que você não consegue apontar

Sintoma: uma classe como suspicious_behavior ou dangerous que dois anotadores rotulam de maneiras diferentes no mesmo quadro. Solução: substitua-a por evidências visíveis — uma pessoa dentro de uma zona restrita, uma porta mantida aberta — e transfira o julgamento para a linha de decisão.

A saída é uma frase ou uma previsão

Sintoma: "descreva o que está acontecendo" (geração de legendas) ou "preveja se a empilhadeira vai atingir alguém" (previsão). Solução: primeiro localize os objetos e, em seguida, adicione regras de rastreamento e movimento. Crie o detector antes da previsão.

Da especificação aos critérios de sucesso#

A especificação diz o que o modelo faz, não qual é o nível de qualidade suficiente nem quanto custa um erro em comparação com um falso alarme. Começa pelo objetivo de negócio, em Construir conjuntos de dados YOLO de alto desempenho, transforma a especificação em objetivos mensuráveis. Todas as lições seguintes deste curso remetem para as tuas três linhas.

Experimente

Escreve a especificação de três linhas para o teu próprio projeto — ou para uma câmara de loja que deve assinalar espaços vazios nas prateleiras. Limita cada linha a uma frase. Depois, enumera todas as palavras da linha da decisão que o modelo não consegue ver nos píxeis e escreve a decisão como uma regra de uma linha sobre a saída do modelo (pode ser pseudocódigo).

Concluído quando
Você concluiu a aula quando todos estes critérios forem atendidos.
  • A linha da entrada indica a origem, a resolução e a frequência de fotogramas.

  • A linha da saída é um tipo de dados com classes identificadas, não um verbo.

  • A decisão é escrita como uma regra sobre a saída, e todas as palavras subjetivas ficam nessa regra, não no nome de uma classe.

Mostrar solução

Uma especificação para a câmara da prateleira:

  • Entrada: uma imagem fixa de 1920×1080 a cada 60 segundos, captada por uma câmara fixa voltada para um corredor.
  • Saída: caixas delimitadoras para product e empty_facing (um espaço da prateleira sem produto), cada uma com uma pontuação de confiança.
  • Decisão: criar uma tarefa de reposição quando três ou mais caixas de empty_facing na mesma prateleira persistirem em cinco imagens fixas consecutivas durante o horário de funcionamento da loja.

As expressões que o modelo não consegue ver são tarefa de reposição, mesma prateleira, persistir em cinco imagens fixas e horário de funcionamento da loja. Como regra:

if count(empty_facing on shelf S) >= 3 in each of the last 5 stills and store_is_open(now):
    create_restock_task(shelf=S)

A loja pode alterar «3», «5» ou o horário de abertura sem voltar a rotular uma única imagem.

Próximos passos

A seguir: as sete tarefas suportadas pelo Ultralytics YOLO e como associar a tua linha de saída a exatamente uma delas.

Entre para salvar seu progresso