Ver como markdown

Detecção de pontos

A detecção de pontos devolve uma localização x, y por objeto em vez de um bounding box. O LibreYOLO expõe isso como a tarefa point, e uma predição carrega uma linha de x, y, classe e confiança por objeto.

Definição

A tarefa point localiza cada objeto com uma única coordenada x, y e uma classe, sem largura, altura ou máscara. Como uma predição é uma lista plana de objetos, a contagem de linhas é a contagem de objetos, e é isso que faz desta a tarefa de contagem.

Uma predição preenche result.points, um payload Points que encapsula um array (N, 4) de linhas x, y, class, confidence em pixels da imagem original. .xy devolve as coordenadas, .xyn as mesmas coordenadas divididas pelo tamanho da imagem, .cls os índices de classe e .conf os scores; len() devolve o número de pontos. result.boxes fica vazio, então iou e max_det não têm sobre o que agir.

Modelos

Três famílias atendem point, e elas não são intercambiáveis.

FOMO é a opção de vocabulário fixo: um classificador de grade que rotula cada célula de uma grade de baixa resolução como fundo ou centro de objeto. É a única família de pontos que o LibreYOLO consegue treinar, e a única que exporta.

LocateAnything recebe texto em vez de um índice de classe, então o vocabulário é qualquer frase que você escrever. Ele precisa do extra vlm, é construído como LibreLocateAnything e não pela factory LibreYOLO(), e seus pesos são restritos a uso não comercial. Os termos exatos, e as duas licenças adicionais que o checkpoint compõe, estão na página dele.

SenseNova-Vision chega a point pelo mesmo checkpoint de geração por prompt que usa para outras seis tarefas, carregado com LibreVLM("sensenova-vision", task="point"). Ele precisa do extra sensenova, e cada predição é uma passagem de geração sobre um modelo de 7B, então espere uma latência por imagem bem mais alta que a de um detector feito sob medida. Seus pesos são não comerciais; a licença está na página dele.

Predição

Os pesos do LibreFOMO são a única exceção ao download automático neste site. LibreYOLO("LibreFOMOs-point.pt") procura esse arquivo no disco e levanta um ValueError nomeando-o em vez de baixá-lo. Baixe primeiro um checkpoint da organização LibreYOLO no Hugging Face e carregue-o pelo caminho local, ou treine o seu.

Prever pontos e contá-los
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Os pesos do LibreFOMO não têm download automático. Baixe primeiro um# checkpoint de https://huggingface.co/LibreYOLO e carregue-o pelo caminho local.model = LibreYOLO("./LibreFOMOs-point.pt")result = model(SAMPLE_IMAGE, save=True) points = result.pointsprint(len(points))     # contagem de objetosprint(points.xy)       # (N, 2) centros em pixels da imagem originalprint(points.cls, points.conf)
Coordenadas normalizadas e contagens por classe
from collections import Counter from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("./LibreFOMOs-point.pt")result = model(SAMPLE_IMAGE) points = result.points.numpy()print(points.xyn)                          # os mesmos centros em [0, 1]print(Counter(points.cls.astype(int).tolist()))

O nome do arquivo precisa carregar o sufixo de tarefa -point para o loader reconhecê-lo. predict(..., nms_radius=1) controla quantas células de grade duas detecções do FOMO precisam ter entre si para que ambas sobrevivam. Veja predição para fontes, streaming e tratamento de resultados.

Formato do dataset

point não tem formato de rótulos próprio. As famílias de pontos leem o layout padrão de detecção do YOLO e derivam um centro de cada linha de caixa, então cx cy é o ponto e w h só decidem se a linha é válida.

dataset/
  data.yaml
  images/
    train/scene.jpg
    val/scene.jpg
  labels/
    train/scene.txt
    val/scene.txt

Cada arquivo de rótulos contém uma linha por objeto, com coordenadas normalizadas:

<class_id> <cx> <cy> <w> <h>
yaml
path: dataset
train: images/train
val: images/val
nc: 1
names: {0: seedling}

Um arquivo de rótulos ausente ou vazio significa nenhum objeto. Veja formatos de dataset para o contrato completo.

Treinamento

O FOMO é a única família de pontos com implementação de treinamento. train() no LocateAnything e no SenseNova-Vision levanta NotImplementedError; faça fine-tuning desses modelos upstream e carregue o resultado.

Treinar o FOMO em um dataset YOLO
from libreyolo import LibreYOLO model = LibreYOLO("./LibreFOMOs-point.pt")model.train(data="my-dataset.yaml", epochs=40, batch=32, lr0=3e-4)
Prever com o checkpoint treinado
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("./LibreFOMOs-point.pt")results = model.train(data="my-dataset.yaml", epochs=40) # train() recarrega o melhor checkpoint no mesmo objeto, então o# modelo prevê com os pesos treinados quando a chamada retorna.print(results["best_checkpoint"])print(model(SAMPLE_IMAGE).points.xy)

imgsz não é uma escolha livre no FOMO: ele assume por padrão a resolução nativa do checkpoint carregado, e passar um valor diferente levanta ValueError nomeando o tamanho que ele espera. Veja treinamento para datasets, loggers e multi-GPU, e a página do FOMO para os padrões desta família.

Validação

val() casa os pontos previstos com os pontos de ground truth um a um pelo algoritmo húngaro, ao longo de uma varredura de limiares de distância. Um limiar é uma distância euclidiana em coordenadas normalizadas da imagem, e a varredura padrão são dez valores de 0.01 a 0.10.

Validar e ler as chaves das métricas
from libreyolo import LibreYOLO model = LibreYOLO("./LibreFOMOs-point.pt")metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/precision"], metrics["metrics/recall"])print(metrics["metrics/f1"])print(metrics["metrics/mAP@[0.01:0.10]"])   # fitnessprint(metrics["metrics/MLE"])               # erro médio de localizaçãoprint(metrics["metrics/MAE"], metrics["metrics/RMSE"])   # erro de contagem
Mudar os limiares de distância
from libreyolo import LibreYOLO model = LibreYOLO("./LibreFOMOs-point.pt") # Os limites da varredura fazem parte do texto da chave, então uma# varredura personalizada renomeia as chaves de mAP que ela produz.metrics = model.val(data="my-dataset.yaml", dist_thresholds=[0.02, 0.05]) print(metrics["metrics/mAP@0.02"])print(metrics["metrics/mAP@[0.02:0.05]"])

metrics/precision, metrics/recall e metrics/f1 são médias macro sobre as classes no limiar mais estrito da varredura, 0.01 por padrão. metrics/mAP@0.01 é a precisão média nesse mesmo limiar, e metrics/mAP@[0.01:0.10] é a média sobre toda a varredura. Esse valor da varredura também é o fitness, o número que a seleção do melhor checkpoint lê. Ambas as chaves de mAP são construídas a partir dos limiares em uso, então passar dist_thresholds= as renomeia.

metrics/MLE é a distância média entre os pares casados no limiar mais estrito, nas mesmas unidades normalizadas. metrics/MAE e metrics/RMSE são métricas de contagem, não de localização: elas medem a diferença, por imagem, entre o número de pontos previstos e o de pontos do ground truth.

O FOMO acrescenta um segundo grupo, em nível de grade, além desses. Ele varre a confiança e o nms_radius e publica a combinação de melhor F1 como metrics/grid_F1, metrics/grid_precision, metrics/grid_recall, metrics/grid_mean_distance, metrics/grid_TP, metrics/grid_FP e metrics/grid_FN, com as configurações que a produziram em decode/threshold e decode/nms_radius.

Exportação

O FOMO exporta pelo caminho de exportação compartilhado, e um artefato exportado é carregado de volta por LibreYOLO() a partir do sufixo do arquivo, então um arquivo .onnx ou .engine se comporta como um checkpoint e devolve o mesmo Results.

Exportar
from libreyolo import LibreYOLO model = LibreYOLO("./LibreFOMOs-point.pt")model.export(format="onnx")
Rodar o arquivo exportado
from libreyolo import LibreYOLO, SAMPLE_IMAGE # A factory roteia pelo sufixo do arquivo, então um artefato exportado# carrega como qualquer checkpoint e retorna o mesmo objeto Results.model = LibreYOLO("./LibreFOMOs-point.onnx")result = model(SAMPLE_IMAGE) print(result.points.xy)

A cobertura por formato está na página do FOMO e na matriz completa de exportação. LocateAnything e SenseNova-Vision não exportam: export() levanta erro em ambos, porque um modelo generativo não tem grafo de detecção rastreável.

Verificado com o LibreYOLO v1.5.0.