چیت‌شیت

ویدیو، عمق و بینایی سه‌بعدی

Video, Depth and 3D Vision

نمونه‌برداری فریم‌ها، مدل‌سازی زمان، رندر NeRF و Gaussian splat، پیش‌بینی عمق و ردگیری اشیاء بین فریم‌ها.

  • ۱۲ بخش
  • ۶ درس مرتبط
  • کد و دستورها عیناً از دوره‌ی اصلی
فهرست مطالب
  1. مدل‌های ویدیو
  2. انتخاب مدل سه‌بعدی، عمق یا ردگیری
  3. ردگیری مبتنی بر آشکارسازی
  4. فرمول‌ها
  5. فریم‌ها، بسط و (2+1)D
  6. رندر یک پرتو NeRF
  7. معیارهای عمق و بالا کشیدن
  8. انتساب مجارستانی و IoU
  9. دستورات و خروجی‌ها
  10. پیش‌فرض‌ها و اعداد
  11. عیب‌یابی
  12. پرسش‌ها

مدل‌های ویدیو

مفهوم‌ها
2D + pool
اعمال CNN روی هر فریم، میانگین‌گیری روی زمان.
3D conv
کرنل‌های (T, H, W). مدل‌سازی حرکت.
I3D
بسط کرنل‌های 2D در طول زمان.
(2+1)D
کانولوشن 2D مکانی، سپس 1D زمانی.
Divided
اتنشن روی زمان، سپس مکان.
Uniform
انتخاب یکنواخت T فریم. پیش‌فرض 2D+pool.
Dense
پنجره پیوسته در حافظه و تصادفی. مناسب 3D conv.
Clip / video acc
دقت یک کلیپ یا میانگین کلیپ‌ها.

انتخاب مدل سه‌بعدی، عمق یا ردگیری

مفهوم‌ها
NeRF
صحنه یک MLP است. ساعت‌ها زمان آموزش.
3DGS
گوسی‌های صریح. دقیقه‌ها زمان آموزش.
Depth Anything V3
عمق نسبی، با DINOv2 فریز شده.
ZoeDepth
متریک. حساس به پارامترهای ذاتی دوربین.
Marigold
عمق مبتنی بر دیفیوژن. 10 تا 50 گام.
ByteTrack
خودروها و افراد با بیش از 30 fps.
DeepSORT
پوشیدگی شدید، با ویژگی‌های ReID.
SAM 3.1 Multiplex
ازدحام‌های تک‌کلاسی.

ردگیری مبتنی بر آشکارسازی

معماری
آشکارسازی‌هاباکس‌های پیش‌بینی‌شدهتطبیق‌یافتهآشکارسازی‌های بدون تطبیقتراک‌های بدون تطبیقفریم tورودی ویدیوآشکارسازآشکارسازی‌ها در tانتساب مجارستانیIoU، کسینوسی، حرکتبه‌روزرسانیتراک‌های تطبیق‌یافتهتراک‌ها تا t-1پیش‌بینی کالمنسرعت ثابتتولدتراک‌های جدیدافزایش سن نامنطبق‌هاحذف پس از N گام

فرمول‌ها

مفهوم‌ها
PointNet
فرمول $f(P) = \max_{p \in P} \mathrm{MLP}(p)$. ترتیب نقاط تغییری در آن ایجاد نمی‌کند.
کدگذاری مکانی
$\sin(2^l \pi p), \cos(2^l \pi p)$ تا $L = 10$ سطح.
رندر حجم
$C = \sum_i T_i (1 - e^{-\sigma_i \delta_i}) c_i$ با $T_i = e^{-\sum_{j<i} \sigma_j \delta_j}$
شکل 3DGS
ماتریس $\Sigma = R S S^T R^T$. روی تصویر: $\Sigma' = J W \Sigma W^T J^T$.
پیکسل 3DGS
فرمول $C = \sum_i \alpha_i T_i c_i$ با $T_i = \prod_{j<i} (1 - \alpha_j)$
بالا کشیدن پین‌هول
$X = (u - c_x) d / f_x$ و $Y = (v - c_y) d / f_y$ و $Z = d$
AbsRel
میانگین $|d_{pred} - d_{gt}| / d_{gt}$. کمتر بهتر است.
MOTA
فرمول $1 - (FN + FP + \mathrm{IDSW}) / GT$

فریم‌ها، بسط و (2+1)D

کد
python
idx = sample_uniform(num_frames_total, T)         # توزیع یکنواخت
idx = sample_dense(num_frames_total, T)           # پنجره پیوسته در حافظه
model = FramePool(num_classes=10)                 # اعمال ResNet-18 روی هر فریم، میانگین روی T
x = torch.randn(2, 8, 3, 224, 224)                 # (N, T, 3, H, W)
conv2d = nn.Conv2d(3, 64, kernel_size=3, padding=1, bias=False)
conv3d = inflate_2d_to_3d(conv2d, time_kernel=3)  # تکرار در زمان، تقسیم بر 3
c = Conv2Plus1D(3, 64)                            # مکانی، سپس زمانی
c(torch.randn(1, 3, 8, 56, 56))                   # ورودی سه‌بعدی یکسان با conv3d

رندر یک پرتو NeRF

کد
python
y = positional_encoding(x, L=10)                      # (5, 3) به (5, 60)
t_vals = torch.linspace(2.0, 6.0, N)                  # N = 64 نمونه روی پرتو
delta = torch.cat([t_vals[1:] - t_vals[:-1], torch.full_like(t_vals[:1], 1e10)])
alpha = 1.0 - torch.exp(-sigma * delta)               # کدر بودن هر نمونه
trans = torch.cumprod(torch.cat([torch.ones_like(alpha[..., :1]), 1.0 - alpha + 1e-10], dim=-1), dim=-1)[..., :-1]
weights = alpha * trans                               # ضریب عبور ضرب‌در کدر بودن
rendered = (weights.unsqueeze(-1) * rgb).sum(dim=-2)  # رنگ پیکسل
depth = (weights * t_vals).sum(dim=-1)                # عمق در طول پرتو

معیارهای عمق و بالا کشیدن

کد
python
aligned = align_scale_shift(pred, gt)         # برازش a * pred + b برای عمق نسبی
abs_rel_error(aligned, gt)                    # 0.05 تا 0.1 برای مدل‌های محیط عملیاتی
delta_accuracy(pred, target, threshold=1.25)  # +0.9 برای مدل‌های پیشرو (SOTA)
intr = (320.0, 320.0, 160.0, 120.0)           # fx, fy, cx, cy
pc = depth_to_point_cloud(depth, intr)             # (H, W, 3)
pipe = pipeline(task="depth-estimation", model="depth-anything/Depth-Anything-V2-Large-hf")
out = pipe(image)
depth_np = np.array(out["depth"])             # تبدیل تصویر خاکستری PIL به numpy

انتساب مجارستانی و IoU

کد
python
iou = bbox_iou(track_boxes, det_boxes)  # (تراک‌ها، آشکارسازی‌ها)
cost = 1 - iou
cost[iou < self.iou_threshold] = 1e6    # مسدود کردن تطبیق‌های ضعیف
row, col = linear_sum_assignment(cost)  # کمینه هزینه کل
for r, c in zip(row, col):
    if cost[r, c] < 1.0:
        self.tracks[r].update(det_boxes[c], frame)
self.tracks = [t for t in self.tracks if frame - t.last_frame <= self.max_age]
tracker = SimpleTracker()               # iou_threshold=0.3, max_age=5
tracks = tracker.step(dets, f)          # لیستی از (id, bbox)

دستورات و خروجی‌ها

دستورها
دستورکاربرد
pip install nerfstudio gsplatنصب ابزارهای 3DGS
ns-download-data exampleدریافت یک دیتاست نمونه
ns-train splatfacto --data path/to/dataآموزش 3DGS، بین 10 تا 30 دقیقه روی RTX 4090
.plyابر گوسی خام. قابل‌حمل، بزرگ‌ترین فایل
.splatفرمت کوانتیزه‌شده
KHR_gaussian_splattingاستاندارد glTF میان نمایشگرها
UsdVolParticleField3DGaussianSplatاسکیمای OpenUSD
model.track(source, tracker="bytetrack.yaml")اجرای YOLOv8 همراه با ByteTrack

پیش‌فرض‌ها و اعداد

پیش‌فرض‌ها
تنظیمپیش‌فرضتوضیحات
Frames per clip T8, 16, 32, or 64T بیشتر یعنی سیگنال و محاسبات بیشتر
time_kernel3وزن‌های بسط‌یافته بر آن تقسیم می‌شوند
NeRF `L`10جهت از L_dir=4 استفاده می‌کند
Samples per ray64t بین 2.0 تا 6.0
SH degree316 ضریب برای هر کانال، 48 عدد ممیز شناور
3DGS iterations~30,000افزایش گوسی‌ها از حدود 100 هزار به 1 تا 5 میلیون
Tracker `iou_threshold`0.3با max_age=5
Delta threshold1.25کسر پیکسل‌ها در بازه خطای 25٪

عیب‌یابی

عیب‌یابی
  • «باز کردن در» معادل «بستن در» است

    علت
    تجمیع زمانی نسبت به ترتیب پایا است
    راه‌حل
    استفاده از 3D conv یا (2+1)D
  • خرابی BN پس از بسط وزن‌ها

    علت
    وزن‌ها مقیاس‌بندی نشده‌اند
    راه‌حل
    تقسیم بر time_kernel
  • تصویر NeRF تار به نظر می‌رسد

    علت
    نبود کدگذاری مکانی
    راه‌حل
    افزودن ویژگی‌های فوریه
  • ترتیب درست، اما متراژ نادرست

    علت
    مدل تخمین عمق نسبی است
    راه‌حل
    استفاده از مدل متریک به همراه پارامترهای ذاتی
  • عمق نادرست روی شیشه و آینه‌ها

    علت
    سطوح بازتابنده
    راه‌حل
    عدم اتکا به این پیکسل‌ها
  • مقدار AbsRel بالا روی خروجی MiDaS

    علت
    تراز نبودن مقیاس و جابه‌جایی
    راه‌حل
    اجرای اولیه‌ی align_scale_shift
  • تعویض شناسه در شلوغی و تراکم

    علت
    انتساب صرفاً با IoU
    راه‌حل
    پاس دوم ByteTrack یا استفاده از ReID
  • گم شدن تراک در پوشیدگی‌های کوتاه

    علت
    نبود مدل حرکتی
    راه‌حل
    افزودن گام پیش‌بینی کالمن

پرسش‌ها

پرسش و پاسخ
چرا کیفیت 3DGS با NeRF برابری می‌کند؟
هر دو از یک معادله‌ی ترکیب‌بندی استفاده می‌کنند.
چرا با 2D + pool شروع کنیم؟
وزن‌های ImageNet را بازاستفاده می‌کند و اغلب اختلافی کمتر از 5 تا 10 امتیاز دارد.
کدام معیار ردگیری مناسب است؟
IDF1 برای حفظ هویت؛ HOTA برای تحلیل‌های ورزشی و مقایسه‌ها.
یک تصویر تک قادر به ارائه چه چیزی نیست؟
مقیاس مطلق بدون پارامترهای ذاتی دوربین، و هندسه نواحی پوشیده.
چرا باکس‌های با اطمینان پایین را نگه داریم؟
ByteTrack آن‌ها را در پاس دوم تطبیق می‌دهد و پوشیدگی‌های کوتاه بازیابی می‌شوند.