Détection d’Objets avec la librairie GluonCV

Le Deep Learning a permis une avancée notable dans plusieurs domaines de recherche dont le Computer Vision (Vision par Ordinateur in french 😄). Dans cet article, je vous présente l’une des applications du Computer Vision : la détection d’objets avec la librairie Python GluonCV.

Présentation de GluonCV

GluonCV (Gluon Computer Vision) est une boîte à outils de la bibliothèque MXNet. Elle utilise un large ensemble de modèles pré-entraînés dit Model Zoo – plus de 200 architectures de réseaux de neurones.
En outre, GluonCV fournit des implémentations d’algorithmes de pointe de Deep Learning en Computer Vision. Il vise à aider les ingénieurs, les chercheurs et les étudiants à prototyper rapidement des produits, à valider de nouvelles idées et à apprendre le Computer Vision.

GluonCV et ses applications

En effet, GluonCV permet les applications suivantes :

  • Classification d’image
Image de chien
Identifie la classe de l’objet présent sur une image. Chien (Dog) 🐕 dans cet exemple.
  • Détection d’objets
Image de chiens et chats
Identifie chaque objet et sa classe dans une image. Dans notre cas, on a 2 chiens (Dog) 🐕 et 2 chats (Cat) 🐈.
  • Segmentation sémantique
Image de chiens et chats
Un peu comme la détection d’objets, GluonCV classifie les objets en supprimant l’arrière-plan.
  • Segmentation des instances
Image de chiens et chats
Tout comme la segmentation sémantique, GluonCV classifie et fait le comptage par couleur.
  • Estimation de la position
Image de personnes qui sautent
Estime la position en temps réel dans une image/vidéo. GluonCV détecte les membres de plusieurs personnes à la fois dans cet exemple.
  • Reconnaissance d’actions
Homme à vélo
GluonCV reconnaît le mouvement dans une image/vidéo. Dans notre exemple, il reconnaît le cyclisme.

Assez fun n’est-ce pas !? 😃
Grâce à GluonCV, on peut imaginer d’autres applications qui découleraient de ces dernières ci-dessus. Mais voyons ensemble la détection d’objets par un tutoriel (sympa 🥳).

Tutoriel sur la détection d’objets

Tout d’abord, importons les différentes bibliothèques nécessaires à notre tutoriel.

# Modeling
from mxnet import image
from gluoncv import model_zoo, data, utils

# Visualization
import os
import matplotlib.pyplot as plt
from pylab import rcParams
rcParams['figure.figsize'] = 5, 10

Le Model Zoo compte plus de 200 modèles et pour les afficher, on peut faire la commande suivante :

for model in model_zoo.get_model_list():
    print(model)

Pour la détection d’objets, il y a 4 grandes familles de modèles : SSD, Faster-RCNN, YOLO-v3 et CenterNet – tous efficaces selon le mAP (mean Average Precision) et le nombre d’échantillons par seconde – et 2 grands datasets comme base d’apprentissage : Pascal VOC et MS COCO (voir le détail ici). Mais dans notre tutoriel, nous allons utiliser le modèle yolo3_darknet53_coco qui permet de traiter plus de 100 images par seconde et une précision moyenne supérieure (mAP) à 33.

Nous allons définir notre réseau avec le modèle choisi.

selected_model = 'yolo3_darknet53_coco'
# Define network
network = model_zoo.get_model(selected_model, pretrained=True)

Après le choix de notre modèle, nous allons faire du traitement d’images (on rentre dans le Computer Vision là 🎉).
Écrivons une fonction pour charger notre image.

def load_image(filepath):
    """
    Charge une image.

    @parameter
        filepath: chemin de fichier de notre image RGB de format JPG.
            Il est de type string (str)
    
    @return
        imageHWC: un tableau de type mx.nd.NDArray avec des intensités de pixel 
            de la forme HWC (H: Height ; W: Width ; C: Channel)
    """

    imageHWC = image.imread(filepath)

    return imageHWC
# Load image
imageHWC = load_image("./sample_data/stanislav-rozhkov-bTsx5PHO5Yc-unsplash.jpg")

Affichons notre image.

Photo prise par Stanislav Rozhkov sur Unsplash
Photo prise par Stanislav Rozhkov sur Unsplash

Nous n’allons pas travaillé avec notre image brut. Nous allons la transformer avant de la passer dans notre modèle. Pour ce faire, nous allons écrire une fonction.

def transform_image(array):
    """
    Transforme une image en :

    1) Redéfinissant la taille de l'image à la plus petite dimension qui est 416.
        Exemple : (832, 3328) -> (416, 1664).
    2) Recadrant à un carré central de dimension (416, 416).
    3) Convertissant l'image de la forme HWC à CHW.
    4) Normalisant l'image en utilisant des statistiques de COCO (normalisation 
        par moyenne et variance du canal couleur).
    5) Créant un batch d'une seule image.

    @parameter
        array: mx.nd.NDArray dans la forme HWC
    
    @return
        Un tuple de (mx.nd.NDArray, numpy.ndarray).
            Ce tuple est un batch d'une image transformée (dans la forme NCHW) 
                et une image non-normalisée.
    """

    return data.transforms.presets.yolo.transform_test(imgs=array)

Utilisons cette fonction et affichons l’image non-normalisée (de type numpy.ndarray).

# Transform imageHCW
norm_image, unnorm_image = transform_image(imageHWC)

# Plot un-normalized image
plt.imshow(unnorm_image)
fig = plt.gcf()
fig.set_size_inches(14, 14)
plt.show()
Photo modifiée
Cette photo modifiée est de taille (628, 416)

Nous pouvons à présent passer à la détection d’objets dans notre image chargée.

def detect(network, array):
    """
    Renvoie les boîtes de délimitation et les prédictions de classe d'un réseau 
        et d'une image donnés.

    @parameters
        network: modèle pré-entraîné de détection d'objets.
            Il est de type mx.gluon.Block
        array : un batch d'images transformées de taille NCHW(1, 3, 416, 416).
            Il est de type mx.nd.NDArray

    @return
        Un tuple de ID de classes, des scores et des boîtes de délimitation 
            des prédictions.
            Ce tuple  est de type mx.nd.NDArrays
    """

    predictions = network(array)

    class_ids, scores, bounding_boxes = predictions

    return class_ids, scores, bounding_boxes

Détectons les objets présents dans notre image et affichons notre solution.

# Predict object detection
class_ids, scores, bounding_boxes = detect(network=network, array=norm_image)

# Plot object detection
ax = utils.viz.plot_bbox(unnorm_image, 
                         bounding_boxes[0], 
                         scores[0], 
                         class_ids[0], 
                         class_names=network.classes)
fig = plt.gcf()
fig.set_size_inches(14, 14)
plt.savefig('object_detection.png')
plt.show()
Détection d'objets presque réussie
Nous détectons 3 personnes, un vélo et 3 pots de plantes.

Conclusion

GluonCV est une boîte à outils puissante de MXNet qui sert pour les applications de Computer Vision. Dans notre article, nous avons fait un TP pour la détection d’objets. Nous pourrions aller plus loin en comptant des personnes dans une base d’images (voir le code 👉 ici 👈).

Sources et ressources complémentaires

[1] Medium, GluonCV – Deep Learning Toolkit for Computer Vision, https://medium.com/apache-mxnet/gluoncv-deep-learning-toolkit-for-computer-vision-9218a907e8da
[2] GluonCV, GluonCV Toolkit, https://gluon-cv.mxnet.io
[3] GitHub, AWS – GluonCV: Object Detection, https://github.com/dmlc/web-data/blob/master/gluoncv/slides/Detection.pdf

Laisser un commentaire

Votre adresse email ne sera pas publiée.

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

Voulez-vous en savoir plus sur la Data Science ?

Inscrivez-vous alors à notre newsletter et vous receverez gratuitement nos derniers articles et actualités ! 
S'INSCRIRE MAINTENANT 
close-link