Le suivi d’objet … Une des grandes problématiques du domaine de la vision par ordinateur … Nous allons lors des 3 prochaines semaines , essayer de comprendre les enjeux et les problématiques de ce sujet. Nous commençons aujourd’hui par créer un programme simple pour suivre un objet. Cette méthode s’appuiera sur la détection de l’objet dans les trames successives de la vidéo.

Afin de se concentrer uniquement sur le suivi d’objet et faciliter la compréhension, les vidéos que nous utiliserons seront générées par ordinateur. Ainsi, l’extraction de l’objet sera la plus simple possible (arrière-plan uni et fixe, luminosité constante).

Déplacement d'un carré dans une image pour le suivi
Vidéo originale (Disponible ici)

Introduction au suivi d’objet.

Comme nous l’avons mentionné précédemment, la méthode que nous allons voir aujourd’hui est une méthode de suivi par détection. Son fonctionnement sera alors divisé en deux étapes :

  • Détecter l’objet dans l’image
  • Lier les positions successives de l’objet.

La première partie est relativement simple si vous suivez ce site depuis quelque temps. Sinon je vous invite, avant de continuer, à aller voir l’article sur la détection de forme dans une image.

import cv2
import numpy as np

cap=cv2.VideoCapture('tracking.mp4')
min_limite=(0,125,125)
max_limite=(255,255,255)
points=[]
nb_points=30

Nous commençons par importer les bibliothèques nécessaires (lignes 1-2), puis nous ouvrons la vidéo à traiter ligne 4. Nous définissons ensuite les valeurs minimales (l. 5) et maximales (l. 6) dans le domaine HSV, que nous utiliserons pour le seuillage des images. Nous chercherons dans cet exemple un objet bleu sur un fond blanc. Nous gardons donc toutes les informations de couleur (H) mais souhaitons ne pas prendre en compte le blanc (Saturation faible)

Puis nous définissons la liste points (l. 7) qui contiendra les valeurs des précédentes détections ainsi que le nombre maximum de points (l’historique des positions) que nous voulons garder (l. 8).

Étape 1: Détection de l’objet

while cap.get(cv2.CAP_PROP_POS_FRAMES)!=cap.get(cv2.CAP_PROP_FRAME_COUNT)-1:
    ret,frame=cap.read()
    img_hsv=cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
    masque=cv2.inRange(img_hsv,min_limite, max_limite)
    im2, contours, hierarchy=cv2.findContours(masque,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    centre = None

    if len(contours)>0:
        c = max(contours, key=cv2.contourArea)
        x,y,w,h=cv2.boundingRect(contours[0])
        cv2.rectangle(frame, (x, y),(x+w,y+h),(0, 255, 0), 3)
        centre=((int(x+w/2),int(y+h/2)))
    points.append(centre)

Pour toutes les trames de la vidéo (l. 11), nous récupérons l’image (l. 12), la convertissons dans le domaine HSV (l. 13) puis nous la seuillons (l. 14) avec les seuils définis précédemment. Enfin, nous extrayons les contours ligne 15 afin d’extraire l’objet qui nous intéresse.

Si un objet est détecté, nous cherchons le contour le plus grand (l. 19), nous calculons le rectangle encadrant (l. 20) et nous le traçons (l. 21).

Et voilà, notre objet est détecté.

Comme vous avez pu le voir, la variable centre est également présente dans les quelques lignes de code ci-dessus. Cette variable, utilisée pour le suivi de l’objet, contient le centre du rectangle encadrant dans le cas où un objet est détecté (l. 22) où ‘None’ (l. 16) dans le cas contraire. Pour chaque trame, nous stockons la valeur de centre dans la liste points.

Étape 2: Suivi de l’objet

if len(points)>nb_points:
        del points[0]

    for i in range (0,len(points)-1,1):
        if points[i] is None or points[i+1] is None:
            continue
        cv2.line(frame, points[i], points[i+1], (0, 0, 255), 3)
 
    cv2.imshow("Frame", frame)
    cv2.waitKey(1)

cap.release()
cv2.destroyAllWindows()

Nous commençons notre suivi d’objet par garantir que l’historique de points enregistré est bien limité par le nombre de points que nous souhaitons. Si le nombre de points dépasse la valeur que nous avons définie (l. 25), alors nous supprimons la première entrée de la liste (point le plus ancien) (l. 26).

Puis, pour chaque valeur de la liste points (l. 28) , nous traçons, dans le cas où l’objet a été détecté dans deux trames successives (l. 29-30) , la ligne reliant leurs centres (l. 31).

Enfin, nous affichons l’image résultante.

Conclusions:

Nous avons vu dans cet article une manière simple de suivre un objet dans une vidéo. Ce suivi consiste en la détection de l’objet dans l’image et en l’association des différentes détections. Cet exemple reste cependant très basique et permet juste de montrer le fonctionnement général du suivi par détection.

Certains aspects du suivi ne sont pas pris en compte : Est-on certain que l’objet que l’on a détecté correspond bien à l’objet que nous avions détecté dans la trame d’avant ? Que ce passe-t-il si deux objets sont présents dans la vidéo ? Comment les associer ?

Ces aspects sont abordés dans cet article.


3 commentaires

Amine · 10 novembre 2019 à 20 h 09 min

C’est quoi la commande que vous avez utilisée pour générer l’image résultante svp? merci

    Florent · 11 novembre 2019 à 18 h 53 min

    Bonjour,
    Nous affichons les images résultantes aux lignes 33 et 34.
    Si vous souhaitez enregistrer la vidéo générée, je vous invite à consulter cet article :

      Amine · 11 novembre 2019 à 21 h 08 min

      Je vous remercie pour votre réponse. Finalement, j’ai réussi à générer une vidéo à partir d’images en consultant votre article ; https://pymotion.com/generer-video-images/.
      Je vous remercie pour toutes ces explications bien détaillées et bon courage pour ce que vous faites.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.