Ultralytics YOLO27: Встать в лист ожидания.
Get Started
Обучи первую модель YOLO·Развёртывание·Урок 9/10
Урокначинающий

Запуск инференса на видео

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

Большинство внедрённых систем компьютерного зрения анализируют видео: камеры над конвейерами, у дверей и на дорогах. В видео есть две проблемы, которых нет у отдельных изображений. Память: длинную запись нельзя целиком хранить в оперативной памяти. Идентификация: детектор видит одного и того же человека в 60 кадрах и сообщает о 60 людях.

В этом уроке ты будешь обрабатывать видео покадрово с помощью режима Predict, добавишь отслеживание объектов, чтобы считать каждого человека один раз, напишешь собственный цикл обработки с камеры и измеришь, успевает ли модель обрабатывать кадры.

Результат

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

Ускоренное прохождение
Если ты уже освоился, вот краткая версия.
  1. model(video, stream=True) выдаёт один Results на каждый кадр, используя ограниченный объём памяти.

  2. model.track(video, stream=True, persist=True, tracker='bytetrack.yaml') добавляет boxes.id.

  3. Считай уникальные объекты по множеству идентификаторов, а не по наибольшему идентификатору.

  4. Бюджет = 1000 ÷ FPS источника; сравни его с result.speed['inference'].

Практические занятия

Пример: предсказание на видеофайле#

Видео обрабатывается в том же режиме Predict, что и изображения. В этом 62-кадровом клипе люди пересекают атриум:

yolo predict model=yolo26n.pt source=https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4
video 1/1 (frame 1/62) solutions_ci_demo.mp4: 384x640 22 persons, 27.3ms
...
video 1/1 (frame 62/62) solutions_ci_demo.mp4: 384x640 22 persons, 54.8ms
Results saved to runs/detect/predict
  • frame 1/62: Ultralytics декодирует видео и обрабатывает каждый кадр как изображение.
  • 22 persons: детекции в этом кадре. Те же прохожие снова учитываются в каждом кадре.
  • 27.3ms ... 54.8ms: время обработки каждого кадра меняется в зависимости от нагрузки на компьютер.

Видео с аннотациями сохранено в runs/detect/predict/solutions_ci_demo.mp4. Твоя модель работает так же: замени yolo26n.pt на runs/detect/pills_v1/weights/best.pt.

Обработка длинных потоков и трансляций в реальном времени#

Если код выполняет действия с детекциями, обрабатывай поток в цикле. На каждой итерации возвращается Results одного кадра, а затем кадр удаляется:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
source = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"

frames, people = 0, 0
for result in model(source, stream=True, classes=[0], verbose=False):  # one Results object per frame
    frames += 1
    people += len(result.boxes)
print(f"{frames} frames, {people / frames:.1f} people per frame")
62 frames, 22.2 people per frame

Тот же цикл работает с индексом веб-камеры (source=0) или URL камеры, например rtsp://camera.local/stream, и выполняется, пока поток не завершится или ты его не остановишь. Добавь vid_stride=2, чтобы обрабатывать каждый второй кадр. Руководство по инференсу в реальном времени с Streamlit показывает, как обернуть этот цикл в приложение с браузерным интерфейсом.

Пример: считай каждого человека один раз#

«22 человека в кадре» — не та цифра, которая нужна; нужна «сколько человек прошло мимо». Многообъектный трекинг связывает рамки между кадрами, а режим Track присваивает каждому объекту идентификатор в boxes.id:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
source = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"

seen = set()
for result in model.track(source, stream=True, persist=True, classes=[0], tracker="bytetrack.yaml", verbose=False):
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
print(f"{len(seen)} unique people tracked")
32 unique people tracked

is_track — это False для кадров до подтверждения трека, когда boxes.id равно None. Используй идентификаторы для подсчёта, построения траекторий или логики вроде «этот объект находится здесь уже 3 секунды».

Трекинг с Ultralytics YOLO на шоссе: у каждой машины, автобуса и грузовика есть постоянная метка с идентификатором и траекторией движения

ТрекерСкоростьНадёжность
bytetrack.yamlБыстрее, прощеЧаще теряет идентификаторы, когда объекты ненадолго исчезают
botsort.yamlМедленнееЛучше сохраняет идентификаторы при движении камеры (компенсация движения; ReID по внешнему виду включается отдельно через with_reid)

Не указывай tracker, и Ultralytics использует tracktrack.yaml — текущий вариант по умолчанию; в режиме Track также доступны ocsort.yaml, deepocsort.yaml и fasttrack.yaml. Выбор и настройка трекеров, а также создание на их основе систем подсчёта объектов, тепловых карт и оценки скорости рассматриваются в руководстве «Отслеживание объектов с ByteTrack, BoT-SORT и TrackTrack».

Пример: собственный цикл обработки с камеры#

Реальным приложениям часто нужно самостоятельно считывать кадры — чтобы изменить размер, обрезать их, добавить временную метку или предоставить доступ к камере другому коду — и передавать каждый кадр модели. В таком случае persist=True поддерживает работу трекера между вызовами:

import cv2

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
cap = cv2.VideoCapture("solutions_ci_demo.mp4")  # saved locally by the commands above; or 0, or an rtsp:// URL

seen = set()
while cap.isOpened():
    ok, frame = cap.read()
    if not ok:
        break
    result = model.track(frame, persist=True, classes=[0], tracker="bytetrack.yaml", verbose=False)[0]
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
cap.release()
print(f"{len(seen)} unique people, highest ID {max(seen)}")
32 unique people, highest ID 67

Столько же людей, сколько в track.py: 32. Обрати внимание: наибольший идентификатор — 67, а не 32: трекер присваивает идентификаторы и предварительным трекам, которые так и не подтверждаются, поэтому в нумерации есть пропуски.

Успевай за источником#

Камера с частотой 30 FPS передаёт кадр каждые 33 мс, а эффективная частота ограничена самым медленным этапом: декодированием, инференсом или записью. На нашем ноутбуке с CPU обработка yolo26n занимала от 26 до 46 мс на кадр размером 384×640 в разных запусках, в зависимости от нагрузки на компьютер: это равно бюджету или превышает его, запаса нет. Если твоя система не успевает, попробуй следующие способы по порядку:

СпособЭффект
Модель поменьше (n вместо s)Часто ускоряет в 2–3 раза
Уменьши imgsz (480 вместо 640)Меньше пикселей — меньше вычислений; в первую очередь страдает обнаружение мелких объектов
vid_stride=2Сокращает объём работы вдвое; подходит для сцен с медленно движущимися объектами
GPU или оптимизированный экспортСамый большой прирост — движок TensorRT на NVIDIA или INT8; подробности — в следующем уроке

Работа с несколькими камерами одновременно и связанная с этим многопоточность рассматриваются в руководстве «Инференс с несколькими потоками».

Избегай этих ошибок#

Забыли stream=True

Симптом: при обработке длинной записи объём памяти растёт, пока процесс не завершится с ошибкой, или вызов для камеры в реальном времени никогда не возвращает результат. Причина: без этого параметра вызов Python собирает объект Results для каждого кадра, прежде чем вернуть результат. Решение: передай stream=True и используй генератор в цикле — он ничего не делает, пока ты не начнёшь его перебирать.

Забыли persist=True в собственном цикле

Симптом: в cv2_loop.py без persist=True количество упало до 27, и максимальный ID тоже оказался равен 27: ID начинались заново в каждом кадре, поэтому «уникальное» количество соответствовало лишь кадру с наибольшим числом объектов. Решение: передавай persist=True каждый раз, когда вызываешь track для очередного кадра.

Подсчёт по максимальному ID

Симптом: насчитано 67 человек при фактическом количестве 32. Причина: в ID есть пропуски из-за неподтверждённых треков. Решение: подсчитывай размер множества ID, как в track.py.

Явно указывай трекер

Трекер по умолчанию может меняться от версии к версии. Передавай tracker="bytetrack.yaml" (или выбранный тобой вариант), чтобы результаты подсчёта оставались сопоставимыми между версиями.

Попробовать

Запусти track_any.py (из решения) на демонстрационном клипе, а затем на коротком собственном видео. Предоставь отчёт из трёх строк: число уникальных объектов, среднее время инференса на кадр в миллисекундах и соответствие этого значения длительности кадра источника, а также первый способ ускорения, который ты применишь, если система не успевает. Сохрани одно видео с аннотациями с помощью yolo track ... save=True и отметь, остаются ли идентификаторы стабильными при перекрытиях; если они меняются, попробуй tracker=botsort.yaml.

Критерии готовности
Урок считается завершённым, если выполнены все условия ниже.
  • Ты сохранил видео с аннотациями с помощью yolo predict или yolo track.

  • Твой скрипт потоковой обработки выводит число уникальных объектов, рассчитанное по множеству значений boxes.id.

  • Ты сравнил измеренное время обработки кадра в миллисекундах с длительностью кадра источника и назвал первый способ ускорения.

Показать решение
import sys

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
seen, times = set(), []
for result in model.track(sys.argv[1], stream=True, persist=True, tracker="bytetrack.yaml", verbose=False):
    times.append(result.speed["inference"])
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
print(f"{len(seen)} unique objects, {sum(times) / len(times):.1f} ms inference per frame")

Запусти его с python track_any.py your_video.mp4.

32 unique objects, 30.5 ms inference per frame (26-46 ms across runs on a laptop CPU)
Source is 30 FPS -> 33 ms budget: fits only on a quiet machine, with no headroom
First lever: export to OpenVINO or ONNX for this CPU, then vid_stride=2 if still short
Что дальше

Твоя модель работает с изображениями и видео в Python. Остался последний шаг: экспортируй её в формат, который сможет загрузить среда выполнения в production.

Войди, чтобы сохранять прогресс