Фаза 04 · урок 21

Обнаружение ключевых точек и оценка позы

Цель урока: Поза — это упорядоченный набор ключевых точек. Детектор ключевых точек — это регрессор тепловых карт. Всё остальное — организационная работа.

Текущий релиз AlexBred.com: первые 100 уроков русскоязычной программы.

Курс
AI Engineering from Scratch
Фаза
Компьютерное зрение
Чтение
9 мин.
Проверено
Содержание урока
  1. Цели обучения
  2. Задача
  3. Концепция
  4. Top-down и bottom-up
  5. Регрессия тепловых карт
  6. Субпиксельная локализация
  7. Поля частичного сродства (PAFs)
  8. Ключевые точки COCO
  9. 2D и 3D
  10. Соберите решение
  11. Шаг 1: Целевая гауссова тепловая карта
  12. Шаг 2: Миниатюрная голова для ключевых точек
  13. Шаг 3: Инференс — извлечение координат ключевых точек
  14. Шаг 4: Синтетический датасет ключевых точек
  15. Шаг 5: Обучение
  16. Используйте решение
  17. Подготовьте к поставке
  18. Упражнения
  19. Ключевые термины
  20. Дополнительные материалы

Поза — это упорядоченный набор ключевых точек. Детектор ключевых точек — это регрессор тепловых карт. Всё остальное — организационная работа.

Тип: Соберите Языки: Python Предварительные требования: Фаза 4, урок 06 (обнаружение), фаза 4, урок 07 (U-Net) Время: ~45 минут

Цели обучения

  • Различать оценку позы по схеме top-down и bottom-up и указывать, когда применяется каждая из них
  • Предсказывать тепловые карты для K ключевых точек с целевой функцией в виде гауссианы на каждую ключевую точку и извлекать координаты ключевых точек при инференсе
  • Объяснить поля частичного сродства (Part Affinity Fields, PAFs) и то, как bottom-up-конвейеры объединяют ключевые точки в экземпляры
  • Использовать MediaPipe Pose или MMPose для промышленной оценки ключевых точек и понимать формат их вывода

Задача

Задачи с ключевыми точками скрываются под множеством названий: поза человека (17 суставов тела), лицевые ориентиры (68 или 478 точек), кисть (21 точка), поза животного, поза роботизированного объекта, ориентиры медицинской анатомии. У всех одна и та же структура: обнаружить K дискретных точек на объекте и выдать их координаты (x, y).

Оценка позы лежит в основе захвата движения, фитнес-приложений, спортивной аналитики, управления жестами, анимации, AR-примерки и роботизированного захвата. Случай 2D уже зрел; 3D-поза (оценка положений суставов в мировых координатах по одной камере) — нынешний передний край исследований.

Инженерный вопрос — масштаб. Поза одного человека на одном изображении решается за 20 ms. Поза нескольких людей в толпе с 30 fps — другая задача, требующая других архитектур.

Концепция

Top-down и bottom-up

Диаграмма к уроку «Обнаружение ключевых точек и оценка позы»

  • Top-down — сначала обнаружить людей, затем запустить модель ключевых точек для каждого человека на каждом обрезанном фрагменте. Даёт наивысшую точность; масштабируется линейно с числом людей.
  • Bottom-up — один прямой проход предсказывает все ключевые точки и поле связей, затем группирует их. Постоянное время независимо от размера толпы.

Top-down (HRNet, ViTPose) лидирует по точности; bottom-up (OpenPose, HigherHRNet) лидирует по пропускной способности в переполненных сценах.

Регрессия тепловых карт

Вместо непосредственной регрессии (x, y) предскажите тепловую карту H x W для каждой ключевой точки с гауссовым пятном, центрированным в истинном положении.

target[k, y, x] = exp(-((x - cx_k)^2 + (y - cy_k)^2) / (2 sigma^2))

При инференсе argmax каждой тепловой карты является предсказанным местоположением ключевой точки.

Почему тепловые карты работают лучше прямой регрессии: пространственная структура сети (карта свёрточных признаков) естественно согласуется с пространственным выводом. Гауссовы цели также регуляризируют: небольшая ошибка локализации создаёт небольшую, а не нулевую потерю.

Субпиксельная локализация

Argmax даёт целочисленные координаты. Для субпиксельной точности уточняйте их, подгоняя параболу по argmax и его соседям, или используйте хорошо известное направление смещения (dx, dy) = 0.25 * (heatmap[y, x+1] - heatmap[y, x-1], ...).

Поля частичного сродства (PAFs)

Приём OpenPose для bottom-up-сопоставления. Для каждой пары соединённых ключевых точек (например, левого плеча и левого локтя) предскажите двухканальное поле, кодирующее единичный вектор, направленный от одной к другой. Чтобы сопоставить плечо с локтем, интегрируйте PAF вдоль линии, соединяющей пары кандидатов; сопоставляется пара с наибольшим интегралом.

For each connection (limb):
  PAF channels: 2 (unit vector x, y)
  Line integral: sum over sample points of (PAF . line_direction)
  Higher integral = stronger match

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

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

Стандартный датасет поз тела: 17 ключевых точек на человека, а также метрики PCK (Percentage of Correct Keypoints) и OKS (Object Keypoint Similarity). OKS — аналог IoU для ключевых точек; именно эту метрику сообщает COCO mAP@OKS.

2D и 3D

  • 2D-поза — координаты на изображении; решена с промышленным качеством (MediaPipe, HRNet, ViTPose).
  • 3D-поза — мировые / камерные координаты; всё ещё активное направление исследований. Распространённые подходы:
    • Поднять 2D-предсказания до 3D с помощью небольшой MLP (VideoPose3D).
    • Прямая 3D-регрессия по изображению (PyMAF, MHFormer).
    • Многокамерные установки (CMU Panoptic) для ground truth.

Соберите решение

Шаг 1: Целевая гауссова тепловая карта

import numpy as np
import torch

def gaussian_heatmap(size, cx, cy, sigma=2.0):
    yy, xx = np.meshgrid(np.arange(size), np.arange(size), indexing="ij")
    return np.exp(-((xx - cx) ** 2 + (yy - cy) ** 2) / (2 * sigma ** 2)).astype(np.float32)

hm = gaussian_heatmap(64, 32, 32, sigma=2.0)
print(f"peak: {hm.max():.3f} at ({hm.argmax() % 64}, {hm.argmax() // 64})")

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

Шаг 2: Миниатюрная голова для ключевых точек

Модель в стиле U-Net, которая выводит K каналов тепловых карт.

import torch.nn as nn
import torch.nn.functional as F

class TinyKeypointNet(nn.Module):
    def __init__(self, num_keypoints=4, base=16):
        super().__init__()
        self.down1 = nn.Sequential(nn.Conv2d(3, base, 3, 2, 1), nn.ReLU(inplace=True))
        self.down2 = nn.Sequential(nn.Conv2d(base, base * 2, 3, 2, 1), nn.ReLU(inplace=True))
        self.mid = nn.Sequential(nn.Conv2d(base * 2, base * 2, 3, 1, 1), nn.ReLU(inplace=True))
        self.up1 = nn.ConvTranspose2d(base * 2, base, 2, 2)
        self.up2 = nn.ConvTranspose2d(base, num_keypoints, 2, 2)

    def forward(self, x):
        h1 = self.down1(x)
        h2 = self.down2(h1)
        h3 = self.mid(h2)
        u1 = self.up1(h3)
        return self.up2(u1)

Вход (N, 3, H, W), выход (N, K, H, W). Функция потерь — попиксельная MSE относительно гауссовых целей.

Шаг 3: Инференс — извлечение координат ключевых точек

def heatmap_to_coords(heatmaps):
    """
    heatmaps: (N, K, H, W)
    returns:  (N, K, 2) float coordinates in image pixels
    """
    N, K, H, W = heatmaps.shape
    hm = heatmaps.reshape(N, K, -1)
    idx = hm.argmax(dim=-1)
    ys = (idx // W).float()
    xs = (idx % W).float()
    return torch.stack([xs, ys], dim=-1)

coords = heatmap_to_coords(torch.randn(2, 4, 32, 32))
print(f"coords: {coords.shape}")  # (2, 4, 2)

Одна строка при инференсе. Для субпиксельного уточнения интерполируйте область вокруг argmax.

Шаг 4: Синтетический датасет ключевых точек

Всё просто: нарисуйте четыре точки на белом холсте и научите модель их предсказывать.

def make_synthetic_sample(size=64):
    img = np.ones((3, size, size), dtype=np.float32)
    rng = np.random.default_rng()
    kps = rng.integers(8, size - 8, size=(4, 2))
    for cx, cy in kps:
        img[:, cy - 2:cy + 2, cx - 2:cx + 2] = 0.0
    hms = np.stack([gaussian_heatmap(size, cx, cy) for cx, cy in kps])
    return img, hms, kps

Это достаточно просто, чтобы миниатюрная модель обучилась за минуту.

Шаг 5: Обучение

model = TinyKeypointNet(num_keypoints=4)
opt = torch.optim.Adam(model.parameters(), lr=3e-3)

for step in range(200):
    batch = [make_synthetic_sample() for _ in range(16)]
    imgs = torch.from_numpy(np.stack([b[0] for b in batch]))
    hms = torch.from_numpy(np.stack([b[1] for b in batch]))
    pred = model(imgs)
    # Upsample pred to full resolution
    pred = F.interpolate(pred, size=hms.shape[-2:], mode="bilinear", align_corners=False)
    loss = F.mse_loss(pred, hms)
    opt.zero_grad(); loss.backward(); opt.step()

Используйте решение

  • MediaPipe Pose — промышленный оценщик позы от Google; поставляется со средами выполнения WebGL + mobile и задержкой менее 10 ms.
  • MMPose (OpenMMLab) — всеобъемлющая исследовательская кодовая база; каждая SOTA-архитектура с предобученными весами.
  • YOLOv8-pose — самая быстрая оценка позы нескольких людей в реальном времени одним прямым проходом.
  • transformers HumanDPT / PoseAnything — более новые подходы «зрение-язык» для позы с открытым словарём (любой объект, любой набор ключевых точек).

Подготовьте к поставке

Этот урок создаёт:

  • outputs/prompt-pose-stack-picker.md — промпт, выбирающий MediaPipe / YOLOv8-pose / HRNet / ViTPose с учётом задержки, размера толпы и потребности в 2D или 3D.
  • outputs/skill-heatmap-to-coords.md — навык, пишущий подпрограмму преобразования тепловой карты в координаты с субпиксельной точностью, используемую каждой промышленной моделью позы.

Упражнения

  1. (Легко) Обучите миниатюрную модель ключевых точек на синтетическом датасете из 4 точек. Сообщите среднюю L2-ошибку между предсказанными и истинными ключевыми точками после 200 шагов.
  2. (Средне) Добавьте субпиксельное уточнение: для позиции argmax подгоните одномерную параболу вдоль x и y по соседним пикселям. Сообщите прирост точности по сравнению с целочисленным argmax.
  3. (Сложно) Постройте синтетический датасет для двух людей, в котором каждое изображение показывает два экземпляра шаблона из 4 ключевых точек. Обучите bottom-up-конвейер с PAFs, предсказывающий принадлежность ключевой точки каждому экземпляру, и оцените OKS.

Ключевые термины

ТерминКак обычно говорятЧто это на самом деле означает
Ключевая точка«Ориентир»Конкретная упорядоченная точка объекта (сустав, угол, признак)
Поза«Скелет»Упорядоченный набор ключевых точек, принадлежащих одному экземпляру
Top-down«Сначала обнаружить, затем поза»Двухэтапный конвейер: детектор человека + модель ключевых точек для каждого обрезанного фрагмента; наивысшая точность
Bottom-up«Сначала поза, потом группировка»Однопроходное предсказание всех ключевых точек + группировка; постоянное время по размеру толпы
Тепловая карта«Гауссова цель»Тензор H x W для каждой ключевой точки с пиком в истинном местоположении; предпочтительная цель регрессии
PAF«Part Affinity Field»Двухканальное поле единичных векторов, кодирующее направления конечностей; используется для группировки ключевых точек в экземпляры
OKS«IoU для ключевых точек»Object Keypoint Similarity; метрика COCO для позы
HRNet«High-Resolution Net»Доминирующая top-down-архитектура для ключевых точек; сохраняет признаки высокого разрешения на всём протяжении

Дополнительные материалы

  • OpenPose (Cao et al., 2017) — bottom-up с PAFs; всё ещё лучшее описание подхода
  • HRNet (Sun et al., 2019) — эталонная top-down-архитектура
  • ViTPose (Xu et al., 2022) — простой ViT как backbone для позы; текущий SOTA на многих бенчмарках
  • MediaPipe Pose — промышленная оценка позы в реальном времени; самый быстрый развёрнутый стек в 2026 году

Источник: Keypoint Detection & Pose Estimation 04.20 — Поиск изображений и метрическое обучение · Фаза 04 — Компьютерное зрение · 04.22 — 3D Gaussian Splatting с нуля · Полный каталог