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

Джерела передбачення

Аргумент source класифікується до відкриття будь-яких даних, тому один виклик обробляє JPEG, папку, MP4, індекс вебкамери, URL RTSP, область екрана або список камер.

Класифікація джерела

classify_source перевіряє значення до відкриття чи завантаження будь-яких даних у наведеному порядку. Застосовується перше правило, що збігається.

ДжерелоІнтерпретація
"screen", "screen 1", "screen 1 100 200 512 256"Захоплення екрана
Невід'ємне int або рядок із цифр, якщо файла з такою назвою немаєВебкамера
URL rtsp://, rtmp://, tcp:// або udp://Мережевий потік
URL http(s)://, шлях якого закінчується на .m3u8Мережевий потік
URL сторінки YouTubeМережевий потік
Список або кортеж, усі елементи якого є джерелами наживо чи відеоКілька потоків наживо
Будь-який інший список або кортежБатч зображень
Шлях, що закінчується на .streamsКілька потоків наживо
Шлях із розширенням відеоВідеофайл
Наявний каталогПапка зображень
Усе іншеОдне зображення

Список, у якому джерела наживо змішано із зображеннями, спричиняє TypeError. Від'ємний індекс вебкамери спричиняє ValueError.

Класифікатор ніколи не звертається до мережі, тому помилка в URL проявляється під час відкриття захоплення, а не під час виклику predict.

Зображення

Одне зображення
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreYOLO9s.pt") # Джерело з одним зображенням повертає один Results, а не список.result = model(SAMPLE_IMAGE)print(len(result.boxes), "detections")
Зображення в пам'яті
import numpy as npfrom PIL import Image from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreYOLO9s.pt") pil_image = Image.open(SAMPLE_IMAGE)array = np.asarray(pil_image)raw_bytes = open(SAMPLE_IMAGE, "rb").read() for source in (pil_image, array, raw_bytes):    result = model(source)    print(type(source).__name__, len(result.boxes))
Папка
from pathlib import Pathfrom PIL import Image from libreyolo import LibreYOLO, SAMPLE_IMAGE folder = Path("sample_folder")folder.mkdir(exist_ok=True)image = Image.open(SAMPLE_IMAGE)for index in range(3):    image.save(folder / f"frame_{index}.jpg") model = LibreYOLO("LibreYOLO9s.pt") # Папка повертає список з одним Results на зображення, відсортований за шляхом.results = model(str(folder))print(len(results), "images")
CLI
libreyolo predict model=LibreYOLO9s.pt \  source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg

Джерело з одним зображенням приймає сім типів.

ТипІнтерпретація
str або pathlib.PathЛокальний файл, http(s)://, s3:// або gs://
PIL.Image.ImageПеретворюється на RGB
numpy.ndarray2D у відтінках сірого або 3D HWC чи CHW; для 4D масиву використовується перше зображення
torch.TensorCHW або NCHW, зчитується як RGB; для пакетного тензора використовується перше зображення
bytesЗакодовані дані зображення
io.BytesIOЗакодовані дані зображення

До попереднього оброблення все перетворюється на RGB. Порядок каналів неоднозначний лише для масивів NumPy, тому ним керує color_format: "auto" (типове значення) залишає масив без змін, а "bgr" змінює порядок каналів на зворотний, що потрібно для кадру, зчитаного через OpenCV.

Масиви з рухомою комою масштабуються за власним діапазоном: значення не вище 1.0 множаться на 255, а вищі значення обмежуються діапазоном [0, 255]. У масиві RGBA альфа-канал відкидається.

Для віддалених шляхів потрібен окремий пакет, жоден із яких типово не встановлено: requests для http(s)://, boto3 для s3:// і gcsfs для gs://.

Папки

Каталог сканується рекурсивно й сортується, а кожен файл з одним із наведених суфіксів стає зображенням: .jpg, .jpeg, .png, .gif, .webp, .bmp, .tiff, .tif. Усе інше в папці пропускається. Порожня папка повертає порожній список, а не спричиняє помилку.

Папки та списки є двома джерелами, які приймають batch. Для сімейств із підтримкою ця функція виконує один прямий прохід складеного тензора на групу. Дивіться Продуктивність інференсу.

Відеофайли

Відеофайл (надайте власний кліп)
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") # Замініть clip.mp4 на відеофайл із диска.for result in model("clip.mp4", stream=True):    print(result.frame_idx, len(result.boxes))
Кожен третій кадр із записом на диск
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") for result in model("clip.mp4", stream=True, vid_stride=3, save=True):    pass

Шлях вважається відео, якщо його суфікс є одним із таких: .asf, .avi, .gif, .m4v, .mkv, .mov, .mp4, .mpeg, .mpg, .ts, .wmv, .webm.

.gif є в обох списках. Шлях .gif, переданий безпосередньо до predict, відкривається як відео, оскільки перевірка відео виконується першою; файл .gif усередині сканованої папки завантажується як нерухоме зображення.

vid_stride обробляє кожен N-й кадр і типово дорівнює 1. Без stream=True усе відео декодується в список, а понад 500 кадрів після застосування кроку спричиняють попередження з рекомендацією stream=True.

Кожен Results із відео містить frame_idx.

Вебкамери, мережеві потоки та YouTube

Вебкамера (потрібна під'єднана камера)
import itertools from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") # Індекс вебкамери 0. Джерела наживо нескінченні, тому обмежте цикл.for result in itertools.islice(model(0, stream=True), 100):    print(result.frame_idx, len(result.boxes))
RTSP (потрібен доступний URL камери)
import itertools from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")source = "rtsp://user:password@192.168.1.64:554/Streaming/Channels/101" for result in itertools.islice(model(source, stream=True), 100):    print(result.frame_idx, len(result.boxes))

Джерела наживо необмежені, тому потребують stream=True. Без нього predict спричиняє ValueError, а не намагається зібрати нескінченний список.

Кадри зчитуються у фоновому потоці, по одному на кожне захоплення. Типово черга зберігає лише найновіший кадр, тому модель, повільніша за камеру, пропускає кадри, а не відстає. stream_buffer=True зберігає кожен захоплений кадр, що не втрачає їх ціною дедалі більшої затримки.

Індекс вебкамери задається як int або рядок із цифр. У Windows захоплення спочатку відкривається через бекенд DirectShow, а в разі невдачі переходить до типового бекенда.

URL сторінки YouTube перетворюється на прямий URL медіаданих без завантаження відео, для чого потрібен yt-dlp:

bash
pip install "libreyolo[stream]"

Мітки потоків редагуються перед записом у журнал або використанням як назв файлів. URL з обліковими даними відображається як user:***@host, а рядки запиту вилучаються з міток прямих потоків, оскільки там розташовуються підписані URL і токени пред'явника. Ідентифікатор відео YouTube зберігається, бо він не є обліковими даними.

Кілька камер одночасно

Файл .streams (надайте власні камери)
import itertoolsfrom pathlib import Path from libreyolo import LibreYOLO Path("cameras.streams").write_text(    "# one source per line, blank lines and comments are skipped\n"    "rtsp://192.168.1.64:554/Streaming/Channels/101\n"    "rtsp://192.168.1.65:554/Streaming/Channels/101\n",    encoding="utf-8",) model = LibreYOLO("LibreYOLO9s.pt")for result in itertools.islice(model("cameras.streams", stream=True), 100):    print(result.frame_idx, len(result.boxes))
Список камер
import itertools from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")cameras = [0, "rtsp://192.168.1.64:554/Streaming/Channels/101"] for result in itertools.islice(model(cameras, stream=True), 100):    print(result.frame_idx, len(result.boxes))

Файл .streams містить одне джерело на рядок. Порожні рядки й рядки, що починаються з #, ігноруються. Кожен інший рядок має містити індекс вебкамери, мережевий потік, URL YouTube або шлях до відеофайла; усе інше спричиняє ValueError із номером рядка. Порожній файл спричиняє помилку, а не запускає оброблення без камер.

Список або кортеж джерел наживо дає той самий результат без файла.

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

Захоплення екрана

Один знімок екрана (потрібні mss і сеанс робочого стола)
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") # Без stream=True отримується один кадр.result = model("screen")print(len(result.boxes), "detections")
Неперервне захоплення області одного монітора
import itertools from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") # "screen <monitor> <left> <top> <width> <height>"for result in itertools.islice(model("screen 1 100 200 512 256", stream=True), 50):    print(len(result.boxes))

Джерело екрана задається словом screen, після якого йде нуль, одне, чотири або п'ять цілих чисел. Будь-яка інша кількість спричиняє ValueError.

ФормаЗахоплює
"screen"Усі монітори разом
"screen 1"Монітор 1
"screen 100 200 512 256"Прямокутник на об'єднаному робочому столі
"screen 1 100 200 512 256"Прямокутник на моніторі 1

Координати прямокутника задано як left top width height відносно верхнього лівого кута вибраного монітора. Джерело екрана повідомляє частоту кадрів як 30, поділене на vid_stride; з такою частотою записується збережене відео. Для захоплення потрібен пакет mss:

bash
pip install mss

Без stream=True джерело екрана захоплює один кадр і повертає один Results, що відповідає передбаченню для знімка екрана як файла зображення. Зі stream=True захоплення триває до переривання циклу.

Що повертає predict

Форма поверненого значення залежить від джерела та stream.

Джерелоstream=Falsestream=True
Одне зображенняОдин ResultsГенератор одного Results
Список зображеньСписок ResultsГенератор
ПапкаСписок ResultsГенератор
ВідеофайлСписок ResultsГенератор
ЕкранОдин ResultsНеобмежений генератор
Вебкамера, мережевий потік, .streamsValueErrorНеобмежений генератор

Одне зображення повертає сам об'єкт Results. Індексування вибирає в ньому виявлення, а не зображення, тому result[0] для передбачення одного зображення є першою рамкою, а не першою картинкою. Вміст цих об'єктів описано в розділі Робота з результатами.

Куди записує save

save=True записує анотований вивід у каталог запуску, а не повертає його.

Зображення потрапляють до автоматично нумерованих каталогів runs/detect/predict, runs/detect/predict2 тощо зі збереженням назви файла джерела. Усі зображення одного процесу потрапляють до одного каталогу, тому дві вхідні папки з однаковою назвою файла перезаписують одна одну. Зображення з пам'яті не мають назви файла для повторного використання й нумеруються як image0, image1 тощо.

Відео та джерела наживо записуються як один файл .mp4, названий за джерелом.

output_path перевизначає каталог. Шлях із суфіксом розглядається як файл, а шлях без нього як каталог. output_file_format вибирає кодування нерухомого зображення та приймає jpg, png або webp.

Після збереження записаний шлях також додається до результату як result.saved_path.

Класифікацію джерел перевірено за libreyolo/utils/source.py (classify_source, SourceKind, StreamSource, MultiStreamSource). Прийняті типи зображень і розширення каталогів взято з libreyolo/utils/image_loader.py. Розширення відео та шляхи збереження взято з libreyolo/utils/video.py. Синтаксис екрана взято з libreyolo/utils/screen.py. Форми повернених даних і типові значення аргументів перевірено за InferenceRunner.__call__ у libreyolo/models/base/inference.py.