ردیابی حرکات بدن، چهره یا دست پایهی اصلی اپلیکیشنهای تناسب اندام، پویانمایی، واقعیت افزوده و تحلیلهای حرکتی است. در نگاه اول، پیشبینی مختصات مفاصل شبیه یک رگرسیون سادهی عددی به نظر میرسد؛ اما شبکههای عصبی بدون درک ساختار فضایی تصویر، در پیشبینی مستقیم اعداد به مشکل میخورند. این درس سازوکار دقیق و استاندارد صنعت را بررسی میکند: تبدیل مسئله به رگرسیون نقشههای حرارتی (Heatmaps) و سپس استخراج مختصات نقاط کلیدی.
در این بخش با تفاوتهای بنیادین روشهای بالا به پایین (Top-down) و پایین به بالا (Bottom-up) مانند OpenPose آشنا میشوید، میدانهای پیوستگی اندامها (PAFs) را بررسی میکنید و یاد میگیرید چگونه با معماریهای شبیه U-Net یک آشکارساز سبک بسازید. برای آزمایش و اجرای کدهای این درس به GPU ابری گرانقیمت نیازی ندارید و پایپلاین آزمایشی روی CPU معمولی یا سیستم شخصی شما بهراحتی اجرا میشود.
ژست بدنی (pose) مجموعهای مرتب از نقاط کلیدی است. آشکارساز نقاط کلیدی هم یک مدل رگرسیون نقشه حرارتی است. باقی ماجرا فقط کارهای دفتری و حسابوکتاب است.
اهداف یادگیری
- تشخیص تفاوت تخمین ژست بالا به پایین (top-down) و پایین به بالا (bottom-up) و تعیین زمان استفاده از هرکدام
- رگرسیون نقشههای حرارتی (heatmaps) برای K نقطه کلیدی با هدف گاوسی بهازای هر نقطه و استخراج مختصات نقاط در زمان استنتاج
- توضیح میدانهای پیوستگی اندامها یا PAFs (مخفف Part Affinity Fields) و نحوهی اتصال نقاط کلیدی به نمونههای مجزا در پایپلاینهای پایین به بالا
- استفاده از MediaPipe Pose یا MMPose برای تخمین نقاط کلیدی در محیط عملیاتی و درک ساختار خروجی آنها
صورت مسئله
مسائل مربوط به نقاط کلیدی با نامهای گوناگونی شناخته میشوند: ژست انسان (17 مفصل بدن)، لندمارکهای چهره (68 یا 478 نقطه)، دست (21 نقطه)، ژست حیوانات، ژست اجسام در رباتیک و نقاط شاخص آناتومی در پزشکی. ساختار همهی آنها یکسان است: K نقطهی متمایز را روی یک شیء شناسایی کن و مختصات (x, y) آنها را تحویل بده.
تخمین ژست پایهی موشن کپچر، اپلیکیشنهای تناسب اندام، تحلیلهای ورزشی، کنترل با ژستهای حرکتی، پویانمایی، پرو مجازی در واقعیت افزوده (AR) و گرفتن اجسام در رباتیک است. حالت 2 بعدی به بلوغ کامل رسیده است؛ اما ژست 3 بعدی (تخمین موقعیت مفاصل در مختصات دنیای واقعی با یک دوربین تکی) مرز پژوهشهای کنونی به شمار میرود.
مسئلهی اصلی مهندسی در اینجا مقیاسپذیری است. تخمین ژست یک فرد در یک تکتصویر، مسئلهای 20 میلیثانیهای است؛ ولی تخمین ژست چندین نفر در میان جمعیت با نرخ 30 فریم بر ثانیه، مسئلهای کاملاً متفاوت با معماریهای جداگانه است.
مفاهیم پایه
رویکرد بالا به پایین در برابر پایین به بالا
- بالا به پایین (Top-down) — ابتدا افراد را شناسایی میکند، سپس مدل نقاط کلیدی را روی برش (crop) تصویر هر فرد اجرا میکند. بیشترین دقت را دارد؛ ولی زمان اجرای آن با تعداد افراد رابطهی خطی دارد.
- پایین به بالا (Bottom-up) — با یک گذر رو به جلو (forward pass)، همهی نقاط کلیدی را به همراه یک میدان پیوستگی پیشبینی و سپس آنها را گروهبندی میکند. زمان اجرای آن صرفنظر از تراکم جمعیت، ثابت است.
مدلهای بالا به پایین (نظیر HRNet و ViTPose) بالاترین دقت را دارند؛ درحالیکه مدلهای پایین به بالا (مانند OpenPose و HigherHRNet) بالاترین گذردهی (throughput) را در صحنههای شلوغ ارائه میدهند.
رگرسیون نقشه حرارتی
به جای رگرسیون مستقیم (x, y)، برای هر نقطه کلیدی یک نقشه حرارتی در ابعاد H x W با یک حباب گاوسی متمرکز بر موقعیت واقعی پیشبینی کنید.
در زمان استنتاج، نقطه بیشینه (argmax) هر نقشه حرارتی، همان موقعیت پیشبینیشدهی نقطه کلیدی است.
چرا نقشههای حرارتی بهتر از رگرسیون مستقیم عمل میکنند؟ ساختار فضایی شبکه (نقشه ویژگیهای کانولوشنی) بهطور طبیعی با خروجی فضایی همراستاست. علاوهبر این، اهداف گاوسی نوعی منظمسازی ایجاد میکنند؛ خطای مکانی کوچک باعث تولید تابعی از زیان ناچیز میشود، نه صفر.
مکانیابی با دقت زیرپیکسل
دستور argmax مختصات صحیح و بدون اعشار میدهد. برای رسیدن به دقت (precision) در سطح زیرپیکسل (sub-pixel)، موقعیت را با برازش یک سهمی روی نقطه بیشینه و همسایگانش بهبود دهید؛ یا مانند کد این درس، نقطه بیشینه را با رابطهی dx = 0.25 * (heatmap[y, x+1] - heatmap[y, x-1]) و فرمولی مشابه برای dy، به سمت همسایهی با مقدار بیشتر بلغزانید.
میدانهای پیوستگی اندامها (PAFs)
شگرد OpenPose برای اتصال پایین به بالا همین است. برای هر جفت نقطه کلیدی متصلبههم (مثلاً از شانهی چپ به آرنج چپ)، یک میدان 2 کاناله پیشبینی میشود که بردار واحد جهتگیری بین آنها را مشخص میکند. برای اتصال شانه به آرنج متناظرش، انتگرال خطی 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 (درصد نقاط کلیدی درست) و OKS (شباهت نقاط کلیدی شیء). معیار OKS معادل IoU برای نقاط کلیدی است و خروجی گزارششده در COCO mAP@OKS به حساب میآید.
مقایسه ژست 2 بعدی و 3 بعدی
- ژست 2 بعدی — مختصات تصویر؛ با کیفیت آماده برای محیط عملیاتی حل شده است (MediaPipe، HRNet، ViTPose).
- ژست 3 بعدی — مختصات دنیای واقعی یا دوربین؛ هنوز حوزهای با پژوهشهای فعال است. رویکردهای رایج:
- ارتقای پیشبینیهای 2 بعدی به 3 بعدی با یک پرسپترون چندلایه (MLP) کوچک (VideoPose3D).
- رگرسیون مستقیم 3 بعدی از روی تصویر (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) است. تابع زیان (loss) نیز 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)
# بزرگنمایی pred به رزولوشن کامل
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 — مدل تخمین ژست عملیاتی گوگل؛ ارائهشده با محیطهای اجرای (runtimes) تحت وب (WebGL) و موبایل با تأخیر کمتر از 10 میلیثانیه.
- MMPose (از OpenMMLab) — پایگاه کد جامع پژوهشی؛ شامل همهی معماریهای پیشرفته با وزنهای ازپیشآموزشدیده.
- YOLOv8-pose — سریعترین گزینه برای تخمین ژست چند نفر بهصورت بلادرنگ تنها با یک گذر رو به جلو.
- transformers HumanDPT / PoseAnything — رویکردهای نوین بینایی-زبانی برای ژستهایی با دایره واژگان باز (هر نوع شیء با هر مجموعهای از نقاط کلیدی).
انتشار در محیط عملیاتی
از این درس خروجیهای زیر به دست میآید:
- فایل
outputs/prompt-pose-stack-picker.md— پرامپتی که با توجه به تأخیر، تعداد افراد و نیاز به حالت 2 بعدی یا 3 بعدی، گزینهی مناسب را از میان MediaPipe ،YOLOv8-pose ،HRNet یا ViTPose انتخاب میکند. - فایل
outputs/skill-heatmap-to-coords.md— مهارتی که روتین تبدیل نقشه حرارتی به مختصات با دقت زیرپیکسل را پیاده میکند؛ همان کدی که در تمام مدلهای عملیاتی ژست به کار میرود.
تمرینها
- (ساده) مدل کوچک نقاط کلیدی را روی مجموعه داده ساختگی 4 نقطهای آموزش دهید. پس از 200 گام، میانگین خطای L2 میان نقاط پیشبینیشده و واقعی را گزارش کنید.
- (متوسط) اصلاح موقعیت زیرپیکسل را پیاده کنید: بر اساس موقعیت argmax، یک سهمی 1 بعدی در امتداد x و y روی پیکسلهای همسایه برازش دهید. میزان بهبود دقت را در مقایسه با argmax با مقادیر صحیح گزارش کنید.
- (سخت) یک مجموعه داده ساختگی دونفره بسازید که در هر تصویر دو نمونه از الگوی 4 نقطهای وجود داشته باشد. سپس یک پایپلاین پایین به بالا همراه با PAFها آموزش دهید تا مشخص کند هر نقطه کلیدی متعلق به کدام نمونه است، و در نهایت OKS را بسنجید.
اصطلاحات کلیدی
| اصطلاح | در گفتار روزمره | معنای واقعی و دقیق |
|---|---|---|
| Keypoint (نقطه کلیدی) | «یک لندمارک» | نقطهای خاص و مرتب روی یک شیء (مفصل، گوشه، ویژگی ظاهری) |
| Pose (ژست) | «اسکلت» | مجموعهای مرتب از نقاط کلیدی متعلق به یک نمونه |
| Top-down (بالا به پایین) | «اول شناسایی کن، بعد ژست بگیر» | پایپلاین دومرحلهای: آشکارساز فرد + مدل نقاط کلیدی برای هر برش؛ بالاترین دقت |
| Bottom-up (پایین به بالا) | «اول نقاط را پیدا کن، بعد گروهبندی کن» | پیشبینی همهی نقاط در یک گذر + گروهبندی؛ زمان اجرا مستقل از تعداد جمعیت |
| Heatmap (نقشه حرارتی) | «هدف گاوسی» | تنسور H x W بهازای هر نقطه کلیدی با قلهای در موقعیت واقعی؛ هدف ایدهآل رگرسیون |
| PAF | «میدان پیوستگی اندامها» | میدان بردار واحد 2 کاناله که جهت اندامها را کدگذاری میکند؛ برای گروهبندی نقاط کلیدی در نمونهها |
| OKS | «مشابه IoU برای نقاط کلیدی» | معیار سنجش شباهت نقاط کلیدی شیء (Object Keypoint Similarity)؛ معیار استاندارد COCO برای ارزیابی ژست |
| HRNet | «شبکه با تفکیکپذیری بالا» | معماری مرجع و مسلط بالا به پایین؛ حفظ ویژگیهای با رزولوشن بالا در سراسر شبکه |
مطالعهی بیشتر
- OpenPose (Cao et al., 2017) — روش پایین به بالا با PAFها؛ هنوز هم بهترین متن برای درک این رویکرد است
- HRNet (Sun et al., 2019) — معماری مرجع بالا به پایین
- ViTPose (Xu et al., 2022) — استفاده از ViT ساده بهعنوان ستون فقرات تخمین ژست؛ برترین عملکرد فعلی در بنچمارکهای متعدد
- MediaPipe Pose — سیستم عملیاتی بلادرنگ تخمین ژست؛ سریعترین پشتهی مستقرشده در سال 2026
