Optical Flow
Luồng quang học ước tính chuyển động của từng pixel giữa hai khung hình video dưới dạng trường vector chuyển động. Tìm hiểu các phương pháp cổ điển và deep learning, ứng dụng và mã nguồn OpenCV.
Luồng quang học là chuyển động biểu kiến của các mẫu độ sáng giữa hai hình ảnh, thường là các khung hình video liên tiếp. Thuật toán luồng quang học ước tính cho mỗi pixel trong khung hình đầu tiên một vector dịch chuyển 2D (dx, dy) chỉ vị trí mà nội dung của pixel đó xuất hiện trong khung hình thứ hai. Kết quả này, được gọi là trường luồng, ghi nhận chuyển động của các vật thể đang di chuyển và của chính camera, cho phép các hệ thống thị giác máy tính ổn định video, ước tính chuyển động tự thân, nội suy khung hình và nhận diện hành động. Luồng đo những gì camera nhìn thấy chứ không phải chuyển động 3D thực: một quả cầu đồng nhất hoàn hảo quay tại chỗ không tạo ra luồng, còn bóng đang di chuyển tạo ra luồng dù không có vật thể thực nào chuyển động.
Cách ước tính luồng quang học#
Hầu hết phương pháp bắt đầu từ giả định độ sáng không đổi: một điểm giữ nguyên cường độ khi di chuyển. Tuyến tính hóa giả định này cho ta một phương trình trên mỗi pixel, Ix·u + Iy·v + It = 0, trong đó Ix, Iy và It là các đạo hàm của hình ảnh theo x, y và thời gian, còn (u, v) là luồng chưa biết. Một phương trình không thể xác định hai ẩn; đây là bài toán khẩu độ: khi nhìn một cạnh thẳng qua một cửa sổ nhỏ, chỉ đo được chuyển động vuông góc với cạnh. Các phương pháp cổ điển bổ sung giả định thứ hai để giải quyết vấn đề này:
- Phương pháp Lucas-Kanade (1981): Giả định luồng không đổi trong một cửa sổ nhỏ và giải các phương trình của mọi pixel trong cửa sổ bằng bình phương tối thiểu. Phương pháp này hoạt động tại những vị trí cửa sổ chứa gradient theo hai hướng, chẳng hạn như góc, nên thường được chạy dưới dạng luồng thưa trên các điểm đặc trưng được chọn.
- Phương pháp Horn-Schunck (1981): Giả định trường luồng trơn trên toàn bộ hình ảnh và giải bài toán tối ưu hóa toàn cục, tạo ra luồng dày đặc cho mọi pixel.
Cả hai giả định đều không còn đúng với chuyển động lớn, vì vậy các phương pháp thực tế ước tính luồng từ thô đến mịn trên tháp ảnh, trong đó chuyển động 16 pixel ở độ phân giải đầy đủ tương đương chuyển động 2 pixel khi xuống ba mức:
OpenCV triển khai Lucas-Kanade dạng tháp cho các điểm thưa và thuật toán khai triển đa thức năm 2003 của Gunnar Farnebäck cho luồng dày đặc. Đoạn mã này dịch chuyển một texture ngẫu nhiên một lượng đã biết rồi khôi phục chuyển động bằng luồng Farnebäck dày đặc:
import cv2
import numpy as np
# A smooth random texture, then the same texture moved 3 px right and 2 px down
rng = np.random.default_rng(0)
texture = cv2.GaussianBlur(rng.random((240, 320)), (0, 0), 3)
frame1 = cv2.normalize(texture, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
frame2 = np.roll(frame1, shift=(2, 3), axis=(0, 1))
# Dense Farneback optical flow: one (dx, dy) displacement vector for every pixel
flow = cv2.calcOpticalFlowFarneback(
frame1, frame2, None, pyr_scale=0.5, levels=3, winsize=15, iterations=3, poly_n=5, poly_sigma=1.2, flags=0
)
print(f"flow field shape: {flow.shape}")
print(f"median motion: dx={np.median(flow[..., 0]):.2f}, dy={np.median(flow[..., 1]):.2f} pixels")Đoạn mã in ra flow field shape: (240, 320, 2) và median motion: dx=3.00, dy=2.00 pixels: một vector gồm hai thành phần cho mỗi trong số 76.800 pixel, khôi phục độ dịch chuyển 3 pixel theo chiều ngang và 2 pixel theo chiều dọc.
Các phương pháp học sâu#
Năm 2015, FlowNet cho thấy mạng nơ-ron tích chập có thể học luồng từ đầu đến cuối bằng dữ liệu huấn luyện tổng hợp, vì video thực tế hiếm khi có luồng ground truth. PWC-Net tích hợp các ý tưởng về tháp ảnh, biến dạng và thể tích chi phí của những phương pháp cổ điển vào một mạng gọn nhẹ. RAFT, mô hình đoạt giải bài báo xuất sắc nhất tại ECCV 2020, so sánh mọi pixel của khung hình đầu tiên với mọi pixel của khung hình thứ hai trong một thể tích tương quan, rồi tinh chỉnh một trường luồng độ phân giải cao duy nhất bằng các cập nhật hồi quy lặp đi lặp lại. Các phương pháp học được xử lý độ dịch chuyển lớn, nhòe chuyển động và vùng không có texture tốt hơn nhiều so với phương pháp cổ điển, và torchvision cung cấp các model RAFT đã huấn luyện trước. Độ chính xác được báo cáo bằng sai số điểm cuối (EPE), tức khoảng cách trung bình tính bằng pixel giữa vector luồng dự đoán và thực tế, trên các benchmark như MPI Sintel và KITTI 2015.
Luồng quang học và các thuật ngữ liên quan#
- Theo dõi vật thể: Theo dõi toàn bộ vật thể với ID ổn định qua nhiều khung hình, trong khi luồng quang học mô tả chuyển động từng pixel giữa hai khung hình và không nhận biết vật thể. Bộ theo dõi sử dụng luồng làm tín hiệu: trong chế độ theo dõi của Ultralytics YOLO, bộ theo dõi TrackTrack mặc định và BoT-SORT ước tính chuyển động camera bằng luồng Lucas-Kanade thưa (
gmc_method: sparseOptFlow), theo dõi tối đa 400 góc trong khung hình có một nửa độ phân giải, khớp phép quay, tỷ lệ và phép tịnh tiến với các góc đó bằng RANSAC, rồi dịch chuyển mọi bounding box theo dõi đã dự đoán theo chuyển động đó trước khi ghép với các phát hiện mới. - Theo dõi điểm: Theo dõi các điểm được chọn xuyên suốt video dài, kể cả khi bị che khuất, thay vì ước tính chuyển động cho mọi pixel giữa hai khung hình.
- Luồng cảnh: Chuyển động 3D của các điểm trong không gian, được ước tính từ dữ liệu stereo hoặc độ sâu. Luồng quang học là hình chiếu của chuyển động đó lên mặt phẳng ảnh.
- Vector chuyển động của codec video: Bộ mã hóa H.264, HEVC và AV1 lưu một vector chuyển động cho mỗi khối, được chọn để giảm số bit cần thiết nhằm mã hóa khung hình, vì vậy vector thường không phản ánh đúng chuyển động thực.
Ứng dụng thực tế#
- Ổn định video: Luồng chủ đạo trên một khung hình cho biết độ rung của camera; phần mềm khử rung bằng cách biến dạng từng khung hình theo hướng ngược lại.
- Nội suy khung hình: Chuyển động chậm và chuyển đổi tốc độ khung hình tạo các khung hình trung gian bằng cách dịch chuyển pixel một phần theo các vector luồng của chúng.
- Xe tự hành và drone: Luồng hỗ trợ odometry thị giác, và tốc độ mở rộng của luồng từ một vật thể cảnh báo nguy cơ va chạm đang đến gần.
- Nhận diện hành động: Mạng hai luồng năm 2014 phân loại hành động từ một luồng không gian gồm các khung hình đơn lẻ và một luồng thời gian nhận đầu vào là một chồng gồm 10 trường luồng quang học liên tiếp.










