Орієнтоване виявлення
Орієнтоване виявлення об'єктів локалізує кожен екземпляр повернутим прямокутником замість вирівняного за осями, тому похилий об'єкт щільно охоплюється рамкою без зайвого тла. Ключ задачі має назву obb.
Визначення
Орієнтоване виявлення додає до виявлення одне число, кут. Кожен екземпляр отримує повернутий прямокутник, клас та оцінку. Перевагою є щільність. Корабель під кутом 45 градусів, дах складу або ряд припаркованих вантажівок: вирівняна за осями рамка навколо будь-якого з них містить переважно тло, а дві сусідні рамки перекриваються навіть тоді, коли об'єкти не перекриваються. Тому задача стандартна для аерофотознімків і компонування документів, а її еталонним датасетом є DOTA.
obb є канонічним ключем задачі, а суфікс -obb у назві файла контрольної
точки вибирає її, тому під час завантаження опублікованих ваг task= не
потрібний.
predict() заповнює result.obb. .xywhr є канонічною формою (N, 5):
центр x, центр y, ширина, висота й кут у радіанах, який задає обертання сторони
ширини навколо центра. .conf і .cls містять оцінку та індекс класу в
result.names, а .id ідентифікатор відстеження під час відстеження.
.xyxyxyxy перетворює кожен рядок на чотири кутові точки як пікселі у формі
(N, 4, 2), .xyxyxyxyn нормалізує ці кути, а .xyxy повертає охоплювальну
рамку, вирівняну за осями, яку слід використовувати, коли подальший код розуміє
лише прямокутники. Поле result.boxes також заповнюється вирівняною за осями
формою.
Моделі
Цю задачу виконують два сімейства, а вибір між ними залежить від потреби в навчанні.
RF-DETR підтримує навчання. Він передбачає, навчає,
валідує та експортує орієнтовані рамки й постачає опубліковані орієнтовані
контрольні точки чотирьох розмірів: n, s, m і l. Для нього потрібний власний
набір залежностей pip install "libreyolo[rfdetr]", а ліцензію ваг та їхнє
походження наведено на сторінці моделі.
Перш ніж планувати роботу з ними, прочитайте наведений нижче розділ про те, що саме передбачають ці контрольні точки.
RT-DETRv2 постачає ваги для аерофотознімків. Сімейство
публікує від LibreRTDETRv2n-obb.pt до LibreRTDETRv2x-obb.pt, офіційні
одномасштабні контрольні точки DOTA v1.0, перетворені у формат LibreYOLO, що
охоплюють 15 класів DOTA за 1024 пікселів. Йому не потрібні додаткові
залежності крім базового пакета, орієнтований граф розпізнається з власних
тензорів контрольної точки, а передбачення, валідація та експорт ONNX і
TorchScript повністю підтримуються. Навчання не підтримується: орієнтована
задача призначена лише для інференсу в цьому сімействі, train() спричиняє
помилку, а перенесення з ваг виявлення неможливе через інший бекбон. Відстеження
та аугментація під час тестування також недоступні для орієнтованих рамок.
Отже, для готових категорій DOTA вибирайте RT-DETRv2. Для власних орієнтованих міток вибирайте RF-DETR.
Передбачення
Ваги завантажуються з Hugging Face під час першого використання та кешуються локально.
# Потрібний набір rfdetr: pip install "libreyolo[rfdetr]"from libreyolo import LibreYOLO, SAMPLE_IMAGE # Суфікс -obb у назві файла вибирає задачу, тому аргумент# task не потрібний.model = LibreYOLO("LibreRFDETRs-obb.pt")result = model(SAMPLE_IMAGE, save=True) obb = result.obbprint(obb.xywhr) # (N, 5): центр x, центр y, ширина, висота, радіаниprint(obb.conf, obb.cls)libreyolo predict model=LibreRFDETRs-obb.pt save=True \ source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpgfrom libreyolo import LibreYOLO, SAMPLE_IMAGE result = LibreYOLO("LibreRFDETRs-obb.pt")(SAMPLE_IMAGE)obb = result.obb print(obb.xyxyxyxy.shape) # (N, 4, 2) кутові точки в пікселяхprint(obb.xyxyxyxyn.shape) # те саме, нормалізованоprint(obb.xyxy.shape) # (N, 4) охоплювальна рамка, вирівняна за осямиfrom libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreRFDETRn-obb.pt")result = model(SAMPLE_IMAGE) print(result.obb.xywhr.shape)from libreyolo import LibreYOLO # Ваги DOTA v1.0, 15 аерофотознімальних класів за 1024 пікселів. Орієнтований# граф розпізнається з власних тензорів контрольної точки, тому аргумент task не потрібний.model = LibreYOLO("LibreRTDETRv2n-obb.pt")result = model("aerial.png", save=True) obb = result.obbprint(obb.xywhr)print(result.names) # літак, корабель, гавань, гелікоптер і ще 11Перед запуском з'ясуйте призначення опублікованих контрольних точок RF-DETR. Хоча DOTA є еталонним бенчмарком для цієї задачі, ці ваги навчено не на ньому. Усі чотири ініціалізовано з ваг виявлення RF-DETR і донавчено на одному датасеті відео з БПЛА у Roboflow Universe із шістьма класами транспортних засобів: bike, bus, car, other_vehicle, taxi і truck. Картки моделей описують їх як ваги для розробки, створені під час перевірки підтримки орієнтованого навчання, і застерігають, що їх не слід вважати виробничими або офіційними бенчмарковими вагами.
На практиці вони є робочою початковою точкою для орієнтованих рамок
транспортних засобів, побачених згори, та перевірки повного пайплайна. Будь-яка
інша предметна область потребує навчання на власних орієнтованих мітках, а для
аерофотознімальних категорій, якими відомий DOTA, слід використовувати
контрольні точки RT-DETRv2, фактично навчені на цих даних. conf і max_det
формують вихідні дані так само, як для виявлення. Джерела, потокове оброблення
й роботу з результатами описано в розділі передбачення.
Формат датасету
Структура збігається зі структурою виявлення: один файл міток .txt для
кожного зображення, знайдений шляхом заміни images на labels у шляху
зображення та зміни розширення.
dataset/
data.yaml
images/
train/P0001.png
val/P0101.png
labels/
train/P0001.txt
val/P0101.txtРядок містить рівно дев'ять полів, індекс класу, за яким ідуть чотири кутові точки по порядку:
<class_id> <x1> <y1> <x2> <y2> <x3> <y3> <x4> <y4>Чотири точки є нормалізованими числами з рухомою комою в діапазоні [0, 1] і
мають утворювати невироджений орієнтований прямокутник. У файлі міток кут не
зберігається: завантажувач отримує канонічний xywhr із кутових точок. Типово
парсер строгий і відхиляє координати поза діапазоном, тоді як завантаження
датасету й валідації може спочатку обрізати їх до [0, 1] для коректних в
іншому міток на межі кадрування, а потім усе одно відхилити вироджені рамки.
Розбір рядка враховує задачу. Дев'ять полів означають орієнтовану рамку лише в
режимі obb; у режимі segment той самий рядок читається як полігон із
чотирьох точок.
YAML збігається з YAML виявлення:
path: dataset
train: images/train
val: images/val
names:
0: plane
1: shipНативний JSON COCO також завантажується з відповідністю annotations між
назвою розбиття та файлом JSON. Анотації читаються в порядку пріоритету: поле
obb із вісьмома кутами в піксельному просторі, поле obb у форматі
[cx, cy, w, h, angle] з кутом у радіанах, полігон segmentation або RLE,
переприпасовані до прямокутника мінімальної площі, або звичайний COCO bbox,
який розглядається як вирівняний за осями прямокутник і канонізується до
xywhr.
Канонічним парсером рядка є libreyolo.data.parse_yolo_obb_label_line.
Навчання
from libreyolo import LibreYOLO # Продовжує з опублікованих орієнтованих ваг. data має вказувати на# датасет, рядки міток якого містять чотири кути.model = LibreYOLO("LibreRFDETRs-obb.pt")model.train(data="my-obb-dataset.yaml", epochs=50, imgsz=512, batch=8, lr0=1e-4)libreyolo train model=LibreRFDETRs-obb.pt data=my-obb-dataset.yaml \ epochs=50 imgsz=512 batch=8 lr0=1e-4# Ваги виявлення не передбачають кут, тому це явне перенесення.# Запит task=obb надає дозвіл на це.libreyolo train model=LibreRFDETRs.pt data=my-obb-dataset.yaml \ task=obb epochs=50 imgsz=512Навчання для цієї задачі означає RF-DETR. Типово воно продовжується з
опублікованої контрольної точки -obb. Початок із ваг виявлення є навмисним
перенесенням: ці ваги не передбачають кут, а передавання task=obb надає дозвіл
на заміну. Зберігайте lr0 на рівні 1e-4 або нижче, як і для інших задач
цього сімейства. Орієнтовані контрольні точки RT-DETRv2 не можна донавчати;
використовуйте їх без змін або навчіть модель RF-DETR на власних мітках.
Датасети, аугментацію, кілька GPU й засоби журналювання описано в розділі
навчання.
Валідація
val() повертає звичайний словник ключів metrics/. Зіставлення використовує
повернутий IoU, обчислений між орієнтованими прямокутниками, а не їхніми
охоплювальними рамками, вирівняними за осями, тому передбачення з правильним
положенням і неправильним кутом оцінюється як промах.
from libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs-obb.pt") # val() повертає звичайний словник, а не об'єкт.metrics = model.val(data="my-obb-dataset.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"], metrics["metrics/mAP75"])print(metrics["metrics/precision"], metrics["metrics/recall"])libreyolo val model=LibreRFDETRs-obb.pt data=my-obb-dataset.yamllibreyolo val model=LibreRTDETRv2n-obb.pt data=my-obb-dataset.yamlmetrics/mAP50-95 є середньою average precision за порогами IoU від 0.50 до
0.95 із кроком 0.05 і головним показником. На відміну від шляху COCO для
виявлення, ця задача враховує iou_thresholds у конфігурації валідації, тому
перебір можна змінити. metrics/mAP50 і metrics/mAP75 є версіями для одного
порога. metrics/precision і metrics/recall є справжніми точністю й повнотою
за IoU 0.50, прочитаними в найм'якшій робочій точці: враховується кожне
передбачення, яке пройшло поріг упевненості, а під час валідації цей поріг
типово дорівнює 0.001. Тому збільшення conf змінює їх, тоді як показники mAP,
що використовують усю криву точність-повнота, залишаються незмінними. Чотири
показники повторюються із суфіксом (OBB): metrics/mAP50-95(OBB),
metrics/mAP50(OBB), metrics/precision(OBB) і metrics/recall(OBB). За ним
код виклику відрізняє орієнтований результат від вирівняного за осями, коли
обидва містяться в одній таблиці. metrics/mAP75 не має відповідника із
суфіксом.
Два параметри не впливають на цю задачу. save_json і save_plots приймаються
та записують попередження до журналу: дампи орієнтованих передбачень і графіки
валідації не реалізовано.
Експорт
from libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs-obb.pt")model.export(format="onnx", imgsz=512)libreyolo export model=LibreRFDETRs-obb.pt format=onnx imgsz=512# ONNX і TorchScript є валідованими цілями за FP32, розміру батча 1# і фіксованого полотна 1024 на 1024.libreyolo export model=LibreRTDETRv2n-obb.pt format=onnx imgsz=1024libreyolo export model=LibreRTDETRv2n-obb.pt format=torchscript imgsz=1024from libreyolo import LibreYOLO, SAMPLE_IMAGE # Фабрика маршрутизує за суфіксом файла, тому експортований артефакт# завантажується як контрольна точка й повертає той самий Results.model = LibreYOLO("LibreRFDETRs-obb.onnx")result = model(SAMPLE_IMAGE) print(result.obb.xywhr)Експортований артефакт завантажується назад через LibreYOLO() за суфіксом
файла, тому файл .onnx або .engine поводиться як контрольна точка й повертає
той самий об'єкт Results. Покриття форматів відрізняється за задачами того
самого сімейства, а матриця на сторінці моделі створюється з валідованого
набору й указує причину недоступності цілі. Формати, їхні додаткові набори
залежностей та обмеження описано в розділі
експорту й розгортання.