添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

光流法的基本概念:

  • 計算光流 :使用 OpenCV 的 cv2.calcOpticalFlowFarneback() cv2.calcOpticalFlowPyrLK() 來追蹤特徵點的移動。
  • 分析運動方向
  • 若視覺流向 放射狀擴散(diverging) ,表示有物體接近。
  • 若視覺流向 集中收斂(converging) ,表示場景遠離。
  • 距離估算
  • 大範圍、高速度的光流變化,代表障礙物接近。
  • 可透過光流向量的長度來估算相對距離(向量越長,代表物體越近)。
  • # 讀取第一幀並轉成灰階 ret, prev_frame = cap.read() prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY) while True: # 讀取新影像 ret, frame = cap.read() if not ret: break # 轉成灰階 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 計算光流 flow = cv2.calcOpticalFlowFarneback(prev_gray, gray, None, 0.5, 3, 15, 3, 5, 1.2, 0) # 計算光流向量的大小 magnitude, angle = cv2.cartToPolar(flow[..., 0], flow[..., 1]) # 繪製光流 hsv = np.zeros_like(frame) hsv[..., 1] = 255 # 設定飽和度 hsv[..., 0] = angle * 180 / np.pi / 2 # 色相(H)表示方向 hsv[..., 2] = cv2.normalize(magnitude, None, 0, 255, cv2.NORM_MINMAX) # 亮度(V)表示速度 flow_img = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) # 顯示結果 cv2.imshow("Optical Flow", flow_img) # 計算障礙物接近的程度 avg_magnitude = np.mean(magnitude) if avg_magnitude > 2.0: # 設定閾值(根據實驗調整) cv2.putText(frame, "Obstacle detected!", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) cv2.imshow("Frame", frame) # 更新前一幀 prev_gray = gray.copy() # 按 'q' 退出 if cv2.waitKey(30) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()

    優化與進階應用:

  • 使用金字塔 Lucas-Kanade(PyrLK)方法
  • PyrLK 只追蹤特徵點,比 Farneback 更適合即時應用。
  • 可以用 cv2.goodFeaturesToTrack() 找出畫面中有代表性的特徵點,然後用 cv2.calcOpticalFlowPyrLK() 來追蹤這些點的移動。
  • 進一步距離估算
  • 可以將光流向量的長度與攝影機焦距、視角對應起來,計算相對距離。
  • 若有已知尺寸的物體出現在畫面中,可以用三角測量法來推算實際距離。
  •