Переглянути як Markdown

Робота з результатами

Кожне передбачення повертає об'єкт Results для кожного зображення. Він має одне іменоване поле для кожного виду корисних даних, усі порожні, крім створених моделлю, і ті самі поля доступні для експортованого артефакту.

Один об'єкт і одне поле для кожного виду корисних даних

Передбачення для одного зображення повертає один Results. Він містить вісімнадцять полів корисних даних, а модель заповнює лише ті, які створює її завдання. Усі інші поля мають значення None, тому читання result.masks для детектора повертає None, а не помилку.

ПолеКласФормаСтворюється для
boxesBoxes(N, 4) плюс оцінки та класиВиявлення об'єктів і будь-яке завдання, що спочатку виконує локалізацію
masksMasks(N, H, W)Сегментація екземплярів
keypointsKeypoints(N, K, 2) або (N, K, 3)Поза
probsProbs(C,)Класифікація
obbOBB(N, 7) або (N, 8)Орієнтовані рамки
gazeGaze(N, 2) нахил і поворот у радіанахОцінювання напрямку погляду
pointsPoints(N, 4) як x, y, клас, упевненістьЛокалізація точок
semantic_maskSemanticMask(H, W) ідентифікатори класівСемантична сегментація
panopticPanopticSegmentation(H, W) ідентифікатори сегментів плюс segments_infoПаноптична сегментація
depth_mapDepthMap(H, W) числа з рухомою комоюОцінювання глибини
normal_mapNormalMap(H, W, 3) одиничні векториНормалі поверхні
edgesEdgeMap(H, W) числа з рухомою комою в [0, 1]Виявлення країв
restoredRestoredImage(H, W, 3) uint8 RGBВідновлення та підвищення роздільної здатності
matteMatte(H, W) числа з рухомою комою в [0, 1]Alpha matting і видалення тла
ocrOCRRegions(N, 4, 2) полігони плюс транскрипціїВиявлення та розпізнавання тексту
embeddingsEmbeddings(N, D) L2-нормалізовані рядкиЗавдання embed
identitiesIdentitiesN імен та оцінокЗавдання embed з галереєю
meshesMeshesПараметри тіла й необов'язкові вершиниВідновлення сітки тіла

Поруч із ними розташовані поля, наявні в кожному результаті: orig_shape у вигляді (height, width), path (шлях до джерела або None для вхідних даних із пам'яті), names із відповідністю ідентифікатора класу його назві, frame_idx для відео та кадрів наживо, track_id під час відстеження й restore_scale, цілий коефіцієнт масштабування результату відновлення.

result.normals є псевдонімом result.normal_map.

result.speed існує в кожному результаті, але заповнюється лише ансамблями, де має ключі member_0, member_1 і fusion зі значеннями в мілісекундах. Для окремої моделі він залишається порожнім словником.

Рамки

Рамки
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreYOLO9s.pt")result = model(SAMPLE_IMAGE) print(result.orig_shape)   # (висота, ширина) початкового зображенняprint(result.path)         # шлях до джерела, None для вхідних даних із пам'яті for xyxy, conf, cls in zip(    result.boxes.xyxy.tolist(),    result.boxes.conf.tolist(),    result.boxes.cls.tolist(),):    print(result.names[int(cls)], round(float(conf), 3), xyxy)
Нормалізовані координати
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreYOLO9s.pt")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy[:1])    # пікселі, x1 y1 x2 y2print(result.boxes.xywh[:1])    # пікселі, центр x, центр y, w, hprint(result.boxes.xyxyn[:1])   # та сама рамка, поділена на ширину й висотуprint(result.boxes.xywhn[:1])
NumPy та пристрої
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreYOLO9s.pt")result = model(SAMPLE_IMAGE) # Кожен із цих викликів повертає новий Results; початковий об'єкт не змінюється.as_numpy = result.numpy()on_cpu = result.cpu() print(type(as_numpy.boxes.xyxy).__name__)print(type(on_cpu.boxes.xyxy).__name__)

Boxes зберігає координати й оцінки в окремих масивах, а не в одному упакованому тензорі.

АтрибутВміст
xyxy(N, 4) абсолютні пікселі, x1 y1 x2 y2
xywh(N, 4) абсолютні пікселі, центр x, центр y, ширина, висота
xyxyn, xywhnТі самі значення, поділені на ширину й висоту зображення
conf(N,) упевненість
cls(N,) ідентифікатор класу як число з рухомою комою
id(N,) ідентифікатор відстеження або None
is_trackЧи встановлено id
dataУсе об'єднане: рамки, необов'язковий ідентифікатор, упевненість, клас

cls є масивом чисел із рухомою комою, тому використовуйте його як result.names[int(cls)].

Для xyxyn і xywhn потрібен orig_shape, який заповнює Results.

Щільні корисні дані

Корисні дані, що охоплюють усе зображення, поводяться інакше, ніж дані окремих екземплярів, і це важливо під час зрізів.

SemanticMask містить ідентифікатори класів (H, W) на початковому полотні, де 255 зарезервовано як значення ігнорування, яке ніколи не вважається класом. classes перелічує наявні ідентифікатори без нього; class_mask(id) повертає булевий масив (H, W).

PanopticSegmentation містить ідентифікатори сегментів (H, W), де 0 є ідентифікатором порожньої області, а список словників segments_info містить щонайменше id і category_id. segment_ids перелічує наявні ідентифікатори, а segment_mask(id) вибирає один із них.

DepthMap містить відносну обернену глибину (H, W): вище значення означає ближчу точку, а значення не є метричними метрами. Атрибути min, max, mean обчислюються за скінченними значеннями, а normalized() масштабує їх до [0, 1].

NormalMap містить одиничні вектори (H, W, 3) у системі координат камери OpenCV, де +x спрямовано праворуч, +y вниз, а +z углиб сцени, тому поверхня, спрямована до камери, має вектор (0, 0, -1). assert_normalized() перевіряє, що кожен піксель скінченний і має одиничну довжину.

EdgeMap містить float32 (H, W) у діапазоні [0, 1]. Замість порогової карти зберігається неперервна, тому поріг вибирається у binary(threshold=0.5).

Matte містить float32 (H, W) у діапазоні [0, 1], де 1 означає повністю передній план. array повертає обмежені значення як float32.

RestoredImage містить RGB uint8 (H, W, 3), надає array для необробленого ndarray і save(path) для запису.

Probs містить один вектор імовірностей для зображення. top1 і top5 є індексами класів, а top1conf і top5conf містять відповідні оцінки.

Embeddings містить рядки (N, D), уже нормалізовані за L2, тому косинусна подібність є скалярним добутком. similarity(other) повертає (N, M) для порівняння з галереєю або (N,) для одного вектора, а verify(i, j, threshold=0.4) порівнює два рядки.

OCRRegions містить полігони (N, 4, 2) у порядку читання з кутами в порядку верхній лівий, верхній правий, нижній правий, нижній лівий. Транскрипції містяться в texts, оцінки розпізнавання в conf, а оцінки виявлення в det_conf. Оскільки це справжні повернуті полігони, вони не заповнюють boxes; ocr.xyxy надає вирівняні за осями оболонки, коли потрібні прямокутники.

Зрізи та переміщення

result[i] повертає новий Results, що містить один екземпляр. Корисні дані окремих екземплярів зрізаються, а дані цілого зображення переносяться без змін. Тому зріз результату класифікації не може обрізати його вектор імовірностей до одного класу, а зріз результату глибини не може пошкодити структуру (H, W).

len(result) підраховує екземпляри: рамки, точки, ембедінги, області OCR або сітки. Будь-які щільні корисні дані цілого зображення рахуються як 1. Порожній результат має довжину 0.

to(), cpu(), cuda() і numpy() повертають новий Results із перетворенням кожного заповненого поля. Вони не змінюють початковий об'єкт.

update() є єдиним методом, що змінює об'єкт на місці, замінюючи іменовані поля й повертаючи той самий об'єкт.

JSON

summary і to_json
import json from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreYOLO9s.pt")result = model(SAMPLE_IMAGE) rows = result.summary()print(json.dumps(rows[:2], indent=2)) # Ті самі дані у вигляді рядка з тими самими іменованими аргументами.print(result.to_json(normalize=True, decimals=3)[:200])
CLI
libreyolo predict model=LibreYOLO9s.pt --json \  source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg

summary() повертає список звичайних словників, а to_json() передає цей список до json.dumps. Обидва приймають ті самі три аргументи: normalize=False перемикає координати на [0, 1], decimals=5 задає округлення, а embeddings=False визначає, чи включати вектори ембедінгів.

Форма рядка відповідає корисним даним. Рядки виявлення містять name, class, confidence і словник box, а також отримують segments за наявності масок, obb і corners для орієнтованих рамок, кути gaze в радіанах і градусах, track_id під час відстеження та параметри mesh за наявності сіток.

Якщо рамок немає, рядки визначаються одним типом корисних даних: OCR створює один рядок на область із полем text, точки створюють один рядок на точку, паноптична сегментація один рядок на сегмент із pixel_count і pixel_fraction, семантична сегментація один рядок на наявний клас, а класифікація п'ять класів із найвищими оцінками. Глибина, нормалі, краї, відновлення та matting створюють по одному підсумковому рядку з описом карти, а не її пікселів.

Два типи корисних даних навмисно скорочено. Для вектора ембедінгу повідомляється лише embedding_dim, оскільки рядок із 512 числами з рухомою комою займає приблизно 2 КБ на обличчя; передайте embeddings=True, щоб включити значення. Вершини сітки не включаються взагалі, оскільки це десятки тисяч координат на людину. Для геометрії читайте result.meshes.vertices або викликайте result.meshes.save_obj(path).

Малювання та збереження

Анотовані зображення
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreYOLO9s.pt") # save=True відображає корисні дані й записує їх у runs/detect/predict*.result = model(SAMPLE_IMAGE, save=True)print(result.saved_path)

predict(save=True) виконує анотування та запис. Він вибирає процедуру малювання за заповненим полем, тому семантичний результат записується як кольорова маска, результат глибини як візуалізація глибини, паноптичний результат зі своїми сегментами, matte як PNG RGBA з прозорим тлом, а результат детектора як рамки з масками під ними. Записаний шлях додається до результату як result.saved_path.

Назва Results.plot() передбачає ширшу функціональність, ніж реалізовано. Метод визначено лише для карт нормалей і карт країв, а для решти він спричиняє NotImplementedError. Для інших завдань використовуйте save=True.

Results.save(path) так само має вузьку дію: записує результат matte як вирізаний PNG RGBA з прозорим тлом і спричиняє NotImplementedError в інших випадках. Results.cutout() повертає той самий масив RGBA без запису. Обом потрібне початкове зображення з result.path або передане через image=.

Два типи корисних даних мають власні засоби запису: result.restored.save(path) для відновленого зображення та result.meshes.save_obj(path, index=0) для сітки.

Про розташування файлів і поведінку output_path та output_file_format читайте в розділі Джерела передбачення.

Експортовані артефакти повертають той самий об'єкт

Установлення додаткового пакета для експорту
pip install "libreyolo[onnx]"
Той самий Results з експортованого артефакту
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreYOLO9s.pt")path = model.export(format="onnx")   # повертає записаний шлях # LibreYOLO() диспетчеризує за суфіксом файла.exported = LibreYOLO(path)result = exported(SAMPLE_IMAGE) print(type(result).__name__, len(result.boxes))

LibreYOLO() диспетчеризує за суфіксом файла, тому експортований артефакт завантажується тим самим викликом, що й контрольна точка .pt, і повертає той самий Results. Файли .onnx, .engine, .pte і .mnn розпізнаються за суфіксом, як і каталоги OpenVINO, Paddle та ncnn і URL моделі Triton. Код, що читає result.boxes.xyxy, не змінюється після заміни моделі її експортованою збіркою. Повний перелік форматів наведено в розділі Експорт.

Якщо натомість використовувати власний API середовища виконання, попереднє оброблення, постоброблення та назви класів доведеться реалізувати самостійно.

Класи корисних даних, поля, семантику переміщення, summary(), to_json(), plot(), save() і cutout() перевірено за libreyolo/utils/results.py. Поведінку анотування та запису на диск взято з InferenceRunner._save_annotated_image у libreyolo/models/base/inference.py і resolve_save_path у libreyolo/utils/general.py. Диспетчеризацію за суфіксом взято з LibreYOLO() у libreyolo/models/__init__.py.