Перейти к содержимому

Простые утилиты

код с перспективой

The ultralytics Пакет поставляется с огромным количеством утилит, которые могут поддержать, улучшить и ускорить твои рабочие процессы. Их можно найти гораздо больше, но вот некоторые, которые пригодятся большинству разработчиков. Они также являются отличным ориентиром при обучении программированию.

Данные

YOLO Проводник данных

YOLO Исследователь был добавлен в 8.1.0 юбилейного обновления и является мощным инструментом, который ты можешь использовать, чтобы лучше понять свой набор данных. Одна из ключевых функций, которую предоставляет YOLO Explorer, - это возможность использовать текстовые запросы для поиска экземпляров объектов в твоем наборе данных.

Автоматическая маркировка / аннотации

Аннотирование массивов данных - очень ресурсоемкий и трудоемкий процесс. Если у тебя есть модель обнаружения объектов YOLO , обученная на разумном количестве данных, ты можешь использовать ее и SAM для автоаннотирования дополнительных данных (формат сегментации).

from ultralytics.data.annotator import auto_annotate

auto_annotate(#(1)!
    data='path/to/new/data',
    det_model='yolov8n.pt',
    sam_model='mobile_sam.pt',
    device="cuda",
    output_dir="path/to/save_labels",
)
  1. Из этой функции ничего не возвращается

  2. Смотри справочный раздел для annotator.auto_annotate чтобы узнать больше о том, как работает эта функция.

  3. Используй в сочетании с функция segments2boxes чтобы сгенерировать ограничительные рамки для обнаружения объектов, а также

Конвертируй COCO в формат YOLO

Используется для преобразования аннотаций COCO JSON в правильный формат YOLO . Для наборов данных по обнаружению объектов (bounding box), use_segments и use_keypoints оба должны быть False

from ultralytics.data.converter import convert_coco

convert_coco(#(1)!
    '../datasets/coco/annotations/',
    use_segments=False, 
    use_keypoints=False,
    cls91to80=True,
)
  1. Из этой функции ничего не возвращается

Для получения дополнительной информации о convert_coco Функция, посетите справочную страницу

Получите размеры ограничительной рамки

from ultralytics.utils.plotting import Annotator
from ultralytics import YOLO
import cv2

model = YOLO('yolov8n.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("Bounding Box Width {}, Height {}, Area {}".format(
        width.item(), height.item(), area.item()))

Преобразуй ограничительные рамки в сегменты

С существующими x y w h Данные ограничительной рамки преобразуй в сегменты с помощью yolo_bbox2segment Функция. Файлы для изображений и аннотаций нужно организовать следующим образом:

data
|__ images
    ├─ 001.jpg
    ├─ 002.jpg
    ├─ ..
    └─ NNN.jpg
|__ labels
    ├─ 001.txt
    ├─ 002.txt
    ├─ ..
    └─ NNN.txt
from ultralytics.data.converter import yolo_bbox2segment

yolo_bbox2segment(#(1)!
    im_dir="path/to/images",
    save_dir=None, # saved to "labels-segment" in images directory
    sam_model="sam_b.pt"
)
  1. Из этой функции ничего не возвращается

Посетите yolo_bbox2segment справочная страница для получения дополнительной информации об этой функции.

Преобразование сегментов в ограничительные рамки

Если у тебя есть набор данных, в котором используется Формат набора данных сегментации ты можешь легко преобразовать их в ограничительные рамки, расположенные вверх-вправо (или по горизонтали) (x y w h формат) с помощью этой функции.

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)#(1)!
  1. Из этой функции ничего не возвращается

Автоматическое разделение набора данных

Автоматически разделите набор данных на train/val/test расщепляй и сохраняй полученные расщепления в autosplit_*.txt файлы. Эта функция будет использовать случайную выборку, которая не включается при использовании fraction Аргумент в пользу тренировок.

from ultralytics.data.utils import autosplit

autosplit( #(1)!
    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
)
  1. Из этой функции ничего не возвращается

Дополнительные сведения об этой функции см. на странице "Справочник ".

Сегмент-полигон в двоичную маску

Преобразуй один полигон (в виде списка) в двоичную маску указанного размера изображения. Полигон в виде списка [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
) 

Ограничительные рамки

Экземпляры Bounding Box (горизонтальные)

Чтобы управлять данными ограничительных рамок, нужно Bboxes Класс поможет преобразовать формат координат бокса, масштабировать размеры бокса, вычислять площади, включать смещения и многое другое!

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")
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,
)

new_boxes#(1)!
>>> 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]]
)
  1. Граничные рамки, масштабированные под новый размер изображения

Преобразования формата ограничительной рамки

XYXY → XYWH

Преобразуй координаты ограничительной рамки из формата (x1, y1, x2, y2) в формат (x, y, width, height), где (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)

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 xywh2xyxy
from ultralytics.utils.ops import xywhn2xyxy # normalized → pixel
from ultralytics.utils.ops import xyxy2xywhn # pixel → normalized
from ultralytics.utils.ops import xywh2ltwh  # xywh → top-left corner, w, h
from ultralytics.utils.ops import xyxy2ltwh  # xyxy → top-left corner, w, h
from ultralytics.utils.ops import ltwh2xywh
from ultralytics.utils.ops import ltwh2xyxy

Смотри docstring для каждой функции или посети ultralytics.utils.ops справочная страница чтобы прочитать больше о каждой функции.

Черчение

Рисование аннотаций

Ultralytics включает класс Annotator, который можно использовать для аннотирования любых данных. Проще всего использовать его с ограничительными рамками для обнаружения объектов, ключевыми точками позы и ориентированными ограничительными рамками.

Горизонтальные ограничительные рамки

import cv2 as cv
import numpy as np
from ultralytics.utils.plotting import Annotator, colors

names { #(1)!
     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()
  1. Имена можно использовать из model.names когда Работа с результатами обнаружения

Ориентированные граничные коробки (OBB)

import cv2 as cv
import numpy as np
from ultralytics.utils.plotting import Annotator, colors

obb_names = {10: "small vehicle"}
obb_image = cv.imread("datasets/dota8/images/train/P1142__1024__0___824.jpg")
obb_boxes = np.array(
    [[ 0, 635, 560, 919, 719, 1087, 420, 803,  261,], # class-idx x1 y1 x2 y2 x3 y2 x4 y4
     [ 0, 331,  19, 493, 260, 776,   70, 613, -171,],
     [ 9, 869, 161, 886, 147, 851,  101, 833,  115,]
    ]
)
ann = Annotator(
    obb_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
)
for obb in obb_boxes:
    c_idx, *obb = obb
    obb = np.array(obb).reshape(-1, 4, 2).squeeze()
    label = f"{names.get(int(c_idx))}"
    ann.box_label(
        obb,
        label,
        color=colors(c_idx, True),
        rotated=True,
    )

image_with_obb = ann.result()

См. Annotator Справочная страница за дополнительными знаниями.

Разное

Профилирование кода

Проверь продолжительность выполнения/обработки кода, используя with Или в качестве декоратора.

from ultralytics.utils.ops import Profile

with Profile(device=device) as dt:
    pass  # operation to measure

print(dt)
>>> "Elapsed time is 9.5367431640625e-07 s"

Ultralytics Поддерживаемые форматы

Хочешь или должен программно использовать форматы типов изображений или видео, поддерживаемые Ultralytics ? Если нужно, используй эти константы.

from ultralytics.data.utils import IMG_FORMATS
from ultralytics.data.utils import VID_FORMATS

print(IMG_FORMATS)
>>> ('bmp', 'dng', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp', 'pfm')

Сделай делимым

Вычисляет ближайшее целое число к x сделать равномерно делимым при делении на y.

from ultralytics.utils.ops import make_divisible

make_divisible(7, 3)
>>> 9
make_divisible(7, 2)
>>> 8


Создано 2024-02-20, Обновлено 2024-04-18
Авторы: glenn-jocher (2), RizwanMunawar (1), Burhan-Q (2)

Комментарии