在 Python 中使用 OpenCV 的卡爾曼濾波器

Manav Narula 2023年1月30日
  1. 在 Python 中使用 opencv 的卡爾曼濾波器
  2. まとめ
在 Python 中使用 OpenCV 的卡爾曼濾波器

計算機視覺處理與人工智慧中的影象和視訊處理相關的各種複雜任務。我們使用 Python 的 opencv 庫來處理其中一些任務。

這個庫使用物件來實現不同的演算法和技術來解決其中一些問題。

其中一項任務是預測給定物體的軌跡。用於此的最常用演算法之一是卡爾曼濾波器。

本教程將演示在 Python 中使用 opencv 的卡爾曼濾波器。

在 Python 中使用 opencv 的卡爾曼濾波器

卡爾曼濾波器使用物件的先前狀態來預測其下一個狀態。該演算法使用線性隨機差分方程來確定下一個狀態。

我們需要熟悉與這個方程相關的一些矩陣。

首先,狀態轉移矩陣將當前狀態與前一個狀態聯絡起來。或者,我們可以使用控制輸入矩陣來控制輸入。

我們需要將狀態轉換為使用轉換矩陣實現的某個測量域。還需要一個具有協方差的過程噪聲向量。

在 Python 中,我們可以使用 opencv 庫中的 KalmanFilter 類來實現該演算法並預測狀態。我們將為此類定義物件的屬性並分配必要的矩陣。

measurementMatrixtransitionMatrixprocessNoiseCov 屬性分別指定了前面討論的測量矩陣、轉換矩陣和具有協方差的過程噪聲矩陣。然後我們可以使用該物件使用 predict() 函式進行一些預測。

讓我們通過一個例子更好地理解這一點。

import cv2
import numpy as np

measured = []
predicted = []
dr_frame = np.zeros((400, 400, 3), np.uint8)
mp = np.array((2, 1), np.float32)
tp = np.zeros((2, 1), np.float32)


def on_mouse(k, x, y, s, p):
    global mp, measured
    mp = np.array([[np.float32(x)], [np.float32(y)]])
    measured.append((x, y))


def paint_canvas():
    global dr_frame, measured, predicted
    for i in range(len(measured) - 1):
        cv2.line(dr_frame, measured[i], measured[i + 1], (0, 100, 0))
    for i in range(len(predicted) - 1):
        cv2.line(dr_frame, predicted[i], predicted[i + 1], (0, 0, 200))


def reset_canvas():
    global measured, predicted, dr_frame
    measured = []
    predicted = []
    dr_frame = np.zeros((400, 400, 3), np.uint8)


cv2.namedWindow("Sample")
cv2.setMouseCallback("Sample", on_mouse)
kalman_fil = cv2.KalmanFilter(4, 2)
kalman_fil.measurementMatrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0]], np.float32)
kalman_fil.transitionMatrix = np.array(
    [[1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32
)
kalman_fil.processNoiseCov = (
    np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32)
    * 0.03
)

while True:
    kalman_fil.correct(mp)
    tp = kalman_fil.predict()
    predicted.append((int(tp[0]), int(tp[1])))
    paint_canvas()
    cv2.imshow("Output", dr_frame)
    k = cv2.waitKey(30) & 0xFF
    if k == 27:
        break
    if k == 32:
        reset_canvas()

輸出:

在 Python 中使用 opencv 的卡爾曼濾波器

在上面的示例中,我們實現了卡爾曼濾波器並使用它來預測我們的滑鼠移動。我們建立一個畫布並在該畫布上移動游標(綠色),同時卡爾曼濾波器將嘗試預測游標移動(紅色)。

讓我們瞭解程式碼中發生了什麼。

我們首先建立一個畫布框架,我們可以在其上繪製游標移動。on_mouse() 函式用於附加游標的值。

paint_canvas() 方法獲取這些值和預測值並將它們繪製在畫布上。每當移動游標時,也會呼叫 setMouseCallback() 函式。

我們建立了一個名為 kalman_fil 物件的 KalmanFilter 類。使用前面討論的屬性分配了所需的矩陣。

然後我們執行一個迴圈在畫布上繪製並進行預測。

此類的 correct() 方法會根據測量結果更新預測狀態。predict() 函式進行預測。

這些預測值被賦予 paint_canvas() 方法。

為了跳出迴圈,我們使用 break 語句,當使用者按下 Esc 鍵(鍵盤上的鍵號 27)時呼叫它。如果我們按下空格鍵,畫布會通過呼叫 reset_canvas() 方法清除先前的測量值。

まとめ

最後,我們在本教程中討論了卡爾曼濾波器的基礎知識。我們討論了它背後的必要邏輯和屬性。

我們使用 opencv 庫中的 KalmanFilter 類實現了這個演算法。演示了該類的不同引數和成員函式。

我們使用該演算法來預測游標在繪圖畫布上的移動。

作者: Manav Narula
Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn