Простые утилиты
Пакет ultralytics предоставляет множество утилит для поддержки, улучшения и ускорения твоих рабочих процессов. Хотя их гораздо больше, в этом руководстве освещены наиболее полезные для разработчиков инструменты, которые служат практическим справочником при программировании с использованием продуктов Ultralytics.
Watch: Ultralytics Utilities | Auto Annotation, Explorer API and Dataset Conversion
Данные
Автоматическая разметка / Аннотации
Аннотирование набора данных — это ресурсоемкий и трудоемкий процесс. Если у тебя есть модель обнаружения объектов Ultralytics YOLO, обученная на достаточном объеме данных, ты можешь использовать ее вместе с SAM для автоматической разметки дополнительных данных в формате сегментации.
from ultralytics.data.annotator import auto_annotate
auto_annotate(
data="path/to/new/data",
det_model="yolo26n.pt",
sam_model="mobile_sam.pt",
device="cuda",
output_dir="path/to/save_labels",
)Эта функция не возвращает никаких значений. Дополнительные детали:
- Смотри справочный раздел по
annotator.auto_annotateдля более глубокого понимания того, как работает эта функция. - Используй ее в сочетании с функцией
segments2boxesдля создания ограничивающих рамок обнаружения объектов.
Визуализация аннотаций набора данных
Эта функция визуализирует аннотации YOLO на изображении перед обучением, помогая выявить и исправить неверные аннотации, которые могут привести к ошибочным результатам обнаружения. Она рисует ограничивающие рамки, подписывает объекты именами классов и регулирует цвет текста в зависимости от яркости фона для лучшей читаемости.
from ultralytics.data.utils import visualize_image_annotations
label_map = { # Define the label map with all annotated class labels.
0: "person",
1: "car",
}
# Visualize
visualize_image_annotations(
"path/to/image.jpg", # Input image path.
"path/to/annotations.txt", # Annotation file path for the image.
label_map,
)Преобразование масок сегментации в формат YOLO

Используй это для преобразования набора данных с масками сегментации в формат сегментации Ultralytics YOLO. Эта функция берет директорию, содержащую маски в бинарном формате, и преобразует их в формат сегментации YOLO.
Преобразованные маски будут сохранены в указанной выходной директории.
from ultralytics.data.converter import convert_segment_masks_to_yolo_seg
# The classes here is the total classes in the dataset.
# for COCO dataset we have 80 classes.
convert_segment_masks_to_yolo_seg(masks_dir="path/to/masks_dir", output_dir="path/to/output_dir", classes=80)Преобразование COCO в формат YOLO
Используй это для преобразования JSON-аннотаций COCO в формат YOLO. Для наборов данных обнаружения объектов (ограничивающие рамки) установи use_segments и use_keypoints в значение False.
from ultralytics.data.converter import convert_coco
convert_coco(
"coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)Дополнительную информацию о функции convert_coco можно найти на странице справочника.
Получение размеров ограничивающих рамок
import cv2
from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator
model = YOLO("yolo26n.pt") # Load pretrain or fine-tune model
# Process the image
source = cv2.imread("path/to/image.jpg")
results = model(source)
# Extract results
annotator = Annotator(source, example=model.names)
for box in results[0].boxes.xyxy.cpu():
width, height, area = annotator.get_bbox_dimension(box)
print(f"Bounding Box Width {width.item()}, Height {height.item()}, Area {area.item()}")Преобразование ограничивающих рамок в сегменты
Имея данные ограничивающих рамок в формате x y w h, преобразуй их в сегменты с помощью функции yolo_bbox2segment. Организуй файлы изображений и аннотаций следующим образом:
data
|__ images
├─ 001.jpg
├─ 002.jpg
├─ ..
└─ NNN.jpg
|__ labels
├─ 001.txt
├─ 002.txt
├─ ..
└─ NNN.txtfrom ultralytics.data.converter import yolo_bbox2segment
yolo_bbox2segment(
im_dir="path/to/images",
save_dir=None, # saved to "labels-segment" in images directory
sam_model="sam_b.pt",
)Посети справочную страницу yolo_bbox2segment для получения дополнительной информации о функции.
Преобразование сегментов в ограничивающие рамки
Если у тебя есть набор данных, который использует формат набора данных сегментации, ты можешь легко преобразовать их в выровненные (или горизонтальные) ограничивающие рамки (формат x y w h) с помощью этой функции.
import numpy as np
from ultralytics.utils.ops import segments2boxes
segments = np.array(
[
[805, 392, 797, 400, ..., 808, 714, 808, 392],
[115, 398, 113, 400, ..., 150, 400, 149, 298],
[267, 412, 265, 413, ..., 300, 413, 299, 412],
]
)
segments2boxes([s.reshape(-1, 2) for s in segments])
# >>> array([[ 741.66, 631.12, 133.31, 479.25],
# [ 146.81, 649.69, 185.62, 502.88],
# [ 281.81, 636.19, 118.12, 448.88]],
# dtype=float32) # xywh bounding boxesЧтобы понять, как работает эта функция, посети справочную страницу.
Утилиты
Сжатие изображений
Сжимай отдельные файлы изображений до уменьшенного размера, сохраняя при этом их соотношение сторон и качество. Если входное изображение меньше заданного максимального размера, оно не будет изменено.
from pathlib import Path
from ultralytics.data.utils import compress_one_image
for f in Path("path/to/dataset").rglob("*.jpg"):
compress_one_image(f)Автоматическое разделение набора данных
Автоматически разделяй набор данных на выборки train/val/test и сохраняй полученные результаты в файлы autosplit_*.txt. Эта функция использует случайную выборку, которая исключается при использовании аргумента fraction для обучения.
from ultralytics.data.split import autosplit
autosplit(
path="path/to/images",
weights=(0.9, 0.1, 0.0), # (train, validation, test) fractional splits
annotated_only=False, # split only images with annotation file when True
)Смотри справочную страницу для получения дополнительных сведений об этой функции.
Преобразование сегмента-полигона в бинарную маску
Преобразуй один полигон (в виде списка) в бинарную маску заданного размера изображения. Полигон должен быть в форме [N, 2], где N — количество точек (x, y), определяющих контур полигона.
N всегда должно быть четным.
import numpy as np
from ultralytics.data.utils import polygon2mask
imgsz = (1080, 810)
polygon = np.array([805, 392, 797, 400, ..., 808, 714, 808, 392]) # (238, 2)
mask = polygon2mask(
imgsz, # tuple
[polygon], # input as list
color=255, # 8-bit binary
downsample_ratio=1,
)Ограничивающие рамки
Экземпляры горизонтальных ограничивающих рамок (BBox)
Для управления данными ограничивающих рамок класс Bboxes помогает конвертировать форматы координат, масштабировать размеры рамок, вычислять площади, учитывать смещения и многое другое.
import numpy as np
from ultralytics.utils.instance import Bboxes
boxes = Bboxes(
bboxes=np.array(
[
[22.878, 231.27, 804.98, 756.83],
[48.552, 398.56, 245.35, 902.71],
[669.47, 392.19, 809.72, 877.04],
[221.52, 405.8, 344.98, 857.54],
[0, 550.53, 63.01, 873.44],
[0.0584, 254.46, 32.561, 324.87],
]
),
format="xyxy",
)
boxes.areas()
# >>> array([ 4.1104e+05, 99216, 68000, 55772, 20347, 2288.5])
boxes.convert("xywh")
print(boxes.bboxes)
# >>> array(
# [[ 413.93, 494.05, 782.1, 525.56],
# [ 146.95, 650.63, 196.8, 504.15],
# [ 739.6, 634.62, 140.25, 484.85],
# [ 283.25, 631.67, 123.46, 451.74],
# [ 31.505, 711.99, 63.01, 322.91],
# [ 16.31, 289.67, 32.503, 70.41]]
# )Смотри справочный раздел Bboxes для ознакомления с другими атрибутами и методами.
Многие из следующих функций (и другие) доступны через класс Bboxes, но если ты предпочитаешь работать с функциями напрямую, смотри следующие подразделы о том, как импортировать их независимо.
Масштабирование рамок
При увеличении или уменьшении изображения ты можешь соответствующим образом масштабировать координаты ограничивающих рамок, используя ultralytics.utils.ops.scale_boxes.
import cv2 as cv
import numpy as np
from ultralytics.utils.ops import scale_boxes
image = cv.imread("ultralytics/assets/bus.jpg")
h, w, c = image.shape
resized = cv.resize(image, None, (), fx=1.2, fy=1.2)
new_h, new_w, _ = resized.shape
xyxy_boxes = np.array(
[
[22.878, 231.27, 804.98, 756.83],
[48.552, 398.56, 245.35, 902.71],
[669.47, 392.19, 809.72, 877.04],
[221.52, 405.8, 344.98, 857.54],
[0, 550.53, 63.01, 873.44],
[0.0584, 254.46, 32.561, 324.87],
]
)
new_boxes = scale_boxes(
img1_shape=(h, w), # original image dimensions
boxes=xyxy_boxes, # boxes from original image
img0_shape=(new_h, new_w), # resized image dimensions (scale to)
ratio_pad=None,
padding=False,
xywh=False,
)
print(new_boxes)
# >>> array(
# [[ 27.454, 277.52, 965.98, 908.2],
# [ 58.262, 478.27, 294.42, 1083.3],
# [ 803.36, 470.63, 971.66, 1052.4],
# [ 265.82, 486.96, 413.98, 1029],
# [ 0, 660.64, 75.612, 1048.1],
# [ 0.0701, 305.35, 39.073, 389.84]]
# )Преобразования форматов ограничивающих рамок
XYXY → XYWH
Преобразуй координаты ограничивающей рамки из формата (x1, y1, x2, y2) в формат (x, y, ширина, высота), где (x1, y1) — верхний левый угол, а (x2, y2) — нижний правый угол.
import numpy as np
from ultralytics.utils.ops import xyxy2xywh
xyxy_boxes = np.array(
[
[22.878, 231.27, 804.98, 756.83],
[48.552, 398.56, 245.35, 902.71],
[669.47, 392.19, 809.72, 877.04],
[221.52, 405.8, 344.98, 857.54],
[0, 550.53, 63.01, 873.44],
[0.0584, 254.46, 32.561, 324.87],
]
)
xywh = xyxy2xywh(xyxy_boxes)
print(xywh)
# >>> array(
# [[ 413.93, 494.05, 782.1, 525.56],
# [ 146.95, 650.63, 196.8, 504.15],
# [ 739.6, 634.62, 140.25, 484.85],
# [ 283.25, 631.67, 123.46, 451.74],
# [ 31.505, 711.99, 63.01, 322.91],
# [ 16.31, 289.67, 32.503, 70.41]]
# )Все преобразования ограничивающих рамок
from ultralytics.utils.ops import (
ltwh2xywh,
ltwh2xyxy,
xywh2ltwh, # xywh → top-left corner, w, h
xywh2xyxy,
xywhn2xyxy, # normalized → pixel
xyxy2ltwh, # xyxy → top-left corner, w, h
xyxy2xywhn, # pixel → normalized
)
for func in (ltwh2xywh, ltwh2xyxy, xywh2ltwh, xywh2xyxy, xywhn2xyxy, xyxy2ltwh, xyxy2xywhn):
print(help(func)) # print function docstringsSee the docstring for each function or visit the ultralytics.utils.ops reference page to read more.
Построение графиков (Plotting)
Утилиты для аннотирования
Ultralytics включает класс Annotator для аннотирования различных типов данных. Лучше всего использовать его с ограничивающими рамками обнаружения объектов, ключевыми точками позы и ориентированными ограничивающими рамками.
Аннотирование рамок
import cv2 as cv
import numpy as np
from ultralytics.utils.plotting import Annotator, colors
names = {
0: "person",
5: "bus",
11: "stop sign",
}
image = cv.imread("ultralytics/assets/bus.jpg")
ann = Annotator(
image,
line_width=None, # default auto-size
font_size=None, # default auto-size
font="Arial.ttf", # must be ImageFont compatible
pil=False, # use PIL, otherwise uses OpenCV
)
xyxy_boxes = np.array(
[
[5, 22.878, 231.27, 804.98, 756.83], # class-idx x1 y1 x2 y2
[0, 48.552, 398.56, 245.35, 902.71],
[0, 669.47, 392.19, 809.72, 877.04],
[0, 221.52, 405.8, 344.98, 857.54],
[0, 0, 550.53, 63.01, 873.44],
[11, 0.0584, 254.46, 32.561, 324.87],
]
)
for nb, box in enumerate(xyxy_boxes):
c_idx, *box = box
label = f"{str(nb).zfill(2)}:{names.get(int(c_idx))}"
ann.box_label(box, label, color=colors(c_idx, bgr=True))
image_with_bboxes = ann.result()Имена можно брать из model.names при работе с результатами обнаружения.
Также смотри справочную страницу Annotator для получения дополнительных сведений.
Аннотирование Ultralytics Sweep
import cv2
import numpy as np
from ultralytics import YOLO
from ultralytics.solutions.solutions import SolutionAnnotator
from ultralytics.utils.plotting import colors
# User defined video path and model file
cap = cv2.VideoCapture("path/to/video.mp4")
model = YOLO(model="yolo26s-seg.pt") # Model file, e.g., yolo26s.pt or yolo26m-seg.pt
if not cap.isOpened():
print("Error: Could not open video.")
exit()
# Initialize the video writer object.
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
video_writer = cv2.VideoWriter("ultralytics.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
masks = None # Initialize variable to store masks data
f = 0 # Initialize frame count variable for enabling mouse event.
line_x = w # Store width of line.
dragging = False # Initialize bool variable for line dragging.
classes = model.names # Store model classes names for plotting.
window_name = "Ultralytics Sweep Annotator"
def drag_line(event, x, _, flags, param):
"""Mouse callback function to enable dragging a vertical sweep line across the video frame."""
global line_x, dragging
if event == cv2.EVENT_LBUTTONDOWN or (flags & cv2.EVENT_FLAG_LBUTTON):
line_x = max(0, min(x, w))
dragging = True
while cap.isOpened(): # Loop over the video capture object.
ret, im0 = cap.read()
if not ret:
break
f = f + 1 # Increment frame count.
count = 0 # Re-initialize count variable on every frame for precise counts.
results = model.track(im0, persist=True)[0]
if f == 1:
cv2.namedWindow(window_name)
cv2.setMouseCallback(window_name, drag_line)
annotator = SolutionAnnotator(im0)
if results.boxes.is_track:
if results.masks is not None:
masks = [np.array(m, dtype=np.int32) for m in results.masks.xy]
boxes = results.boxes.xyxy.tolist()
track_ids = results.boxes.id.int().cpu().tolist()
clss = results.boxes.cls.cpu().tolist()
for mask, box, cls, t_id in zip(masks or [None] * len(boxes), boxes, clss, track_ids):
color = colors(t_id, True) # Assign different color to each tracked object.
label = f"{classes[cls]}:{t_id}"
if mask is not None and mask.size > 0:
if box[0] > line_x:
count += 1
cv2.polylines(im0, [mask], True, color, 2)
x, y = mask.min(axis=0)
(w_m, _), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
cv2.rectangle(im0, (x, y - 20), (x + w_m, y), color, -1)
cv2.putText(im0, label, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
else:
if box[0] > line_x:
count += 1
annotator.box_label(box=box, color=color, label=label)
# Generate draggable sweep line
annotator.sweep_annotator(line_x=line_x, line_y=h, label=f"COUNT:{count}")
cv2.imshow(window_name, im0)
video_writer.write(im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
# Release the resources
cap.release()
video_writer.release()
cv2.destroyAllWindows()Находи дополнительные подробности о методе sweep_annotator в нашем справочном разделе здесь.
Адаптивное аннотирование меток
Начиная с Ultralytics v8.3.167, circle_label и text_label были заменены на единую функцию adaptive_label. Теперь ты можешь указать тип аннотации с помощью аргумента shape:
- Прямоугольник:
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="rect") - Круг:
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="circle")
Watch: In-Depth Guide to Text & Circle Annotations with Python Live Demos | Ultralytics Annotations 🚀
import cv2
from ultralytics import YOLO
from ultralytics.solutions.solutions import SolutionAnnotator
from ultralytics.utils.plotting import colors
model = YOLO("yolo26s.pt")
names = model.names
cap = cv2.VideoCapture("path/to/video.mp4")
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
writer = cv2.VideoWriter("Ultralytics circle annotation.avi", cv2.VideoWriter_fourcc(*"MJPG"), fps, (w, h))
while True:
ret, im0 = cap.read()
if not ret:
break
annotator = SolutionAnnotator(im0)
results = model.predict(im0)[0]
boxes = results.boxes.xyxy.cpu()
clss = results.boxes.cls.cpu().tolist()
for box, cls in zip(boxes, clss):
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="circle")
writer.write(im0)
cv2.imshow("Ultralytics circle annotation", im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
writer.release()
cap.release()
cv2.destroyAllWindows()Смотри справочную страницу SolutionAnnotator для получения дополнительных сведений.
Прочее
Профилирование кода
Проверяй длительность выполнения/обработки кода, используя with или в качестве декоратора.
from ultralytics.utils.ops import Profile
with Profile(device="cuda:0") as dt:
pass # operation to measure
print(dt)
# >>> "Elapsed time is 9.5367431640625e-07 s"Поддерживаемые форматы Ultralytics
Нужно программно использовать поддерживаемые форматы изображений или видео в Ultralytics? Используй эти константы при необходимости:
from ultralytics.data.utils import IMG_FORMATS, VID_FORMATS
print(IMG_FORMATS)
# {'avif', 'bmp', 'dng', 'heic', 'heif', 'jp2', 'jpeg', 'jpeg2000', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp'}
print(VID_FORMATS)
# {'asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv', 'webm'}Делать делимым (Make Divisible)
Вычисляй ближайшее целое число к x, которое делится на y без остатка.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8Часто задаваемые вопросы (FAQ)
Какие утилиты включены в пакет Ultralytics для улучшения рабочих процессов машинного обучения?
Пакет Ultralytics включает утилиты, разработанные для упрощения и оптимизации рабочих процессов машинного обучения. Основные утилиты включают автоаннотирование для разметки наборов данных, преобразование COCO в формат YOLO с помощью convert_coco, сжатие изображений и автоматическое разделение наборов данных. Эти инструменты сокращают объем ручной работы, обеспечивают согласованность и повышают эффективность обработки данных.
Как я могу использовать Ultralytics для автоматической разметки моего набора данных?
Если у тебя есть предобученная модель обнаружения объектов Ultralytics YOLO, ты можешь использовать ее вместе с моделью SAM для автоматической аннотации твоего набора данных в формате сегментации. Вот пример:
from ultralytics.data.annotator import auto_annotate
auto_annotate(
data="path/to/new/data",
det_model="yolo26n.pt",
sam_model="mobile_sam.pt",
device="cuda",
output_dir="path/to/save_labels",
)Для получения подробной информации изучи справочный раздел auto_annotate или воспользуйся Ultralytics Platform в качестве облачной альтернативы без написания кода, предлагающей маскирование в один клик через SAM 2.1 или SAM 3, а также предсказания от предобученных и дообученных моделей YOLO для задач детекции, сегментации и OBB.
Как преобразовать аннотации набора данных COCO в формат YOLO в Ultralytics?
Для преобразования JSON-аннотаций COCO в формат YOLO для обнаружения объектов ты можешь использовать утилиту convert_coco. Вот пример фрагмента кода:
from ultralytics.data.converter import convert_coco
convert_coco(
"coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)Для получения дополнительной информации посети справочную страницу convert_coco.
Как я могу проанализировать состав и распределение моего набора данных?
Ultralytics Platform предоставляет автоматическую аналитику наборов данных: вкладка Charts показывает распределение выборок, количество основных классов, гистограммы размеров изображений и 2D-тепловые карты расположения аннотаций, помогая выявить дисбаланс и выбросы перед началом обучения.
Как я могу преобразовать ограничивающие рамки в сегменты в Ultralytics?
Для преобразования существующих данных ограничивающих рамок (в формате x y w h) в сегменты ты можешь использовать функцию yolo_bbox2segment. Убедись, что твои файлы организованы с разделением директорий для изображений и меток.
from ultralytics.data.converter import yolo_bbox2segment
yolo_bbox2segment(
im_dir="path/to/images",
save_dir=None, # saved to "labels-segment" in the images directory
sam_model="sam_b.pt",
)Для получения дополнительной информации посети справочную страницу yolo_bbox2segment.