Kalman-Filter mit OpenCV in Python

Manav Narula 13 Juni 2022
  1. Kalman-Filter mit opencv in Python
  2. Fazit
Kalman-Filter mit OpenCV in Python

Computer Vision bewältigt verschiedene komplizierte Aufgaben im Zusammenhang mit der Bild- und Videoverarbeitung in der künstlichen Intelligenz. Wir verwenden Pythons Bibliothek opencv, um einige dieser Aufgaben zu erledigen.

Diese Bibliothek implementiert verschiedene Algorithmen und Techniken unter Verwendung von Objekten, um einige dieser Probleme anzugehen.

Eine solche Aufgabe ist die Vorhersage der Flugbahn eines bestimmten Objekts. Einer der dafür am häufigsten verwendeten Algorithmen ist der Kalman-Filter.

Dieses Tutorial demonstriert den Kalman-Filter mit opencv in Python.

Kalman-Filter mit opencv in Python

Der Kalman-Filter verwendet den vorherigen Zustand des Objekts, um seinen nächsten Zustand vorherzusagen. Dieser Algorithmus verwendet eine lineare stochastische Differenzgleichung, um den nächsten Zustand zu bestimmen.

Wir müssen mit einigen Matrizen vertraut sein, die mit dieser Gleichung verbunden sind.

Zunächst verbindet eine Zustandsübergangsmatrix den aktuellen Zustand mit dem vorherigen Zustand. Optional können wir den Eingang über eine Steuereingangsmatrix steuern.

Wir müssen den Zustand in eine Messdomäne transformieren, was mit einer Transformationsmatrix erreicht wird. Es muss auch einen Prozessrauschvektor mit Kovarianz geben.

In Python können wir die Klasse KalmanFilter aus der Bibliothek opencv verwenden, um diesen Algorithmus zu implementieren und Zustände vorherzusagen. Wir werden die Attribute eines Objekts für diese Klasse definieren und die notwendigen Matrizen zuweisen.

Die Attribute measurementMatrix, transitionMatrix und processNoiseCov spezifizieren die zuvor diskutierte Messmatrix, Übergangsmatrix bzw. die Prozessrauschmatrix mit Kovarianz. Wir können das Objekt dann verwenden, um mit der Funktion predict() einige Vorhersagen zu treffen.

Lassen Sie uns dies anhand eines Beispiels besser verstehen.

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()

Ausgabe:

Kalman-Filter mit opencv in Python

Im obigen Beispiel implementieren wir den Kalman-Filter und verwenden ihn, um unsere Mausbewegung vorherzusagen. Wir erstellen eine Leinwand und bewegen den Cursor auf dieser Leinwand (grüne Farbe), und gleichzeitig versucht der Kalman-Filter, die Cursorbewegung vorherzusagen (rote Farbe).

Lassen Sie uns verstehen, was im Code passiert.

Wir beginnen damit, einen Leinwandrahmen zu erstellen, auf dem wir die Cursorbewegung zeichnen können. Die Funktion on_mouse() wird verwendet, um die Werte des Cursors anzuhängen.

Die Methode paint_canvas() nimmt diese Werte und die vorhergesagten Werte und zeichnet sie auf die Leinwand. Die Funktion setMouseCallback() wird auch immer dann aufgerufen, wenn der Cursor bewegt wird.

Wir erstellen eine KalmanFilter-Klasse namens kalman_fil-Objekt. Die erforderlichen Matrizen wurden unter Verwendung der zuvor besprochenen Attribute zugewiesen.

Dann führen wir eine Schleife aus, um auf der Leinwand zu zeichnen und die Vorhersagen zu treffen.

Die correct()-Methode dieser Klasse aktualisiert den vorhergesagten Zustand aus der Messung. Die Funktion predict() macht die Vorhersagen.

Diese vorhergesagten Werte werden der Methode paint_canvas() übergeben.

Um aus der Schleife auszubrechen, verwenden wir die Anweisung break, die aufgerufen wird, wenn der Benutzer die Taste Esc drückt (Tastennummer 27 auf der Tastatur). Wenn wir die Leertaste drücken, wird die Leinwand von der vorherigen Messung gelöscht, indem die Methode reset_canvas() aufgerufen wird.

Fazit

Zum Abschluss haben wir in diesem Tutorial die Grundlagen eines Kalman-Filters besprochen. Wir haben die notwendige Logik und Attribute dahinter diskutiert.

Wir haben diesen Algorithmus mit der Klasse KalmanFilter aus der Bibliothek opencv implementiert. Verschiedene Parameter und Elementfunktionen dieser Klasse wurden demonstriert.

Wir verwenden den Algorithmus, um die Bewegung des Cursors auf einer Zeichenfläche vorherzusagen.

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