Cours:Classif

De troyesGEII
Aller à : navigation, rechercher

TP Classification : détection d'objet en temps réel par vision

Le travail de cette étape va consister à

  • analyser des images acquises en "temps réel" afin de détecter et identifier des objets
  • les objets seront
    • dans un premier temps des jetons de nain jaune
    • dans un second temps des briques lego.

Technos matérielles et logicielles

Vous utiliserez :

  • Une Rpi 4 que vous programmerez depuis des postes utilisés en terminaux connectés par ssh, avec redirection graphique (option - X).
  • Une camera PiCam Wide (grand angle)
  • la librairie opencv pour la reconnaissance
  • la librairie CImg pour des traitements bas niveaux et affichages : https://cimg.eu/

Prise d'images en terminal

  • Connecter (si cela n'est pas fait) la PiCam à la Rpi4
  • Tester la PiCam avec libcamera-hello (la capture doit s'afficher sur l'écran de la Rpi)
  • Tester l'acquisition d'image avec l'éxecutable libcamera-still
  • Explorer les options de cette application (libcamera-still -h), en particulier -n, --immediate, --width, --height et -o

Voir la page suivante pour le détails des options possibles : https://www.raspberrypi.com/documentation/computers/camera_software.html

Livrable 1 : acquisition d'image

La PiCam s'interface en exploitant la librairie LibCamera.

Démo

  • Télécharger depuis GitHub (git clone ...), ce projet de démo : https://github.com/edward-ardu/libcamera-cpp-demo/tree/main
  • Le compiler et l'exécuter pour tester.
  • Prendre le temps d'analyser le programme main.cpp pour comprendre :
    • comment il fonctionne ;
    • comment l'image est acquise et utilisée dans openCV :
      • quel est l'objet openCV qui contient l'image ?
      • comment est affichée cette image ?
      • comment l'acquisition d'une touche est-elle gérée ?
      • ...

OneShot

  • copier le dossier de ce programme exemple vers un nouveau dossier OneShot
  • modifier le main.cpp en l'alégeant, afin d'obtenir un programme qui
  1. dès son lancement, lance une acquisition d'image ;
  2. attend que cette acquisition soit terminée
  3. affiche l'image, et attend l'appui d'une touche
  4. se termine

Avec CImg

  • copier ce dossier OneShot vers un dossier OneshotCimg
  • Télécharger la libraire CImg et placer CImg.h dans le dossier source
  • Modifier le main.cpp pour
  1. convertir l'image openCV couleur en niv. de gris
  2. convertir l'image niv. de gris openCV en image CImg
  3. avec CImg : afficher l'image et attendre la fermeture de la fenêtre.
  • Il sera nécessaire d'ajouter :
    • dans le main.cpp:
#include "CImg.h"
#define cimg_plugin1 "cvMat.h"
using namespace cimg_library;
    • dans le fichier CMakeLists.txt
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")

et de modifier

target_link_libraries(libcamera-demo "${LIBCAMERA_LIBRARIES}" ${OpenCV_LIBS})

en

target_link_libraries(libcamera-demo "${LIBCAMERA_LIBRARIES}" ${OpenCV_LIBS} X11)

Prétraitements et mesure de descripteurs

Cette partie est moins guidée, elle devra être incluse dans votre compte-rendu.

  • Modification éventuelle de la zone de capture de la camera.
  1. Conversion en image niv. de gris.
  2. Binarisation.
  3. (si plusieurs objets) Segmentation.
  • Fonction de calcul des descripteurs géométriques (longueur l, largeur w) d'un objet dans une image :
void compute_desc(CImg<> image) {
    long M00, M10, M01, M11, M20, M02;
    M00 = 0; M10 = 0; M01 = 0; M11 = 0; M20 = 0; M02 = 0;
    cimg_forXY(image,x,y) {
        M00 += image(x,y);
        M10 += x*image(x,y);
        M01 += y*image(x,y);
        M11 += x*y*image(x,y);
        M20 += x*x*image(x,y);
        M02 += y*y*image(x,y);
    }
    long xm = M10/M00;
    long ym = M01/M00;
    long mu20 = M20/M00 - xm*xm;
    long mu02 = M02/M00 - ym*ym;
    long mu11 = M11/M00 - xm*ym;
    long l = sqrt(8 * (mu20 + mu02 + sqrt(4*mu11*mu11 + (mu20-mu02)*(mu20-mu02))));
    long w = sqrt(8 * (mu20 + mu02 - sqrt(4*mu11*mu11 + (mu20-mu02)*(mu20-mu02))));
    cout << "l = " << l << endl;
    cout << "w = " << w << endl;
}