Как стать автором
Обновить

YOLOv7 для определения поз людей на видео

Уровень сложности Средний
Время на прочтение 16 мин
Количество просмотров 7.5K

Привет, Хабр!

С вами Максим Алёшин, Data Scientist и участник профессионального сообщества NTA.

В этом посте мы познакомимся с возможностями YOLOv7 для определения поз людей на видео, обсудим принцип работы алгоритма, разберёмся, чем принципиально отличается подход к детекции скелетов человека в модели YOLOv7 и других фреймворках, подробно пройдёмся по всем шагам запуска на инференс предобученной модели YOLOv7-pose для детекции людей с их скелетами.

В процессе копания в первоисточниках и не только, мне удалось почерпнуть несколько интересных фактов о YOLO, чем я поделюсь. Некоторые труднопереводимые термины будут оставаться как есть.

Быстрая навигация по материалу

Введение

Обнаружение объектов (Object detection) — это очень обширная область компьютерного зрения и одно из самых важных применений компьютерного зрения «в природе». С развитием различных подходов в этой области возникла также задача детекции ключевых точек (keypoint detection), которые могут быть различными: части лица, конечности тела и другие. Определение позы человека (pose estimation, будем иногда называть это задачей детекции скелета) — это частный случай детекции ключевых точек, в котором ими являются части человеческого тела. В некоторых случаях использование моделей детекции ключевых точек даёт ощутимое преимущество перед обычными моделями детекции объектов, которые гарантируют на выходе лишь получение области, ограничивающей сам объект на изображении (boundary box или bbox). Так, детекция скелета может быть полезна в самых разных применениях: например, в системах мониторинга состояния человека, приложениях дополненной реальности, в компьютерной графике при создании анимации персонажа.

Мы обратили внимание на модели детекции скелета благодаря их потенциальному применению в рамках проекта с использованием компьютерного зрения. В нашем случае подразумевается использование YOLOv7-pose совместно с моделью‑детектором для определения факта передачи мобильных устройств от одного человека другому. Логика, реализуемая после определения точек скелета, позволяет, во‑первых, запускать детектор мобильного устройства не на всём кадре, а только в окрестности координат ключевых точек запястий, во‑вторых по этим же координатам при наличии в кадре нескольких человек, предсказывать вероятность передачи устройства из рук в руки.

Немного о YOLO

YOLO (You Only Look Once, «ты смотришь лишь раз») — метод идентификации и распознавания объектов на фотографиях в реальном времени, который впервые был предложен в 2015 году. Благодаря скорости, точности и простоте в обучении YOLO быстро стал самым используемым алгоритмом для идентификации объектов, в последствии к его совершенствованию приложили свои усилия разные разработчики. YOLOv1, YOLOv2 и YOLOv3 были реализованы одним коллективом авторов под началом Джозефа Редмона. Третья версия стала, последней над которой работал Редмон: он перестал заниматься задачами компьютерного зрения по этическим соображениям.

YOLOv4 была выпущен Алексеем Бочковским и др., и изначально являлась форком YOLOv3. Все перечисленные версии были основаны на фреймворке DarkNet. Начиная c YOLOv5 стал использоваться PyTorch. Это самая популярная в настоящее время версия, она был выпущена компанией Ultralytics (они же недавно представили усовершенствованную версию YOLOv8). Примечательно, что YOLOv6 была представлена китайской компанией Meituan примерно в одно время с YOLOv7, которая в свою очередь была выпущена уже упомянутым Бочковским и др. Некоторые из существовавших ответвлений мы даже не упомянули. Сложно ответить на вопрос, какой из последних репозиториев является актуальной официальной версией, ведь они развиваются параллельно.

YOLOv7 — это не просто архитектура обнаружения объектов. Она предоставляет новые блоки предсказаний на выходе (prediction heads), которые помимо определения bbox объектов могут выдавать ключевые точки и выполнять сегментацию объектов, что не было стандартным для предыдущих моделей YOLO. Сама модель была создана путем изменения архитектуры, а также оптимизации процесса обучения, получившей название «bag‑of‑freebies» (дословно мешок бесплатных подарков), что позволило повысить точность без уменьшения скорости детекции. Подробно архитектуру сети и возможности алгоритма авторы описывают в своей публикации «YOLOv7: Trainable bag‑of‑freebies sets new state‑of‑the‑art for real‑time object detectors» . YOLOv7 обучена на датасете COCO, в котором есть разметка ключевых точек скелета. К слову, среди всех официальных репозиториев YOLO предобученная модель для детекции скелета с сопутствующими скриптами постобработки есть только в YOLOv7.

YOLOv7-pose

Современные модели определения поз в отличие от ранних предшественников позволяют детектировать скелеты сразу нескольких человек в кадре. В большинстве случаев это приводит к значительному увеличению времени детекции, в связи с чем в некоторых моделях предусмотрено ограничение количества детектируемых человек. Обычно алгоритмы определения поз работают в два этапа и делятся на два типа в зависимости от их порядка:

Сверху вниз (Top‑down):

1 этап. Детекция человека

2 этап. Локализация ключевых точек скелета в найденной области.

Снизу вверх (Bottom‑up)

1 этап. Детекция ключевых точек с построением тепловой карты

2 этап. Объединение групп точек, принадлежащих одному человеку.

Top‑down подходы более ресурсозатратны, поскольку обычно используют тяжелые сетки для детекции людей, их вычислительная сложность увеличивается линейно с количеством людей в кадре. Bottom‑up подходы в целом имеют меньшую сложность и преимущество в виде постоянного времени детекции. Однако при этом наблюдается существенное снижение точности по сравнению с первыми. Для извлечения информации необходимы различные дополнительные этапы корректировки и уточнения для извлечения лучших ключевых точек из тепловой карты.

Но, YOLOv7-pose — одноэтапная модель определения поз одновременно нескольких человек на изображении. Алгоритм детекции поз YOLOv7 похож на Bottom‑up, но в нём не происходит построения тепловой карты. В модели YOLO детекция человека и ключевых точек позы происходит совместно, в один этап. Среди всех обнаруженных объектов с помощью метода non‑maximum suppression происходит фильтрация результатов предсказания. Как пишут разработчики YOLOv7 в приложении к своей публикации, размещённой в репозитории, для подготовки YOLOv7-pose они использовали настройки, описанные авторами модели YOLO‑Pose, которые получили её на основе YOLOv5. Также отметим, что качество предсказаний моделей детекции ключевых точек определяется с помощью метрики OKS (Object Keypoint Similarity — схожесть ключевых точек объекта). Согласно авторам YOLOv7-pose OKS их модели на тестовом наборе COCO равна 90.3%.

Несмотря на наличие весов предобученной модели в репозитории, готового скрипта для детекции скелета там нет. Чтобы реализовать его самостоятельно разберёмся, как работает модель, в каком формате выдаёт результат.

Ключевые точки

YOLOv7-pose способна детектировать 17 ключевых точек скелета, что соответствует разметке в наборе данных COCO. Изобразим наглядно эти точки.

Ключевые точки позы человека, размеченные в датасете COCO
Ключевые точки позы человека, размеченные в датасете COCO

Принцип работы YOLOv7 на детекции

Семейство алгоритмов YOLO — это «ancor‑based» модели (модели на основе якорей). Общая идея в том, чтобы сначала создать множество потенциальных bbox, а затем выбрать наиболее подходящие варианты, соответствующие нашим целевым объектам. Модель генерирует сетку поверх изображения и в каждом узле сетки (якоре, anchor) создаёт опорные боксы (anchor boxes) нескольких размеров (anchor sizes). В каждом узле повторяется один и тот же набор боксов. Таким образом, модель будет обучаться в процессе перемещения по сетке и изменения размеров этих bbox, это проще, чем генерирование bbox с нуля.

Пример боксов на сетке, сгенерированных моделью (источник)
Пример боксов на сетке, сгенерированных моделью (источник)

Однако одна из проблем этого подхода заключается в том, что размеры bbox могут варьироваться — от крошечных до огромных. Поэтому обычно невозможно определить универсальный набор размеров якорей для любых изображений. По этой причине архитектуры моделей на основе якорей обычно используют Feature‑Pyramid‑Network (сети пирамид признаков), которые, если говорить обобщённо, извлекают признаки одновременно из изображений разных масштабов. По этой причине YOLOv7 работает одновременно с несколькими сетками на изображении.

Подробнее можно почитать тут (хороший материал с объяснением принципа работы).

Примеры различных сеток и различных размеров ящиков (источник)
Примеры различных сеток и различных размеров ящиков (источник)

Загрузка модели YOLOv7-pose

Приступим к реализации алгоритма, по ходу разбираясь со структурой модели и выводов.

Конфигурация системы, на которой будем работать: персональный компьютер с Windows 11, Python 3.10, восьми ядерный CPU — AMD Ryzen 7 3700X, 32 ГБ RAM, GPU — GeForce RTX 2060 c 8 ГБ GDDR5, диск — NVMe SSD.

Весь описанный ниже код можно запускать даже на CPU, поскольку работа модели в режиме выдачи предсказаний не столь требовательна, как при её обучении. Однако, время обработки на CPU может быть на порядки выше, чем на GPU + CPU. И если при обработке отдельного изображения разница во времени выполнения не столь заметна, то при запуске детекции на видео наличие GPU уже существенно: на нашей системе обработка изображения разрешением 4900×6400 пикселей не превышала 4 секунд на CPU и занимала менее 1 секунды при подключении GPU. В завершении поделюсь некоторыми тестами. Необходимые библиотеки устанавливаются в окружение из requirements.txt. Используется torch 1.11.0+cu113, torchvision 0.12.0+cu113, opencv‑python 4.6.

Первым делом склонируем себе репозиторий yolov7.

! git clone https://github.com/WongKinYiu/yolov7.git

Перейдём в директорию и установим необходимые библиотеки.

%cd yolov7
!pip install -r requirements.txt

Также предварительно скачаем веса, они находятся в разделе релизов репозитория, для детекции скелетов доступна только одна модификация весов — yolov7-w6-pose.pt.

import requests
WEIGHTS_URL = 'https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-w6-pose.pt'
open("weights/yolov7-w6-pose.pt", "wb").write(requests.get(WEIGHTS_URL).content)

Папка weights должна быть предварительно создана. Импортируем необходимые библиотеки и функции.

import cv2
import torch
from torchvision import transforms
import numpy as np
import matplotlib.pyplot as plt

from models.experimental import attempt_load 
from utils.datasets import letterbox 
from utils.general import non_max_suppression_kpt, xywh2xyxy
from utils.plots import output_to_keypoint, plot_skeleton_kpts, plot_one_box

attempt_load понадобится нам для загрузки весов модели, letterbox для приведения размера картинки к нужным пропорциям, non_max_suppression_kpt для фильтрации предсказаний модели, xywh2xyxy для изменения координат bbox формата центр + размеры прямоугольника в координаты углов прямоугольника, output_to_keypoint для преобразования вывода модели в координаты ключевых точек, plot_skeleton_kpts и plot_one_box для прорисовки скелета и bbox.

Итак, загрузим модель и посмотрим информацию о ней, установим в качестве устройства для расчётов видеокарту, если она доступна. Командой eval() переведём модель в режим инференса. Также посмотрим информацию о количестве классов в модели и количестве ключевых точек.

# set gpu device if possible
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print('Device:', device)
# Load model
model = attempt_load('weights/yolov7-w6-pose.pt', map_location=device) 
# Switch to evaluation mode, map_location=device
model.eval()

print('Number of classes:', model.yaml['nc'])
print('Number of keypoints:', model.yaml['nkpt'])

Результат вывода этого блока кода следующий:

Device: cuda:0

Fusing layers...

Number of classes: 1

Number of keypoints: 17

Действительно, предсказывается вероятность единственного класса nc = 1, то есть человека, для него детектируется 17 ключевых точек nkpt = 17.

Детекция скелета с YOLOv7

На инференс модели подаётся батч картинок в формате torch.Tensor. Мы будем работать здесь с отдельными изображениями, поэтому в нашем случае батч будет содержать отдельную картинку. Но перед подачей картинки в модель, её размер должен удовлетворять условию кратности каждой стороны шагу stride сетки, по которой модель пробегает для детекции объектов. Это обусловлено алгоритмом работы, о котором мы писали выше. Загрузим тестовое изображение, посмотрим на него и его размеры, и проследим, как оно изменится после применения функции letterbox. Предварительно объявим функцию для более простого вывода картинок.

def show_image(img, figsize=(6,6)):            
    plt.figure(figsize=figsize)
    plt.imshow(img)
    plt.axis('off')
    plt.show()

# read original image
orig_img = cv2.imread('test_img.jpg')
orig_img = cv2.cvtColor(orig_img, cv2.COLOR_BGR2RGB)
print('Original image', orig_img.shape)
show_image(orig_img)

Original image (576, 768, 3)

# resize and pad
img = letterbox(orig_img, 640, stride=64, auto=True)[0]
print('Resized image', img.shape)
show_image(img)

Resized image (512, 640, 3)

Мы не случайно выбрали размер страйда равным 64. После того, как мы подадим картинку на вход модели, получим тензор с результатами детекции на множестве прямоугольников в каждом узле сетки, сгенерированной моделью YOLO. Таких сеток несколько, с разным шагом stride. YOLOv7-pose генерирует 4 сетки с шагами [8, 16, 32, 64], соответственно выбираем максимальный из них. Размер картинки мы установили равным 640, чтобы выполнялось условие кратности шагу. И в каждом узле вычисление производится в прямоугольниках нескольких размеров, они также называются якорями anchors.

print('Anchors:', model.yaml['anchors'])

Anchors: [[19, 27, 44, 40, 38, 94], [96, 68, 86, 152, 180, 137], [140, 301, 303, 264, 238, 542], [436, 615, 739, 380, 925, 792]]

Здесь каждый вложенный массив — это пары размеров таких прямоугольников (w, h) для детекции на якоре, здесь по три пары. Индексы вложенных массивов anchors соответствуют значениям страйдов [8, 16, 32, 64]. Детекция производится на сетках с этими шагами.

Таким образом, для нашей картинки размером (512, 640) модель сгенерирует 4 сетки c размерами: (512/s, 640/s), где s — величина страйда. Итого 5120 + 1280 + 320 + 80 = 6800 узлов во всех сетках. Умножая это значение на количество якорей для каждой сетки получаем: 6800 ⋅ 3 = 20 400 прямоугольников‑кандидатов.

Действительно, преобразуем картинку к torch.Tensor, сделаем вложенной в массив и передадим модели, посмотрим на размер предиктов.

# transform to tensor
img_ = transforms.ToTensor()(img)
# add dimension
img_ = torch.unsqueeze(img_, 0)
print('Transformed to tensor image:', img_.shape)
# send the picture to the calculating device
img_ = img_.to(device).float()

with torch.no_grad():
    pred, _ = model(img_)
print('Predictions shape:', pred.shape)

Transformed to tensor image: torch.Size([1, 3, 512, 640])

Predictions shape: torch.Size([1, 20400, 57])

Получили 20400 возможных bbox. Для каждого прямоугольника-кандидата модель выдаёт 57 значений:

  • c 0 по 3 — bbox найденного человека в формате xyxy;

  • 4, 5 — вероятность и метка предсказанного класса (confidence, label);

  • остальные тройки значений: [x, y, conf, x, y, conf,...] — координаты и значимость найденной точки скелета.

Среди этих предиктов лишь часть имеют значимую вероятность, кроме того, результирующий bbox целевого объекта совсем не обязан совпадать с боксом на якоре. Для их фильтрации используется функция non_max_suppression_kpt, не будем здесь разбираться в подробностях её работы, но отметим, что фильтрация происходит в два этапа, сначала по пороговому значению для вероятности детекции человека conf_thres, затем оставшиеся значения фильтруются по взвешенному среднему iou_thres для вероятностей детекции точек скелета. По умолчанию в реализованной разработчиками функции эти значения соответственно 0.25 и 0.45. Оставим пороговое значение для детекции человека без изменения, а пороговое значение детекции точек скелета увеличим и установим iou_thres = 0.65, чтобы уменьшить количество ложных срабатываний.

pred = non_max_suppression_kpt(pred, 
                               conf_thres=0.25, 
                               iou_thres=0.65, 
                               nc=model.yaml['nc'], 
                               nkpt=model.yaml['nkpt'], 
                               kpt_label=True)
print('Detected poses:', len(pred))
print('Prediction shape:', pred[0].shape)

Detected poses: 1

Prediction shape: torch.Size([1, 57])

Далее функцией output_to_keypoint предикты преобразуются к списку, содержащему оставшиеся после фильтрации распознанные позы. На каждый обнаруженный скелет приходится массив из 58 значений, содержащий номер батча (batch_id), метку класса (class_id), bbox (c_x, c_y, w, h), значимость (conf), координаты ключевых точек скелета и их вероятности (kpt_x, kpt_y, kpt_conf). То есть, имеет следующий вид:

[ batch_id, class_id, c_x, c_y, w, h, conf, kpt_x, kpt_y, kpt_conf,... ]

Посмотрим на результат, предварительно объявив функцию для прорисовки скелета и bbox.

def plot_pose_prediction(img : cv2.Mat, pred : list, thickness=2, 
                         show_bbox : bool=True) -> cv2.Mat:
    bbox = xywh2xyxy(pred[:,2:6])
    for idx in range(pred.shape[0]):
        plot_skeleton_kpts(img, pred[idx, 7:].T, 3)
        if show_bbox:
            plot_one_box(bbox[idx], img, line_thickness=thickness)

pred = output_to_keypoint(pred)
plot_pose_prediction(img, pred)
show_image(img)

Мы успешно детектировали скелет человека и построили его на изображении. Однако, модель делает предсказания на изменённом по размеру изображении, ещё и с отступами по краям, которые были добавлены для выполнения условия кратности размеров шагам сетки с якорями. Чтобы нанести детектированные ключевые точки на исходное изображение, необходимо написать функцию для перевода предсказанных точек в систему координат исходного изображения. Помимо этого, соберём все описанные шаги работы модели с изображением в функцию make_pose_prediction.

Посмотреть код
def scale_pose_output(output, resized_shape:tuple, original_shape:tuple, is_padded:bool=True):
    ''' Scale yolo pose estimator output coordinates of bbox and keypoints
    from `resized_shape` to `original_shape` 
    '''
    scaled_output = output.copy()
    scale_ratio = (resized_shape[1] / original_shape[1], 
                   resized_shape[0] / original_shape[0])      
    if is_padded:
        # remove padding
        pad_scale = min(scale_ratio)
        padding = (resized_shape[1] - original_shape[1] * pad_scale ) / 2, (
                   resized_shape[0] - original_shape[0] * pad_scale ) / 2
        scale_ratio = (pad_scale, pad_scale)
        
        scaled_output[:, 2] -= padding[0]     # x_c unpadding
        scaled_output[:, 3] -= padding[1]     # y_c unpadding
        scaled_output[:, 7::3] -= padding[0]  # x_kpts unpadding
        scaled_output[:, 8::3] -= padding[1]  # y_kpts unpadding
    
    scaled_output[:, [2, 4]] /= scale_ratio[0]
    scaled_output[:, [3, 5]] /= scale_ratio[1]
    scaled_output[:, 7::3] /= scale_ratio[0]
    scaled_output[:, 8::3] /= scale_ratio[1]

    return scaled_output

def make_pose_prediction(model, img : cv2.Mat) -> list:
    ''' Make prediction with yolo pose estimator `model` on image `img`
    '''
    # Resize and pad image while meeting stride-multiple constraints
    img_ = letterbox(img, 960, stride=64, auto=True)[0]
    resized_shape = img_.shape[0:2]
    # Transform image to model readable structure
    img_ = transforms.ToTensor()(img_)
    img_ = torch.tensor(np.array([img_.numpy()]))
    img_ = img_.to(device).float()
    with torch.no_grad():
        output, _ = model(img_)
    # Filter predictions
    output = non_max_suppression_kpt(output, 0.25, 0.65, 
                                     nc=model.yaml['nc'], 
                                     nkpt=model.yaml['nkpt'], 
                                     kpt_label=True)
    output = output_to_keypoint(output)
    # scale to original image shape
    output = scale_pose_output(output, resized_shape, img.shape[0:2])
    return output

Проверим для разнообразия на другом изображении.

img = cv2.cvtColor(cv2.imread('breakdance.jpg'), cv2.COLOR_BGR2RGB)
pred = make_pose_prediction(model, img)
plot_pose_prediction(img, pred, show_bbox=False)
show_image(img, (18,18))

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

Детекция на видео

Перенесём этот алгоритм на обработку видео. В качестве примера возьмём любительское видео с горнолыжного склона в разрешении 1280×720 пикселей, частотой 30 кадров в секунду и продолжительностью 18 секунд.

Используем OpenCV для чтения видео и обработаем моделью каждый кадр. Все кадры будем писать в новый файл. Одновременная запись нового файла с отображением кадров неминуемо замедлит процесс обработки, но мы не ставим целью запускать детекцию в реальном времени. Для ускорения процесса можно избежать создания нового файла и записи кадров в него в цикле. Напишем функцию для запуска детекции скелетов на видео.

Посмотреть код
def video_pose(filename, out_filename):
    # Open the input video file and extract its properties
    cap = cv2.VideoCapture(filename)
    fps = cap.get(cv2.CAP_PROP_FPS)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fourcc = cv2.VideoWriter_fourcc(*'MP4V')
    # Create VideoWriter object 
    out = cv2.VideoWriter(out_filename, fourcc, fps, (width, height))
    #  Processing a video file frame by frame
    while cap.isOpened():
        ret, frame = cap.read()
        if ret:
            pred = make_pose_prediction(model, frame)
            plot_pose_prediction(frame, pred, show_bbox=False)
            out.write(frame)
            cv2.imshow('Pose estimation', frame)
        else:
            break

        if cv2.waitKey(10) & 0xFF == ord('q'):
            break
    # Release VideoCapture and VideoWriter
    cap.release()
    out.release()
    # Close all frames and video windows
    cv2.destroyAllWindows()

VideoWriter принимает имя выходного файла, FourCC (код кодека, используемый для кодирования видео), частоту кадров и разрешение видео в виде кортежа. Мы использовали все параметры исходного видео, полученные через VideoCapture, который содержит данные о полученном видео. Теперь мы можем вызывать метод, передав в него путь к любому видео.

video_pose('board.mp4', 'board_out.mp4')

Результат:

Для сравнительной оценки скорости работы алгоритма мы провели подсчёт времени инференса на описанной выше системе (ПК AMD Ryzen 3700X + GeForce RTX 2060 Super) и на ноутбуке c четырёх ядерным CPU Intel i7–1165G7, 32 ГБ RAM, видеокартой GeForce MX450 c 2 ГБ GDDR5, NVMe SSD диском. Производились замеры только времени детекции скелетов, операции по отображению и записи кадров видео с обнаруженными скелетами были полностью исключены из скрипта. С кодом скрипта и результатами можно ознакомиться в Jupyter ноутбуке. Ниже приводим результаты измерений времени детекций в данном видео, содержащем 562 кадра разрешением 1280×720, для конфигураций с использованием GPU и без.

Конфигурация

Время обработки, секунды

Ryzen 3700X + RTX 2060 Super

27

Ryzen 3700X

483

i7-1165G7 + MX450

99

i7-1165G7

908

Обработка видео длительностью 18 секунд самой мощной нашей системой заняла 27 секунд. Заметим, что благодаря реализации алгоритма детекции в YOLOv7 это время практически не зависит от количества людей в кадре. Но для обработки видео с таким разрешением в реальном времени необходимы более мощные видеокарты либо оптимизация алгоритма, в частности может помочь масштабирование изображения или запуск детекции не на каждом кадре.

Заключение

Мы рассмотрели архитектуру YOLOv7, узнали о её новых возможностях, таких как, сегментация, детектирование скелета человека, которые выделяют её среди предшествующих YOLO. На наглядном примере убедились в простоте использования фреймворка. Надеюсь, что руководство и обзор будут полезны читателям, возможно кто‑то почерпнёт для себя новое об алгоритмах YOLO, о принципе их работы.

Отмечу, что есть и другие модели для детекции скелета, которые показывают довольно хорошие результаты, несмотря на некоторые ограничения. Так, MoveNet от Google, в которой используются MobileNetV2 и CenterNet, может работать на мобильных устройствах «из коробки» и даёт неплохую точность. OKS модели по информации разработчиков составляет от 80% до 90% в зависимости от категории датасета (см. описание модели, средней метрики не приводятся). Её авторы в качестве преимущества отмечают отсутствие необходимости использования алгоритма «non‑maximum suppression«. MoveNet также была обучена на COCO датасете, однако разработчики расширили его датасетом, собранным из различных спортивных видео, чтобы улучшить качество детекции людей в движении.

Jupyter Notebook с разобранным примером и готовым скриптом для обработки видео можно найти в репозитории GitHub. Пишите, если хотите увидеть примеры практического применения YOLOv7-pose не только для детектирования скелета, а также сравнение точности и скорости работы c MoveNet или другими моделями.

Теги:
Хабы:
+9
Комментарии 1
Комментарии Комментарии 1

Публикации

Истории

Работа

Data Scientist
66 вакансий

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн
PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн