Python | OpenCV 光流分析 (Optical Flow)
📚 前言
在前一篇我們學會了 即時圖片中的物件追蹤。
這一篇要介紹 光流分析 (Optical Flow),它是一種用來估計圖片中物件移動的方法。
光流分析常用於運動偵測、物件追蹤、影片穩定化等場景。
🎨 範例影片
這裡我們使用 Pexels 提供的免費影片素材:Tennis Video。
下載後將檔名改為 tennis.mp4,在程式碼範例中使用。這段影片中有明顯的移動物件,非常適合用來測試追蹤演算法。
🔎 原理說明
- 光流 (Optical Flow):描述圖片中像素隨時間的移動。
- 兩種常用方法:
- Lucas-Kanade Optical Flow:追蹤特徵點的移動,適合少量特徵點。
- Dense Optical Flow (Farneback):計算整張圖片的光流,適合分析整體運動。
🧠 函式與參數說明
📌 cv2.goodFeaturesToTrack()
用途:偵測圖片中的角點 (特徵點)。
1 | p0 = cv2.goodFeaturesToTrack(old_gray, maxCorners=100, qualityLevel=0.3, minDistance=7) |
- maxCorners:最多偵測多少角點。
- qualityLevel:角點品質閾值。
- minDistance:角點之間的最小距離。
📌 cv2.calcOpticalFlowPyrLK()
用途:計算 Lucas-Kanade 光流,追蹤特徵點移動。
1 | p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None) |
- old_gray:前一幀圖片 (灰階)。
- frame_gray:當前圖片 (灰階)。
- p0:前一幀的特徵點。
- p1:計算後的新位置。
- st:追蹤狀態 (1=成功, 0=失敗)。
- err:誤差值。
📌 cv2.calcOpticalFlowFarneback()
用途:計算 Dense Optical Flow,分析整張圖片的運動。
1 | flow = cv2.calcOpticalFlowFarneback(prvs, next, None, |
- prvs:前一幀圖片 (灰階)。
- next:當前圖片 (灰階)。
- 其他參數:控制金字塔層數、窗口大小、迭代次數等。
📌 cv2.cartToPolar()
用途:將光流的水平與垂直分量轉換為角度與大小。
1 | mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1]) |
- mag:光流大小 (速度)。
- ang:光流方向 (角度)。
💻 範例程式 — Lucas-Kanade Optical Flow
1 | import cv2 |

圖:Lucas-Kanade 光流分析,顯示特徵點的移動軌跡
💻 範例程式 — Dense Optical Flow (Farneback)
1 | import cv2 |

圖:Dense Optical Flow,顯示整張圖片的運動方向與速度
⚠️ 注意事項
- 光流分析需要 連續影格,若影片斷裂或幀率過低,效果會不佳。
- Lucas-Kanade 適合少量特徵點,Dense Optical Flow 適合整體運動分析。
- 光流結果容易受光線變化、遮擋影響。
- 建議在 灰階圖片上計算光流,以減少計算量。
📊 應用場景
- 運動分析:分析球員或球的移動軌跡。
- 監控系統:偵測移動物體。
- 影片穩定化:估計相機晃動並修正。
- 自動駕駛:分析道路上物件的移動。
🎯 結語
本篇我們學會了如何使用 OpenCV 光流分析 (Optical Flow),並透過 Lucas-Kanade 與 Dense Optical Flow 方法來追蹤圖片中物件的移動。
這些技術在運動分析、監控與自動駕駛中非常常見,後續可以結合物件偵測與追蹤,打造更完整的系統。
📖 如在學習過程中遇到疑問,或是想了解更多相關主題,建議回顧一下 Python | OpenCV 系列導讀,掌握完整的章節目錄,方便快速找到你需要的內容。
註:以上參考了
OpenCV Tutorials
OpenCV-Python Tutorials
Pexels — 免費影片素材
