Фаза 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 с нуля · Полный каталог