Object detection
Object detection locates every object instance in an image and returns an axis-aligned rectangle, a class label and a score for each one. The task key is detect.
Definition
Object detection answers where each object is and what it is. One image in, one row per instance out: four numbers for the rectangle, a class index and a score. Nothing about pixel shape, orientation or parts is included, which is what separates it from instance segmentation, oriented boxes and pose.
detect is the canonical task key and the default: a checkpoint whose filename
carries no task suffix loads as a detector.
predict() fills result.boxes. .xyxy gives pixel corners on the
original image canvas, .conf the score, and .cls the class index into
result.names. .xywh, .xyxyn and .xywhn are derived views of the
same rows, and .id carries a track id once a tracker is attached. Iterating
a Boxes object yields one-row slices, so box.cls, box.conf and
box.xyxy all work per detection.
Models
Eleven families both train and predict: YOLOv9,
RF-DETR, EdgeCrafter,
RT-DETR, D-FINE,
DEIM, YOLO-NAS,
YOLOX, YOLOv7,
RTMDet and PicoDet. YOLOv9 and
RF-DETR are the two flagship families, and features land on them first. RF-DETR
needs its own extra, pip install "libreyolo[rfdetr]"; the rest run on the
base package.
Eleven more predict, validate and export, but their train() raises
NotImplementedError: LW-DETR,
DETR, Deformable DETR,
DINO-DETR, Faster R-CNN,
Mask R-CNN, FCOS,
RetinaNet, SSD,
CenterNet and
EfficientDet.
The Darknet lineage, YOLOv1, YOLOv2, YOLOv3 and YOLOv4, is kept as a frozen exhibit: predict, validate and export work, training does not.
A separate group takes its class list at runtime rather than from the checkpoint, so it detects names never seen in training: Grounding DINO, OWLv2, OMDet-Turbo and OV-DEIM, plus the vision-language families Florence-2, Kosmos-2, Qwen3-VL, SmolVLM2, InternVL3, LFM2-VL, LocateAnything, SenseNova-Vision and LibreMODUS. These load through their own factory and extras; each model page carries the exact call.
Predict
Weights download from Hugging Face on first use and are cached locally.
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreYOLO9t.pt")result = model(SAMPLE_IMAGE, save=True) for box in result.boxes: print(result.names[int(box.cls)], float(box.conf), box.xyxy)libreyolo predict model=LibreYOLO9t.pt save=True \ source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpgfrom libreyolo import LibreYOLO, SAMPLE_IMAGE # The factory routes on the checkpoint, and every detector returns the# same Results object, so switching family is a one line change.model = LibreYOLO("LibreDFINEn.pt")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy.shape)from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9t.pt") # Any source the library accepts: file, folder, URL, webcam index,# RTSP stream, or a .streams list.for result in model.predict("clip.mp4", stream=True, save=True): print(len(result.boxes))conf sets the confidence threshold and max_det caps the number of rows.
iou is the NMS threshold, so it only has an effect on a family that runs NMS;
RF-DETR and the end-to-end YOLOv9 head decode a fixed set of predictions and
ignore it. See prediction for sources, streaming and result
handling.
Dataset format
One .txt label file per image, found by swapping images for labels in the
image path and changing the extension.
dataset/
data.yaml
images/
train/000001.jpg
val/000101.jpg
labels/
train/000001.txt
val/000101.txtEach row is exactly five fields, a class index followed by a normalized center-and-size box:
<class_id> <cx> <cy> <w> <h>Coordinates are floats in [0, 1], relative to the original image width and
height. w and h must be positive. A missing or empty label file means the
image has no objects. Rows carry no confidence and no track id.
The YAML names the splits and the classes:
path: dataset
train: images/train
val: images/val
names:
0: person
1: bicycletrain and val may be image directories, image-list .txt files, or lists
of either. nc is optional and must match names when present. Native COCO
JSON works too: add an annotations mapping of split name to JSON file, and
the split path then gives the image root. When names is present it defines
the label ids, so the JSON category names have to match it.
Train
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9t.pt") # coco128.yaml downloads a 128-image sample on first use. Point data# at your own dataset YAML for a real run.model.train(data="coco128.yaml", epochs=50, imgsz=640, batch=8)libreyolo train model=LibreYOLO9t.pt data=coco128.yaml \ epochs=50 imgsz=640 batch=8libreyolo train model=LibreYOLO9t.pt data=coco128.yaml \ epochs=50 device=0,1 batch=-1epochs, imgsz, batch and lr0 are the arguments that move first. lr0 is
the one that does not carry across families: a rate a convolutional detector
tolerates will diverge a transformer one, so take the value from the model page
rather than from another family's example. A family can also ignore an argument
outright, and its page lists which. See training for datasets,
augmentation, multi-GPU and loggers.
Validate
val() returns a plain dictionary of metrics/ keys, computed with COCO
evaluation over the split named by val in the dataset YAML.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9t.pt") # val() returns a plain dict, not an object.metrics = model.val(data="coco128.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"], metrics["metrics/mAP75"])print(metrics["metrics/AR100"])libreyolo val model=LibreYOLO9t.pt data=coco128.yamlmetrics/mAP50-95 is mean average precision averaged over IoU thresholds 0.50
to 0.95, and it is the headline number. metrics/mAP50 and metrics/mAP75 are
the single-threshold versions. metrics/mAP_small, metrics/mAP_medium and
metrics/mAP_large split the same average by object area, and metrics/AR1,
metrics/AR10, metrics/AR100, metrics/AR_small, metrics/AR_medium and
metrics/AR_large are the matching average-recall figures.
metrics/AR_max_det and metrics/max_det record the detection cap the run
used.
Read metrics/precision and metrics/recall carefully on this task. They are
kept for backward compatibility and are aliases, not an operating point:
metrics/precision holds the same value as metrics/mAP50-95, and
metrics/recall the same value as metrics/AR100. Plotting them as a
precision-recall pair reports one number twice. Four keys also repeat under a
(B) suffix, for box, so that a detection key reads the same on a model that
also predicts masks: metrics/mAP50-95(B), metrics/mAP50(B),
metrics/precision(B) and metrics/recall(B).
Export
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9t.pt")model.export(format="onnx", imgsz=640)libreyolo export model=LibreYOLO9t.pt format=onnx imgsz=640from libreyolo import LibreYOLO, SAMPLE_IMAGE # The factory routes on the file suffix, so an exported artifact loads# like a checkpoint and returns the same Results object.model = LibreYOLO("LibreYOLO9t.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)An exported artifact loads back through LibreYOLO() on its file suffix, so a
.onnx or .engine file behaves like a checkpoint and returns the same
Results. Format coverage differs by family; the matrix on each model page is
generated from the validated set rather than typed by hand. See
export and deploy for the formats, their extras and their
constraints.