Filtre de Kalman utilisant OpenCV en Python

Manav Narula 13 juin 2022
  1. Filtre de Kalman utilisant opencv en Python
  2. Conclusion
Filtre de Kalman utilisant OpenCV en Python

La vision par ordinateur s’attaque à diverses tâches complexes associées au traitement d’images et de vidéos dans l’intelligence artificielle. Nous utilisons la bibliothèque opencv de Python pour gérer certaines de ces tâches.

Cette bibliothèque implémente différents algorithmes et techniques utilisant des objets pour résoudre certains de ces problèmes.

L’une de ces tâches consiste à prédire la trajectoire d’un objet donné. L’un des algorithmes les plus couramment utilisés pour cela est le filtre de Kalman.

Ce tutoriel démontrera le filtre de Kalman en utilisant opencv en Python.

Filtre de Kalman utilisant opencv en Python

Le filtre de Kalman utilise l’état précédent de l’objet pour prédire son état suivant. Cet algorithme utilise une équation de différence stochastique linéaire pour déterminer l’état suivant.

Nous devons nous familiariser avec quelques matrices associées à cette équation.

Tout d’abord, une matrice de transition d’état relie l’état actuel à l’état précédent. En option, nous pouvons contrôler l’entrée à l’aide d’une matrice d’entrée de contrôle.

Nous devons transformer l’état en un domaine de mesure qui est obtenu à l’aide d’une matrice de transformation. Il doit également y avoir un vecteur de bruit de processus avec covariance.

En Python, on peut utiliser la classe KalmanFilter de la bibliothèque opencv pour implémenter cet algorithme et prédire les états. Nous définirons les attributs d’un objet pour cette classe et assignerons les matrices nécessaires.

Les attributs measurementMatrix, transitionMatrix et processNoiseCov spécifient respectivement la matrice de mesure, la matrice de transition et la matrice de bruit de processus avec covariance discutées précédemment. Nous pouvons ensuite utiliser l’objet pour faire des prédictions à l’aide de la fonction predict().

Comprenons mieux cela avec un exemple.

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

Production:

Filtre de Kalman utilisant opencv en Python

Dans l’exemple ci-dessus, nous implémentons le filtre de Kalman et l’utilisons pour prédire le mouvement de notre souris. Nous créons un canevas et déplaçons le curseur sur ce canevas (couleur verte), et simultanément le filtre de Kalman tentera de prédire le mouvement du curseur (couleur rouge).

Comprenons ce qui se passe dans le code.

Nous commençons par créer un cadre de toile sur lequel nous pouvons dessiner le mouvement du curseur. La fonction on_mouse() permet d’ajouter les valeurs du curseur.

La méthode paint_canvas() prend ces valeurs et les valeurs prédites et les dessine sur le canevas. La fonction setMouseCallback() est également appelée à chaque déplacement du curseur.

Nous créons une classe KalmanFilter appelée l’objet kalman_fil. Les matrices requises ont été attribuées à l’aide des attributs discutés précédemment.

Ensuite, nous exécutons une boucle pour dessiner sur la toile et faire les prédictions.

La méthode correct() de cette classe met à jour l’état prédit à partir de la mesure. La fonction predict() fait les prédictions.

Ces valeurs prédites sont données à la méthode paint_canvas().

Pour sortir de la boucle, nous utilisons l’instruction break, et elle est appelée lorsque l’utilisateur appuie sur la touche Esc (touche numéro 27 sur le clavier). Si on appuie sur la barre d’espace, le canevas est effacé de la mesure précédente en appelant la méthode reset_canvas().

Conclusion

Pour conclure, nous avons abordé les bases d’un filtre de Kalman dans ce didacticiel. Nous avons discuté de la logique nécessaire et des attributs qui la sous-tendent.

Nous avons implémenté cet algorithme en utilisant la classe KalmanFilter de la bibliothèque opencv. Différents paramètres et fonctions membres de cette classe ont été démontrés.

Nous utilisons l’algorithme pour prédire le mouvement du curseur sur une toile de dessin.

Auteur: 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