光流法(Optical Flow)偵測障礙物並估算距離

光流法的基本概念:

Python 程式範例(使用 Farneback Optical Flow):


import cv2
import numpy as np

# 開啟攝影機
cap = cv2.VideoCapture(0)

# 讀取第一幀並轉成灰階
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()

    

優化與進階應用:

這個方法能讓你的自駕車判斷前方是否有障礙物,並根據光流變化來決定是否需要避障。這樣的做法符合你的需求嗎?