Traquer un objet en utilisant OpenCV

 

 

ARTICLE IDLABS

Traquer un objet en utilisant OpenCV

PÉRIODE
(2017-2018)

Sommaire


Sommaire

Introduction

Présentation de OpenCV

Installation

Exemple d’utilisation

Références

Auteur

 

Introduction


OpenCV (Open Source Computer Vision) est une bibliothèque proposant un ensemble de plus de 2500 algorithmes de vision par ordinateur.

 La vision nous permet de discerner et reconnaître les formes, les couleurs et les textures du monde qui nous entoure. On pourrait croire que seul nos yeux sont nécessaires à cela, mais la réalité est tout autre : nos yeux ne servent qu'à capter le signal contenu dans les rayons lumineux qui viennent frapper nos rétines, pas à en extraire des informations. Ça, c'est le travail de la zone de notre cerveau que nous appelons le cortex visuel.

De nos jours, nous avons donné le sens de la vue aux ordinateurs grâce aux caméras numériques, mais cela ne suffit pas à les doter de vision : il leur manque encore la capacité à extraire des informations des images et des flux vidéo, de manière à percevoir, analyser et comprendre le monde qu'ils observent.

C'est ici qu'intervient ce vaste domaine de recherche qu'est la vision par ordinateur, à la croisée des chemins entre les mathématiques, le traitement du signal et l'intelligence artificielle.

 

 

Présentation de OpenCV


OpenCV est accessibles au travers d'API pour les langages C, C++, et Python. Elle est distribuée sous une licence BSD (libre) pour les plate-formes Windows, GNU/Linux, Android et MacOS.

Initialement écrite en C il y a 10 ans par des chercheurs de la société Intel, OpenCV est aujourd'hui développée, maintenue, documentée et utilisée par une communauté de plus de 40 000 membres actifs. C'est la bibliothèque de référence pour la vision par ordinateur, aussi bien dans le monde de la recherche que celui de l'industrie.

Afin de mieux présenter son étendue et ce qu'elle permet de faire, jetons un œil aux principaux modules accessibles au travers de son API C :

  • core : les fonctionnalités de base. Cette bibliothèque permet de manipuler les structures de base, réaliser des opérations sur des matrices, dessiner sur des images, sauvegarder et charger des données dans des fichiers XML…

  • imgproc : traitement d'image. Nous entrons dans le cœur du sujet. Les fonctions et structures de ce module sont relatives aux transformations d'images, au filtrage, à la détection de contours, de points d'intérêt…

  • features2d : descripteurs. Ce module concerne principalement l'extraction de descripteurs selon deux approches courantes (SURF et StarDetector), qui s’utilise lorsque nous nous intéressons à la caractérisation d'images.

  • objdetect : détection d'objets. Cette bibliothèque permet de faire de la reconnaissance d'objets dans une image au moyen de l'algorithme Adaboost (Viola & Jones, 2001). Elle sera utilisé lorsque nous parlerons d'apprentissage et de reconnaissance de formes.

  • video : traitement de flux vidéo. Ces fonctions servent à segmenter et suivre les objets en mouvement dans une vidéo.

  • highgui : entrées-sorties et interface utilisateur. OpenCV intègre sa propre bibliothèque haut-niveau pour ouvrir, enregistrer et afficher des images et des flux vidéo. Celle-ci contient aussi un certain nombre de fonctions permettant de réaliser des interfaces graphiques très simples.

  • calib3d : calibration, estimation de pose et stéréo-vision. Ce module contient des fonctions permettant de reconstruire une scène en 3D à partir d'images acquises avec plusieurs caméras simultanément.

En ce qui concerne la documentation, vous trouverez tout ce dont vous aurez besoin sur cette page. Sachez que l'API C/C++ est stable. Cela signifie qu'il est très peu probable que grand-chose ne soit modifié ou retiré de son côté dans les versions 3.x, 2.x d'OpenCV, et c'est la raison pour laquelle nous utiliserons cette API.

 

Installation


OpenCV est accessible au travers d'API pour les langages C, C++, et Python. Elle est distribuée sous une licence BSD (libre) pour les plates-formes Windows, GNU/Linux, Android et MacOS. Dans cet article, je ne présenterai que l’installation sur Linux en détail.

Windows

Sous Windows, la méthode d'installation dépend de l'environnement que vous utilisez pour développer.

Si vous utilisez Microsoft Visual Studio, vous avez tout intérêt à utiliser l'installeur exécutable, puisqu'il contient les bibliothèques compilées spécialement pour votre IDE. Vous pouvez suivre cette vidéo pour l’installation.

Si vous utilisez un autre IDE (Code::Blocks, Eclipse, etc.), il faudra que vous génériez vos propres bibliothèques à partir des fichiers sources. Vous pouvez suivre cette page pour l’installation.

Mac Os

Si vous tenez à rester à la pointe, vous pouvez compiler OpenCV avec CMake pour votre machine en suivant les instructions de cette vidéo.

Si vous souhaitez utiliser Python pour votre projet OpenCV (3.x.x) sur mac, vous pouvez suivre ce guide complet.

Linux – Ubuntu (for C/C++/Python)

Chaque étape l’installation devra être effectuée dans le terminal. Pour commencer, ouvrez un terminal et mettez à jour les dépendances et distributions.

Ensuite, il faut installer quelques outils nécessaires tels que pkg-config (permet de simplifier la compilation d’application, utilisant des bibliothèques partagées sur le système) et cmake (comparable au programme Make dans le sens où le processus de construction logicielle est entièrement contrôlé par des fichiers de configuration). OpenCV doit être capable de charger divers formats d’images tels que PNG, JPEG, TIFF, etc. Il doit être aussi capable de charger des vidéos, et réaliser différents traitements. Pour cela, il est nécessaire d’installer différentes librairies.

Vous pouvez copier/coller ces 3 commandes dans un terminal

  • $ sudo apt-get install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev

  • $ sudo apt-get install python3.5-dev python3-numpy libtbb2 libtbb-dev

  • $ sudo apt-get install libjpeg-dev libpng-dev libtiff5-dev libjasper-dev libdc1394-22-dev libeigen3-dev libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev sphinx-common libtbb-dev yasm libfaac-dev libopencore-amrnb-dev libopencore-amrwb-dev libopenexr-dev libgstreamer-plugins-base1.0-dev libavutil-dev libavfilter-dev libavresample-dev.

Par la suite, il nous faut télécharger OpenCV. Pour accéder à toutes les fonctionnalités de OpenCV, il nous est nécessaire de télécharger également OpenCV_Contrib. En effet, dans les versions antérieures de OpenCV (avant 3.x.x), SIFT et SURF étaient inclus par défaut. Depuis la version 3.x, ces paquets ont été déplacés vers Contrib qui héberge (1) des modules qui sont actuellement en développement ou (2) des modules qui sont marqués comme "non libres" (c'est-à-dire, brevetés). Vous pouvez en apprendre plus sur le raisonnement derrière la restructuration SIFT / SURF dans cet article de blog.

À ce point, il ne nous reste plus qu’à installer et compiler OpenCV. Pour ce faire, nous utiliserons Cmake :

Vous pouvez copier/coller ces commandes dans un terminal

  • $ cd opencv

  • $ mkdir release

  • $ cd release

  • $ cmake -D BUILD_TIFF=ON -D WITH_CUDA=OFF -D ENABLE_AVX=OFF -D WITH_OPENGL=OFF -D WITH_OPENCL=OFF -D WITH_IPP=OFF -D WITH_TBB=ON -D BUILD_TBB=ON -D WITH_EIGEN=OFF -D WITH_V4L=OFF -D WITH_VTK=OFF -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=/opt/opencv_contrib/modules /opt/opencv/

  • $ make -j4

  • $ make install

  • $ ldconfig

  • $ exit

  • $ cd ~

Pour vérifier si OpenCV est bien installé, exécuter la commande suivante : $ pkg-config --modversion opencv. À l’heure où cet article est écrit, la version 3.4.0 devrait apparaître.

Pour tester le bon fonctionnement de notre installation, créer un dossier cpp_test (mkdir cpp_test) et créer un fichier main.cpp à l’intérieur (cd cpp_test et touch main.cpp). Ajouter ce code à votre fichier main.cpp :

Il ne reste plus qu’à compiler votre programme à l’aide la commande : g++ main.cpp -o output `pkg-config --cflags --libs opencv.

Lancer le programme : ./output

 

Exemple d’utilisation


Ajouter (fusionner)

Dans cet exemple, nous allons apprendre comment ajouter (fusionner) deux images avec OpenCV, en utilisant la méthode addWeighted(), qui se repose sur le principe du mélange linéaire. Cette méthode prendra 6 paramètres : premier tableau d’entrée, le poids des éléments du premier tableau, second tableau d’entrée, le poids des éléments du second tableau, le gamma, et le tableau de sortie qui a la même taille et le même nombre de canaux que les tableaux d’entrée.

Explication :

  1. Nous chargeons nos deux images :

    src1 = imread( "LinuxLogo.jpg");

    src2 = imread( "WindowsLogo.jpg");

    Attention : src1 et src2 doivent toux deux avoir la même taille (largeur et hauteur) et le même type !

  2. Maintenant, il faut générer l’image finale souhaitée :

    beta = ( 1.0 - alpha ); ceci correspond au gamma

    addWeighted( src1, alpha, src2, beta, 0.0, dst);

  3. Et enfin, on crée la fenêtre, en affichant l’image et en attendant que l’utilisateur saisisse une touche :

    imshow( "Linear Blend", dst );

    waitKey(0);

  4. Résultat :

Contraste et luminosité

 Précédemment, nous avons vu comment ouvrir une image, ou fusionner deux images avec OpenCV. Il nous est possible de jouer sur certains paramètres de la photo, tel que le contraste et la luminosité.

Explication :

  1. Nous commençons par créer des paramètres à saisir par l’utilisateur :

    double alpha = 1.0; /* contraste */

    int beta = 0; /* luminosité */

  2. Nous chargeons une image en utilisant cv::imread et l’enregistrons dans un objet Mat :

    String imageName("lena.jpg");

                    if (argc > 1)

                    {

                                        imageName = argv[1];

                    }

                    Mat image = imread( imageName );

  1. Puisque nous allons faire quelques transformations à cette image, nous avons besoin d’un nouvel objet Map pour le stocker. Nous voulons que cette image ait les caractéristiques suivantes : valeurs initiales des pixels à zéro + même taille et type que l’image originale ;

    Mat new_image = Mat::zeros( image.size(), image.type());

    cv::Mat::zeros renvoie un initialiseur de matrice zéro de style Matlab basé sur image.size() et image.type().

  2. Pour effectuer l’opération de transformation de l’image, nous devons accéder à chaque pixel de l’image. Puisque nous fonctionnons avec des images RGB, nous aurons trois valeurs par pixel (R,G et B), et nous allons donc y accéder séparément :

    for( int y = 0; y < image.rows; y++ ) {

                    for( int x = 0; x < image.cols; x++ ) {

                    for( int c = 0; c < 3; c++ ) {

                    new_image.at<Vec3b>(y,x)[c] =

saturate_cast<uchar>( alpha*( image.at<Vec3b>(y,x)[c] ) + beta );

}

}

}

  1. Pour finir, nous créons des fenêtres et montrons les images :

             → namedWindow("Original Image", WINDOW_AUTOSIZE);

                    namedWindow("New Image", WINDOW_AUTOSIZE);

imshow("Original Image", image);

imshow("New Image", new_image);

waitKey();

Résultat :

Trackbar

  Précédemment, nous avons vu comment joueur sur certains paramètres au lancement du programme. Mais il nous est possible de rajouter une trackbar, afin de modifier, par exemple, la luminosité et le contraste de l’image dynamiquement.

Explication :

  1. La seule nouveauté dans ce code est la méthode createTrackbar(). Elle peut prendre jusqu’à 6 paramètres, mais ici que 4. Le nom de la trackbar, le nom de la fenêtre à laquelle la trackbar est attachée, un pointeur sur la valeur associé à la position de la trackbar, et la valeur maximale de la trackbar. La valeur minimale est toujours zéro :

    int iSliderValue1 = 50;

    createTrackbar("Brightness", "My Window", &iSliderValue1, 100);

  2. On itère dans une boucle infinie et applique périodiquement la luminosité et le contraste à l’image parce que l’on souhaite appliquer les changements à l’image chaque fois que l’utilisateur modifie la position de la trackbar :

    while (true) {

    Mat dst; //Change la luminosité et le contraste de l'image

    int iBrightness = iSliderValue1 - 50;

    double dContrast = iSliderValue2 / 50.0;

    src.convertTo(dst, -1, dContrast, iBrightness);

    imshow("My Window", dst); //Montre les modifications apportées à l'image

    int iKey = waitKey(50); //Attend que l'utilisateur saisit une touche

    if (iKey == 27) //Si l'utilisateur presse la touche Echap

    {

    break;

    }

    }

 Résultat :

Références


 

 

Auteur


Article écrit par Marciniak Marius, élève de 3ème année, dans le cadre de l’année scolaire à CampusID.

 

Pas de commentaire.

Ajouter un commentaire