View  Edit  Attributes  History  Attach  Print  Search

ACCUEIL | ARDUINO > S'INSTALLER > DEBUTER > APPROFONDIR | PROCESSING | MECATRONIQUE | MATERIEL | OUTILS | TESTS | Plus...|
Python > Shell > ATELIERS Python + Qt > PyQt apps > PyQt+Arduino | Mes Robots | RepRap | Mes lib'Arduino | Mes shields Arduino | Mes distros | Les Mini-PC |
ATELIERS ARDUINO| VIDEOS | COMPRENDRE | REFERENCES | CODER | TECHNIQUE | GNU/LINUX | LIENS | Rien à voir |

Outils > Processing : Codes javacvPro

Processing : OpenCV : librairie javacvPro : Joystick Virtuel par détection, reconnaissance visuelle et suivi de balle en direct à partir d'un flux vidéo webcam. (tracking ball)

Par X. HINAULT - 24 Mars 2012

Explication

  • Ce programme assure la reconnaissance visuelle d'une balle colorée, détecte sa position et analyse celle-ci à la façon d'un Joystick virtuel : l'ordre associé à la position est affiché dans la console sous forme d'une chaine de caractères.
  • On pose ici les bases d'un simple "joystick" visuel par balle colorée et qui peut être couplé par exemple à une carte Arduino contrôlée par le port Série pour le contrôle de moteur, etc...

Matériel et configuration utilisés

  • PC Intel Core Quad 2.33 Ghz
  • Webcam(s) USB Hercules DualPix Exchange
  • Ubuntu 10.04 LTS
  • Processing 1-5
  • Librairie GSVideo 0.9
  • Librairie javacvPro 0.4

Ressources utiles

Le programme


// Programme processing
// généré avec le générateur de code Processing
// du site www.mon-club-elec.fr
// par X. HINAULT - tous droits réservés

// Programme écrit le : 24/03/2012

// ------- Licence du code de ce programme : GPL v3-----
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License,
//  or any later version.
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

/////////////// Description du programme ////////////
// Utilise la librairie GSVideo de capture et lecture vidéo
// Utilise la librairie javacvPro de traitement d'image et reconnaissance visuelle

/*
Détection et suivi de balle à partir d'un flux vidéo webcam à l'aide de la librairie javacvPro
Réalisation d'un "Joystick virtuel"
*/


// XXXXXXXXXXXXXXXXXXXXXX ENTETE DECLARATIVE XXXXXXXXXXXXXXXXXXXXXX

// inclusion des librairies utilisées

import codeanticode.gsvideo.*; // importe la librairie vidéo GSVideo qui implémente GStreamer pour Processing (compatible Linux)
// librairie comparable à la librairie native vidéo de Processing (qui implémente QuickTime..)- Voir Reference librairie Video Processing
// cette librairie doit être présente dans le répertoire modes/java/libraries du répertoire Processing (1-5)
// voir ici : http://gsvideo.sourceforge.net/
// et ici : http://codeanticode.wordpress.com/2011/05/16/gsvideo-09-release

import monclubelec.javacvPro.*; // importe la librairie javacvPro qui implémente le traitement d'image avancé et la reconnaissance visuelle pour Processing
// cette librairie se base sur les fonctions java de la librairie javacv par Samuel Audet : http://code.google.com/p/javacv/
// javacv implémente en Java les centaines de fonctions natives de la librairie OpenCV (2500 algorithmes) !
// la librairie javacvPro doit être présente dans le répertoire modes/java/libraries du répertoire Processing (1-5)
// dispo ici : http://www.mon-club-elec.fr/pmwiki_reference_lib_javacvPro/pmwiki.php
// nécessite également que la librairie native OpenCV 2.3.1 soit installée sur votre ordinateur
// NB : compatibilité avec la plupart des fonctions de la librairie OpenCV pour Processing : http://ubaa.net/shared/processing/opencv/

// déclaration objets

PImage imgSrc, imgDest; // déclare un/des objets PImage (conteneur d'image Processing)

GSCapture cam1; // déclare un objet GSCapture représentant une webcam
// L'objet GSCapture étend PImage - se comporte comme un conteneur des frames issues de la webcam

OpenCV opencv; // déclare un objet OpenCV principal

Blob[] blobs=null; // tableau pour la détection des blobs (contour de forme)


// déclaration variables globales

//------ déclaration des variables de couleur utiles ----
int jaune=color(255,255,0);
int vert=color(0,255,0);
int rouge=color(255,0,0);
int bleu=color(0,0,255);
int noir=color(0,0,0);
int blanc=color(255,255,255);
int bleuclair=color(0,255,255);
int violet=color(255,0,255);

// variable pour la taille de la capture video
int widthCapture=320; // largeur capture
int heightCapture=240; // hauteur capture
int fpsCapture=30; // framerate (image/secondes) pour la capture video

long millis0=0; // variable mémorisation millis()

// XXXXXXXXXXXXXXXXXXXXXX  Fonction SETUP XXXXXXXXXXXXXXXXXXXXXX

void setup(){ // fonction d'initialisation exécutée 1 fois au démarrage

        // ---- initialisation paramètres graphiques utilisés
        colorMode(RGB, 255,255,255); // fixe format couleur R G B pour fill, stroke, etc...
        fill(0,0,255); // couleur remplissage RGB - noFill() si pas de remplissage
        stroke (0,0,0); // couleur pourtour RGB - noStroke() si pas de pourtour
        rectMode(CORNER); // origine rectangle : CORNER = coin sup gauche | CENTER : centre
        imageMode(CORNER); // origine image : CORNER = coin sup gauche | CENTER : centre
        ellipseMode(CENTER); // origine cercles / ellipses : CENTER : centre (autres : RADIUS, CORNERS, CORNER
        //strokeWeight(0); // largeur pourtour
        frameRate(30);// Images par seconde - The default rate is 60 frames per second

        // --- initialisation fenêtre de base ---
        size(widthCapture, heightCapture); // ouvre une fenêtre xpixels  x ypixels
        background(0,0,0); // couleur fond fenetre



// --- initialisation des objets et fonctionnalités utilisées ---

        //======== Initialisation Objets GSVideo (capture et/ou lecture video =========

        // GSCapture(this, int requestWidth, int requestHeight, [int frameRate], [String sourceName], [String cameraName])
        // cam1 = new GSCapture(this, widthCapture, heightCapture,fpsCapture,"v4l2src","/dev/video0"); // Initialise objet GSCapture désignant webcam - avant GSVideo 1.0
        cam1 = new GSCapture(this, widthCapture, heightCapture,"v4l2src","/dev/video1", fpsCapture); // Initialise objet GSCapture désignant webcam - depuis GSVideo 1.0
        // largeur et hauteur doivent être compatible avec la webcam - typiquement 160x120 ou 320x240 ou 640x480...
        // Meilleurs résultats avec framerate webcam entre 20 et 30 et frameRate programme idem ou multiple plus grand (40 pour 20 par ex)
        // la liste des webcam installées sous Ubuntu (Gnu/Linux) est donnée par la commande : ls /dev/video*

        // cam1.play();  // démarre objet GSCapture = la webcam - version GSVideo avant 0.9
        cam1.start();  // démarre objet GSCapture = la webcam - version GSVideo après 0.9

        //======== Initialisation Objets OpenCV (librairie javacvPro : traitement d'image et reconnaissance visuelle) =========

        opencv = new OpenCV(this); // initialise objet OpenCV à partir du parent This
        opencv.allocate(widthCapture,heightCapture); // crée les buffers image de la taille voulue


} // fin fonction Setup

// XXXXXXXXXXXXXXXXXXXXXX Fonction Draw XXXXXXXXXXXXXXXXXXXX

void  draw() { // fonction exécutée en boucle

// Code type capture GSVideo - utilisation possible aussi de captureEvent()

  if (cam1.available() == true) { // si une nouvelle frame est disponible sur la webcam

    cam1.read(); // acquisition d'un frame
    //image(cam1, 0, 0); // affiche image
    //set(0, 0, cam); // affiche image - plus rapide

    imgSrc=cam1.get(); // récupère l'image GS video dans Pimage
    opencv.copy(imgSrc); // charge l'image dans le buffer openCV

    //opencv.copy(cam1.get()); // autre possibilité - charge directement l'image GSVideo dans le buffer openCV

    millis0=millis(); // pour analyse durée - mémorise debut

    opencv.mixerRGBGray(); // isole la couleur orangée par défaut - couleur de la balle

    opencv.threshold(0.7,"BINARY"); // applique seuillage binaire pour éliminer tout ce qui n'est pas orange

    //image(opencv.image(), 0, 0); // affiche image traitée - utile pour debug ou comprendre

    image(imgSrc, 0, 0); // affiche image de départ avant tracé des formes détectées

    blobs=opencv.blobs(); // détection des formes - renvoie tableau de blobs
    //blobs=opencv.blobs(opencv.area()/256,opencv.area(),20, true, 1000,false); // forme détaillée - applique blobs au buffer principal avec paramètres et renvoie tableau d'objets Blob

    blobs=opencv.selectBallBlobs(blobs,false); // sélectionne que les formes compatibles avec une balle

    /*blobs = opencv.selectBlobs(blobs,
                true, 0.7, 0.7,// boolean hwTestIn, float ratioWHTest, float ratioHWTest,
                true, 0.6,// boolean areaTestIn, float areaRatioTest,
                true, true//boolean modeIn, boolean debugIn
                );
    */




    //println("Durée traitement d'1 frame = "+(millis()-millis0) + "ms soit fps max théorique de " + (1000/(millis()-millis0))+" fps !"); // pour analyse - affiche durée traitement image


    //---- analyse de la position du centre du Blob ------

    if (blobs.length>0) { // si le tableau de blobs n'est pas vide

      int x = blobs[0].centroid.x;
      int y = blobs[0].centroid.y;


      if ((x>0) &&  (x<(width/3)) ){ // test si dans la colonne médiane

        if ( (y>(height/3)) &&  (y<(2*height/3)) )  {
          rect(0,height/3,width/3,height/3);// test si dans la colonne médiane
          println("GAUCHE");
        }

      }   // fin if x

      if ((x>width/3) &&  (x<(2*width/3)) ){ // test si dans la colonne médiane

        if ( (y>0) &&  (y<(height/3)) )  {
          rect(width/3,0,width/3,height/3);// test si dans la colonne médiane
          println("HAUT");
        }

        if ( (y>(height/3)) &&  (y<(2*height/3)) )  {
          rect(width/3,height/3,width/3,height/3);// test si dans la colonne médiane
          println("STOP");
        }

        if ( (y>(2*height/3)) &&  (y<(3*height/3)) )  {
          rect(width/3,2*height/3,width/3,height/3);// test si dans la colonne médiane
          println("BAS");          
        }

      }   // fin if x



      if ((x>(2*width/3)) &&  (x<(3*width/3)) ){ // test si dans la colonne médiane

        if ( (y>(height/3)) &&  (y<(2*height/3)) )  {
          rect(2*width/3,height/3,width/3,height/3);// test si dans la colonne médiane
          println("DROITE");
        }

      }   // fin if x

    } // fin if tableau pas vide

    //------- tracé du blob --------

        // void drawRectangleBlobs (Blob[] blobsIn, int xRefIn, int yRefIn, float scaleIn, int colorStrokeIn, int strokeWeightIn, boolean fillIn, int colorFillIn)
    //opencv.drawRectBlobs(blobs); // javacvPro : trace le rectangle de tous les blobs détectés
    opencv.drawRectBlobs(blobs, 0,0,1,vert,2,false,0); // forme détaillée - javacvPro : trace le rectangle de tous les blobs détectés

    // void drawBlobs (Blob[] blobsIn, int xRefIn, int yRefIn, float scaleIn, int radius, int colorStrokeIn, int strokeWeightIn, boolean fillIn, int colorFillIn, int mode)
    //opencv.drawBlobs (blobs); // javacvPro : trace le contour de tous les blobs détectés
    opencv.drawBlobs (blobs, 0,0,1,5,rouge,1,true,jaune,1); // forme détaillée - javacvPro : trace le contour de tous les blobs détectés

    // nb : mettre dessin centre après dessin blob, sinon invisible
    // void drawCentroidBlobs (Blob[] blobsIn, int xRefIn, int yRefIn, float scaleIn, int radius, int colorStrokeIn, int strokeWeightIn, boolean fillIn, int colorFillIn)
    //opencv.drawCentroidBlobs( blobs); //  javacvPro : trace le centre de tous les blobs détectés
    opencv.drawCentroidBlobs( blobs, 0,0,1,10,jaune,1,true,rouge); // forme détaillée -javacvPro : trace le centre de tous les blobs détectés


    //--- mémo : les champs de l'objet Blob --
    /*
    int area : l'aire du contour
    int lengthArc : la longueur du contour (ou périmètre)
    int length : le nombre de points du Blob
    point centroid : le point central du contour, les coordonnées étant fournies par centroid.x et centroid.y
    point[] points : le tableau contenant les points du contour
    rectangle rectangle : le rectangle entourant le Blob, accessible depuis rectangle.x, rectangle.y, rectangle.width, rectangle.height
    */



  } // fin if available



} // fin de la fonction draw()

// XXXXXXXXXXXXXXXXXXXXXX Autres Fonctions XXXXXXXXXXXXXXXXXXXXXX


//------------- Fonction d'arret de Processing ----

public void stop(){ // fonction d'arrêt de Processing

        cam1.delete(); // efface l'objet GScapture

        super.stop(); // obligatoire

} // fin fonction stop()


//XXXXXXXXXXXXXXXXXX Fin du programme XXXXXXXXXXXXXXXXX