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

Processing - openCV : Suivi de balle colorée avec élimination des artéfacts par calcul de cohérence des paramètres de l'objet détecté.

Explication

  • Ce programme est une amélioration du programme Processing Suivi de balle colorée (tracking colored ball) avec OpenCV dans Processing
  • Ici, le but est d'éliminer les artéfacts colorés détectés mais qui ne correspondent pas à l'objet détecté. En fait, la librairie openCV donne accès à la fois au rectangle contenant l'objet détecté et l'aire de l'objet détecté. D'où l'idée d'une double analyse de l'objet détecté :
    • que le rectangle soit proche du carré
    • que la surface de l'objet détecté sur la surface du carré contenant soit compatible avec la détection d'un cercle (ratio = pi/4 théorique, 0.5 en pratique)
  • En utilisant ce double contrôle, les artéfacts sont éliminés à 90 % donnant un très bon suivi de balle.

Ressources utiles

  • la librairie openCV

Le programme


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

/////////////// Description du programme ////////////
// Utilise un/des objets PImage (conteneur d'image .jpeg .gif .png et .tga)
// Utilise la librairie OpenCV de capture vidéo et reconnaissance visuelle

// ce programme réalise tout d'abord un traitement détecter l'objet de couleur voulu
// puis on utilise un calcul du ratio de l'aire de la forme / aire rectangle contenant
// pour améliorer la discrimination de l'objet
// le suivi d'objet final obtenu est très bon et les formes "aberrantes" sont ignorées


// XXXXXXXXXXXXXXXXXXXXXX ENTETE DECLARATIVE XXXXXXXXXXXXXXXXXXXXXX

// inclusion des librairies utilisées

import hypermedia.video.*; // importe la librairie vidéo et reconnaissance visuelle OpenCV
// cette librairie doit être présente dans le répertoire /libraries du répertoire Processing
// voir ici : http://ubaa.net/shared/processing/opencv/

import java.awt.Rectangle;
// impporte l'objet rectangle du langage Java qui est utilisé par certaines fonction de la librairie openCV
// l'objet rectangle fournit les champs x,y du centre et hauteur/largeur (height/width) du rectangle
// voir ici : http://download.oracle.com/javase/1.4.2/docs/api/java/awt/Rectangle.html

// déclaration objets

PImage img1, img2; // déclare un/des objets PImage (conteneur d'image)

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

// déclaration variables globales
int xmin, xmax, ymin, ymax; // coordonnées de la zone à tester


//------ 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);


// 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(255,255,0); // couleur remplissage RGB
        stroke (255,0,0); // couleur pourtour RGB
        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
        smooth(); // lissage des formes

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

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

//---- Initialisation des objets PImage ---

        //img1 = createImage(100, 100, RGB); // initialise l'objet PImage (conteneur d'image)
        //image(img1, 0, 0, width/2, height/2); // affiche l'image

        //img2 = loadImage("monimage.jpg"); // charge un fichier image dans l'objet PImage (conteneur d'image)
        // ce fichier doit être présent dans le répertoire du programme ou à l'emplacement indiqué
        //image(img2, 0, 0, width, height);// affiche l'image

        //======== Initialisation Objets OpenCV (vidéo et reconnaissance visuelle =========

        opencv = new OpenCV(this); // initialise objet OpenCV à partir du parent This
        opencv.capture(width,height); // initialise capture flux vidéo
        // width et height sont les valeurs de la taille de la fenêtre processing



} // fin fonction Setup

// XXXXXXXXXXXXXXXXXXXXXX Fonction Draw XXXXXXXXXXXXXXXXXXXX

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


        opencv.read(); // lecture flux vidéo via OpenCV

        img1=opencv.image(); // récupère Image opencv dans Processing

        //traitement de l'image de capture openCV dans Processing

        image( img1, 0, 0 );   // affichage image video

        //----- 1°) application du "mixeur de canaux" avec sortie sur canal Rouge
            //---- coeff à appliquer
            float coefRouge=1; // 100% de rouge
            float coefVert=1.5; // 80% du vert
            float coefBleu=-2; // - 200% du bleu
            //---------- le traitement le plus efficace qui fonctionne est à tester dans Gimp au préalable
            //--------- ici réglage pour balle de couleur orangée ----

          loadPixels(); // charge les pixels de la fenetre d'affichage

          for (int i = 0; i < width*height; i++) { // passe en revue les pixels de l'image - index 0 en premier

            float r = (red(pixels[i])) + (green(pixels[i])*coefVert) + (blue(pixels[i])*coefBleu); // la couleur rouge
            //---- fonction mixeur de canaux
            //---- le canal rouge est le canal de sortie et a pour coeff 1
            //---- auquel on ajoute du vert avec coeff vert
            //---- et du bleu avec coeff bleu

            // les deux autres canaux restent inchangés
            float g = green(pixels[i]); // la couleur verte

            float b = blue(pixels[i]); // la couleur bleue

             pixels[i] = color(r, g, b); // modifie le pixel en fonction

            }

          updatePixels();  // met à jour les pixels  

        //----- 2°) transformation de l'image en monochrome en se basant sur le canal rouge

          loadPixels(); // charge les pixels de la fenetre d'affichage

          for (int i = 0; i < width*height; i++) { // passe en revue les pixels de l'image - index 0 en premier

            float r = red(pixels[i]);// la couleur rouge
            float g = red(pixels[i]); // la couleur verte

            float b = red(pixels[i]); // la couleur bleue

             pixels[i] = color(r, g, b); // modifie le pixel en fonction

            }

          updatePixels();  // met à jour les pixels  

        //------ on applique filtre de seuillage ---
        filter(THRESHOLD,0.7); // applique filtre seuil à la fenetre d'affichage
        // à adapter en fonction de la luminosité ambiante - plus sombre, valeur 0.7, plus lumineux, valeur 0.8 ou plus  

        //--- on récupère l'image transformée ---
        img2=get(0,0,width,height); // récupère image à partir fenetre d'affichage


        //--- on rebascule dans OpenCV ---
        opencv.copy(img2); // charge l'image modifiée dans le buffer opencv

        // trouve les formes à l'aide de la librairie openCV
        // blobs(minArea, maxArea, maxBlobs, findHoles, [maxVertices]);
        Blob[] blobs = opencv.blobs( 10, width*height/4, 5, false, OpenCV.MAX_VERTICES*4 );


        // ---- recharge image vidéo non traitée ---
        opencv.read(); // lecture flux vidéo via OpenCV
        noTint();
        image( opencv.image(), 0, 0 );   // affichage image video


       // xxxxxxxxxxxx Analyse et gestion des formes reconnues xxxxxxxxxxxxxx
      for( int i=0; i<blobs.length; i++ ) { // passe en revue les blobs (= formes détectées)

      //---- détection du "centre" de l'objet ----
      int centreX= blobs[i].centroid.x; // centroid renvoie un objet Point qui fournit x et y
      int centreY= blobs[i].centroid.y; // centroid renvoie un objet Point qui fournit x et y

      /*
      //---------- dessine un cercle autour du centre détecté -----------
      noFill();
      stroke(vert);
      strokeWeight(2);
      ellipse (centreX,centreY, 10,10);
      */


       Rectangle rectangleBlob=blobs[i].rectangle; // récupère le rectangle qui contient la forme détectée

       //---- analyse du rectangle objet ----
       int ratioWH=rectangleBlob.width/rectangleBlob.height; // calcule le ratio largeur/hauteur
       int ratioHW=rectangleBlob.height/rectangleBlob.width; // calcule le ratio hauteur/largeur

       float aireBlob=blobs[i].area; // récupère l'aire de la forme courante


       float ratioAire=aireBlob/(rectangleBlob.width*rectangleBlob.height); // calcul du ratio Aire forme / Aire rectangle
       // aire cercle = pi * r²
       // aire carré = (2r)²=4r²
       // aire cercle/aire carré = (pi * r²)/ (4*r²) = pi/4 = 3/4 env
       // un cercle occupe 3/4 du carré le contenant

       //if ((ratioWH>0.9)) { // si forme proche du carré
       if ((ratioAire>0.5) && ((ratioWH>0.8) || (ratioHW>0.8))) { // si le rapport de l'aire de la forme / rectangle contenant est compatible avec un cercle
        //fill(jaune); // couleur remplissage RGB
        noFill(); // pas de remplissage
        stroke (bleuclair); // couleur pourtour RGB

        //tracé d'un rectangle autour du blob
        rect( rectangleBlob.x, rectangleBlob.y, rectangleBlob.width, rectangleBlob.height );

       }
       else { // trace avec couleurs différentes les rectangles non souhaités


        fill(bleu); // couleur remplissage RGB
        stroke (jaune); // couleur pourtour RGB

        //tracé d'un rectangle autour du blob
        rect( rectangleBlob.x, rectangleBlob.y, rectangleBlob.width, rectangleBlob.height );


       }




        fill(jaune); // couleur remplissage RGB
        stroke (rouge); // couleur pourtour RGB

        // tracé des formes détectées
        beginShape(); // début tracé forme complexe

        for( int j=0; j<blobs[i].points.length; j++ ) { // parcourt tous les points du pourtour du blob
            vertex( blobs[i].points[j].x, blobs[i].points[j].y ); // tracé des points de la forme
        }
        endShape(CLOSE); // tracé forme complexe



    } // ---- fin for blobs --------


        // while(true); // stoppe boucle draw

} // fin de la fonction draw()

// XXXXXXXXXXXXXXXXXXXXXX Autres Fonctions XXXXXXXXXXXXXXXXXXXXXX

 

Voir ici :