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