Lecture 18 — Optical Flow

Chương D** · tín hiệu chuyển động trên ảnh — “cây gần xẹt nhanh” (Lab 3 khóa gốc)

Lecture 18 — Optical Flow

Chương D · tín hiệu chuyển động trên ảnh — “cây gần xẹt nhanh” (Lab 3 khóa gốc)


Khung 6 câu hỏi

# Câu hỏi Trả lời ngắn
1 Tại sao cần? Cần cảm nhận “sắp đụng / đang trôi” từ camera trước khi (hoặc thay) depth/CNN nặng.
2 So với cái khác? Vs stereo/depth net: nhẹ, cổ điển, interpret được. Vs end-to-end RL ảnh: đặc trưng có cấu trúc, sample-efficient hơn khi onboard yếu.
3 Giải quyết gì & thế nào? Brightness constancy → PT flow; aperture problem; LK giả định hằng cục bộ; divergence ~ \(1/\tau\) (TTC).
4 Kết quả ra sao? Vector field / TTC → tránh vật cản, odometry thô, hoặc feature cho policy / reward.
5 Nên dùng khi nào? Onboard yếu; cần inductive bias tránh đụng; prototype nhanh trước CNN.
6 Không nên khi nào? Ánh sáng nhấp / blur mạnh; cần ngữ nghĩa vật (dùng detect/CNN); coi flow = odometry tuyệt đối.

🖼️ Hình nhanh: Cường độ “đi theo” vật — một PT, hai ẩn; tường bung ra = sắp đụng.
```
Brightness constancy Aperture (nhìn lỗ nhỏ)
I(x,y,t) ≈ I(x+u,y+v,t+1) ┌───┐
⇒ Ix·u + Iy·v + It = 0 │███│ cạnh dọc: chỉ biết u⊥
└── 1 PT, 2 ẩn (u,v) │███│ không biết trượt dọc cạnh
└───┘

t t+Δt divergence ↑ → τ = Z/Ż nhỏ
░░██░░ → ░██░░░ ★ phanh / né trước khi đụng
```

🇻🇳 Chuyện thật (sân B/D): Lùa vào hẻm Hà Nội hoặc bay sát tường nhà sau bão — texture bung ra trên ảnh chính là divergence tăng: \(\tau\) (time-to-contact) đang nhỏ lại.
Chưa cần CNN biết “đó là tường”; flow đã thì thầm “sắp đụng — phanh / né”.
Chốt: optical flow = tín hiệu an toàn nhẹ onboard khi GPS kém và depth còn xa xỉ. ../00C.

Hình minh họa (seminar-ready)

Hình gốc hoặc minh họa cho ebook — không cắt từ slide Princeton. Dùng Present: bật Slide · F toàn màn.

Flow bung ra · time-to-contact.
Flow bung ra · time-to-contact.HiếuTC · gốc
Lùa hẻm: divergence tăng.
Lùa hẻm: divergence tăng.Generated for ebook · seminar OK

0. Mục tiêu học

  1. Viết và giải thích phương trình brightness constancy.
  2. Nêu aperture problem và vì sao Lucas–Kanade cần cửa sổ.
  3. Liên hệ divergence của flow với time-to-contact \(\tau\).
  4. Biết chỗ đặt flow trong stack RL–UAV: feature / reward shaping / an toàn nhẹ — không phải “pose tuyệt đối”.

1. Trực giác

Ngồi tàu nhìn cửa sổ: cây gần xẹt rất nhanh, núi xa trôi chậm. Não dùng tốc độ trôi trên võng mạc để đoán khoảng cách và tốc độ tiếp cận.

Drone cũng có thể dùng optical flow để cảm nhận “tường phía trước đang lớn dần” — tức sắp đụng — trước khi có depth map đẹp. Bay khảo sát gần tán chè hoặc cột điện: flow bung phía trước là tín hiệu khẩn cấp rẻ hơn chạy YOLO mỗi frame.

Optical flow không trả lời “đó là ống PVC hay người”. Nó trả lời “pixel đang trôi đi đâu, nhanh bao nhiêu”. Ngữ nghĩa để dành Lec 19.


2. Cốt lõi + sơ đồ

2.1. Brightness constancy

Giả định cường độ sáng bảo toàn theo chuyển động nhỏ:

\[ I(x,y,t) \approx I(x+u\Delta t,\ y+v\Delta t,\ t+\Delta t) \]

Tuyển tính hóa bậc nhất:

\[ I_x u + I_y v + I_t = 0 \]

Một phương trình cho hai ẩn \((u,v)\) → aperture problem.

2.2. Lucas–Kanade (ý tưởng)

Giả định flow gần như không đổi trong cửa sổ \(W\) quanh điểm đang xét → xếp chồng nhiều phương trình → giải bình phương tối thiểu:

\[ \min_{u,v}\ \sum_{(x,y)\in W}\big(I_x u + I_y v + I_t\big)^2 \]

Cần texture (gradient đủ lớn). Vùng trời / tán chè đồng nhất → flow không đáng tin.

2.3. Time-to-contact

\[ \tau \approx \frac{Z}{\dot{Z}} \propto \frac{1}{\mathrm{divergence}(\text{flow})} \]

Flow phía trước “bung ra” mạnh → \(\tau\) nhỏ → cần phanh hoặc né.

camera ──► I_t, I_{t+1}
              │
              ▼
        [LK / dense flow]
              │
              ├─► vector field (u,v) ──► VO thô / feature RL
              └─► divergence phía trước ──► τ̂ ──► tránh / giảm tốc
Tín hiệu Ý nghĩa vật lý (xấp xỉ) Dùng cho
Flow lớn gần cạnh khung Cảnh trôi nhanh (thường gần) Ổn định ngang / hover thô
Divergence phía trước ↑ Đang lao vào bề mặt TTC, phanh
Flow nhiễu / outlier Ánh sáng đổi, vùng phẳng Đừng tin tuyệt đối

3. Demo — ước lượng flow 1D bằng gradient

"""
Demo Lec18: brightness constancy 1D.
Tín hiệu dịch phải ~1 mẫu → nơi có cạnh, u ≈ +1.
Vùng phẳng (Ix≈0) bị che — đó là phiên bản 1D của aperture/không texture.
"""
import numpy as np

I0 = np.array([0, 0, 1, 2, 3, 2, 1, 0, 0], dtype=float)
I1 = np.array([0, 0, 0, 1, 2, 3, 2, 1, 0], dtype=float)  # dịch +1 mẫu

Ix = 0.5 * (I0[2:] - I0[:-2])       # đạo hàm không gian
It = I1[1:-1] - I0[1:-1]            # đạo hàm thời gian

u = np.zeros_like(Ix)
mask = np.abs(Ix) > 0.3             # tránh chia vùng phẳng
u[mask] = -It[mask] / Ix[mask]      # Ix*u + It ≈ 0

print("Ix:", np.round(Ix, 2))
print("It:", np.round(It, 2))
print("flow u:", np.round(u, 2))

# Proxy TTC 1D: "bung" = |du/dx| lớn → τ nhỏ
du = np.diff(u)
print("|du| (proxy divergence):", np.round(np.abs(du), 2))
print("→ Cạnh dịch phải: u~+1; vùng phẳng: u=0 (không ước lượng).")

🧪 Kỳ vọng demo:
- Ở chỗ có cạnh, u gần +1 (cùng hướng dịch tín hiệu).
- Vùng phẳng bị mask → u=0.
- |du| lớn nơi flow đổi mạnh — minh họa tinh thần divergence / TTC (không phải công thức bay thật).


4. Gắn RL–UAV

  • Flow / proxy chiều sâu là đặc trưng cổ điển trước khi nhảy sang end-to-end pixel→action.
  • Reward có thể phạt divergence cao phía trước — inductive bias tránh va chạm, sample-efficient hơn phạt đụng nhị phân muộn.
  • Hữu ích khi onboard không chạy nổi mạng nặng theo thời gian thực.
  • Bay gần tán chè: texture lá tốt cho LK hơn bầu trời đồng nhất — nhưng gió lay lá tạo flow giả → cần lọc / ngưỡng.
Cách dùng flow ✅ Khi nào ❌ Khi nào
Feature nối policy Cần tránh đụng nhẹ, companion yếu Cần nhận “loại vật”
Reward shaping (\(-\lambda/\tau\)) Tín hiệu thưa “đụng = −1” Flow quá nhiễu → reward độc
Thay VIO Không bao giờ một mình Cần loop closure / bias ước lượng

5. Ưu / nhược

✅ Nên ❌ Không nên
Optical flow Tín hiệu chuyển động rẻ, realtime Coi là pose tuyệt đối / odometry dài hạn
Lucas–Kanade Texture cục bộ, chuyển động nhỏ Motion lớn giữa 2 frame, blur mạnh
TTC từ divergence Cảnh báo va chạm sớm Tin số \(\tau\) tuyệt đối khi camera xoay mạnh
Nghĩa năng lượng / gió / phủ Né sớm → ít manoeuvre gấp → mượt hơn Gió lay cảnh → flow giả → phanh oan tốn pin

6. Lỗi thường gặp

  1. Quên giả định chuyển động nhỏ / độ sáng không đổi (nhấp nháy, bóng đổ → flow giả).
  2. Dùng flow làm “odometry chính xác tuyệt đối” — thực tế có drift và outlier.
  3. Nhầm optical flow (2D trên ảnh) với scene flow 3D.
  4. Không mask vùng gradient yếu rồi tin mọi mũi tên trên sky.
  5. Đưa flow thô vào RL không chuẩn hóa → scale đổi theo tốc độ bay / độ cao (nối Lec 17: \(h\) đổi → độ lớn flow đổi).

7. Checklist

  1. Aperture problem là gì? Một câu + một hình lỗ nhỏ.
  2. Lucas–Kanade thêm giả định nào để giải được \((u,v)\)?
  3. Time-to-contact liên hệ thế nào với divergence?
  4. Bạn sẽ dùng flow làm obs, reward, hay cả hai — vì sao?
  5. Điều kiện ánh sáng / texture nào làm flow gãy trên đồi chè?

Nhớ một câu: Một PT sáng → hai ẩn flow; tường bung ra = \(\tau\) nhỏ — tín hiệu tránh đụng rẻ nhất từ camera.

🔗 Sang bài sau mang theo: Flow biết “đang trôi”, chưa biết “đó là gì” → Lec 19 học detection và đóng vòng visual servoing.


Trước: Lec17 — Intro Vision · Sau: Lec19 — Deep Learning Vision