Ebook Robotics · RL–UAV
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)
Chế độ Slide · phím ← → · F toàn màn · Esc về đọc · S mở slide
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)
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)
| # | 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 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.
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.
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.
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.
\[ \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 |
"""
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,ugầ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).
| 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 |
| ✅ 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 |
⚡ 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