Estimativa do olhar
A estimativa do olhar retorna uma direção de olhar para cada rosto de uma imagem. O LibreYOLO modela isso como uma tarefa de duas etapas: um detector de rostos roda primeiro, e uma cabeça de olhar lê o pitch e o yaw de cada recorte de rosto que ele retorna.
Definição
A estimativa do olhar retorna dois ângulos por rosto. result.gaze é um payload
Gaze de formato (N, 2), com o pitch na coluna 0 e o yaw na coluna 1, em
radianos, alinhado linha a linha com result.boxes, os boxes de rosto
detectados. A convenção é a que o L2CS-Net usa: um yaw positivo gira o olhar
para a esquerda do sujeito, e um pitch positivo gira o olhar para baixo.
O mesmo payload expõe pitch_deg e yaw_deg para graus, e direction_3d, um
vetor unitário (N, 3) no referencial da câmera com as colunas (x, y, z).
Como a tarefa é de duas etapas, uma predição depende de dois modelos. Rostos que
o detector deixa passar não têm linha de olhar, e boxes que ele posiciona mal
produzem ângulos a partir de um rosto mal recortado. A chave canônica da tarefa é
gaze; gaze-estimation é normalizado para ela.
Modelos
A L2CS-Net é a única família que atende esta tarefa. Ela combina um tronco ResNet com duas cabeças paralelas de classificação por bins de ângulo, uma para o pitch e outra para o yaw, sobre recortes de rosto de 448x448. A arquitetura dá suporte a cinco profundidades de backbone, e uma delas, a ResNet-50, tem checkpoint publicado.
Os pesos carregam uma restrição de licença. Foram treinados no Gaze360, cuja
licença permite apenas uso em pesquisa e uso não comercial e proíbe a
redistribuição, então o LibreYOLO não espelha nada para essa família. O único
checkpoint que a biblioteca consegue baixar automaticamente vem direto da
distribuição dos próprios autores no Google Drive, via gdown, depois de
imprimir os termos da licença. Leia L2CS-Net antes de fazer
deploy dele.
Esse caminho de download precisa do extra gaze:
pip install "libreyolo[gaze]"Sem ele, a biblioteca imprime instruções de download manual em vez de tentar a transferência. Fazer predição e exportação com um checkpoint que você já tem não exige extra nenhum.
Predição
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Sem face_detector, a predição recorre ao detector embutido do# OpenCV, então nada é baixado além do checkpoint.model = LibreYOLO("LibreL2CSr50.pt")result = model(SAMPLE_IMAGE) gaze = result.gazeprint(gaze.pitch, gaze.yaw) # radianos, uma linha por rostoprint(gaze.pitch_deg, gaze.yaw_deg) # os mesmos ângulos em grausprint(gaze.direction_3d) # vetores unitários (N, 3)# Ao contrário do caminho em Python, a CLI não tem fallback automático:# modelos de olhar exigem um detector de rostos explícito, e ele precisa# ser um detector do LibreYOLO cujos boxes sejam rostos.libreyolo predict model=LibreL2CSr50.pt source=photo.jpg face_detector=face-detector.pt save=Truefrom libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreL2CSr50.pt") # Passe para a cabeça de olhar os boxes de um detector que você já rodou.result = model(SAMPLE_IMAGE, face_boxes=[[34, 12, 90, 80]]) # Ou nomeie um dos detectores embutidos.result = model(SAMPLE_IMAGE, face_detector="yunet")A fonte dos rostos é escolhida de uma destas três formas. face_boxes passa
boxes que você já calculou e pula a detecção. face_detector aceita "auto",
"haar", "yunet", um modelo de detecção do LibreYOLO ou um callable comum, e
pode ser definido no construtor ou a cada chamada. Se você não definir nada em
Python, a predição recorre ao detector embutido do OpenCV, então uma chamada
simples funciona sem configurar nada. No OpenCV 4 esse detector é a cascata de
Haar que vem dentro do wheel e não precisa de download nenhum; no OpenCV 5, onde
a API do Haar foi removida, é o YuNet, que baixa uma única vez um arquivo de
modelo pequeno do zoo do OpenCV.
A CLI não compartilha esse fallback. libreyolo predict rejeita um modelo de
olhar sem face_detector=, e o valor que ele aceita é o nome de um detector do
LibreYOLO ou o caminho de um checkpoint. Veja predição para
fontes, streaming e tratamento de resultados.
Treinamento
Nenhuma família desta tarefa treina dentro do LibreYOLO. LibreL2CS.train()
lança uma exceção: treine no projeto original do L2CS-Net e carregue aqui o
state dict resultante.
Validação
Validar contra datasets de ground truth de olhar está fora do escopo, e val()
lança uma exceção em vez de retornar métricas que não calculou. Não existe
dicionário metrics/ para esta tarefa. Faça a avaliação no projeto original,
com o dataset para o qual o checkpoint foi treinado.
Exportação
from libreyolo import LibreYOLO model = LibreYOLO("LibreL2CSr50.pt")model.export(format="onnx")libreyolo export model=LibreL2CSr50.pt format=onnxO contrato de exportação do olhar cobre ONNX, TorchScript, ExecuTorch, TensorRT
e OpenVINO. O que sai da biblioteca é apenas o tronco ResNet e as duas cabeças
de bins de ângulo: o grafo recebe um recorte de rosto 448x448 já pré-processado
e retorna os logits brutos de yaw e pitch. A detecção de rostos, o recorte, o
softmax, o valor esperado sobre os bins e a conversão para ângulos ficam todos em
Python, em libreyolo.models.l2cs.utils. Veja exportação para os
formatos e seus argumentos.