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 – Capture vidéo avec openCV : Centrage de la webcam sur une cible.

Explication

  • Le but ici est de centrer la webcam sur une cible et de paramétrer aussi précisément que possible l'interface Processing pour pouvoir extraire les coordonnées réelle en cm d'un point de la cible à partir de sa position en pixel dans l'image et inversement.
  • Il s'agit ici d'un code préparatoire à des fonctions de détection d'objet présent dans une zone cible avec extraction de ses coordonnées réelles en cm à partir de la position dans l'image (pixels).

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

Ressources utiles

  • librairie OpenCV

Procédure à suivre

  • Préparer une cible carrée, par exemple en prenant une page A4 à petits carreaux. Tracer un carré de 18cm de côté (valeur utilisée par code présenté ici) et tracer une croix au centre de la cible.
  • Lancer le programme Processing ci-dessous.
  • Positionner la webcam au dessus de la cible de façon à ce que toute la cible soit vue par la webcam. Pour limiter les aberrations optiques, faire en sorte que la surface de la cible n'occupe que les 2/3 de la surface vue par la webcam.
  • Une fois fait, positionner la cible sous la webcam en centrant sur la croix le plus précisément possible.
  • Prendre une règle, la poser sous la webcam dans le sens de la largeur et mesurer précisément la largeur de l'image en lisant sur l'image vidéo.
  • Toujours avec la règle, faire la même chose pour la longueur.
  • Stopper le programme. Modifier les valeurs en cm de largeur et d'hauteur de l'image dans le programme avec les valeurs mesurées.
  • Relancer le programme : les points doivent se positionner assez précisément aux coins du carré de la cible.

En pratique, on obtient assez facilement une précision de l'ordre du mm pour un carré de 18cmx18cm ce qui est tout à fait correct.

Le programme


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

/////////////// Description du programme ////////////
// Utilise le port Serie
// Utilise la librairie OpenCV de capture vidéo et reconnaissance visuelle

// XXXXXXXXXXXXXXXXXXXXXX ENTETE DECLARATIVE XXXXXXXXXXXXXXXXXXXXXX

// inclusion des librairies utilisées

import processing.serial.*; // importe la librairie série processing

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/

// déclaration objets

// --- port Série ---
Serial  myPort; // Création objet désignant le port série

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

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

//--- variables globales utiles
int tailleCroix=50; // 1/2 largeur bras croix

//--- pour étalonner ces valeurs, poser une règle devant la webcam
// et lire sur l'image vidéo la largeur en cm vue par la webcam

float largeurImageCm=30.5; // largeur en cm de l'image capturée par la webcam
float hauteurImageCm=23.2; // hauteur en cm de l'image capturée par la webcam


float tailleZoneUtileCm=18; // taille de la zone centrale carrée de travail utilisée
// idéalement cette zone ne doit pas dépasser 2/3 de la taille totale de l'image car les bords de l'image sont déformés par l'objectif

float xPixel, yPixel, xCm, yCm; // variables utiles

float[] xPixelCoin=new float[4]; // tableau pour les x des coins de la zone
float[] yPixelCoin=new float[4]; // tableau pour les y des coins de la zone




// 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(20);// Images par seconde

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

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

        //------------- initialisation port série ----
        println(Serial.list()); // affiche dans la console la liste des ports séries
        // Vérifier que le numéro du port série utilisé est le meme que celui utilisé avec  Serial.list()[index]
        myPort = new Serial(this, Serial.list()[0], 115200); // Initialise une nouvelle instance du port Série
        //myPort = new Serial(this, "/dev/ttyUSB0", 115200); // Initialise une nouvelle instance du port Série
        myPort.bufferUntil('\n'); // attendre arrivée d'un saut de ligne pour générer évènement série

        //======== 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

//------ calcul des coordonnées des coins de la zone utile centrée sur le centre de l'image ---

        //--- point angle sup gauche ---
        xCm=(largeurImageCm/2)-(tailleZoneUtileCm/2);
        println("xCm="+xCm);

        xPixelCoin[0]=map(xCm,0,largeurImageCm,0,width);
        println("xPixel 0="+xPixelCoin[0]);

        yCm=(hauteurImageCm/2)-(tailleZoneUtileCm/2);
        println("yCm="+yCm);

        yPixelCoin[0]=map(yCm,0,hauteurImageCm,0,height);
        println("yPixel 0="+yPixelCoin[0]);

        //--- point angle sup droit ---
        xCm=(largeurImageCm/2)+(tailleZoneUtileCm/2);
        println("xCm="+xCm);

        xPixelCoin[1]=map(xCm,0,largeurImageCm,0,width);
        println("xPixel 1="+xPixelCoin[1]);

        yCm=(hauteurImageCm/2)-(tailleZoneUtileCm/2);
        println("yCm="+yCm);

        yPixelCoin[1]=map(yCm,0,hauteurImageCm,0,height);
        println("yPixel 1 ="+yPixelCoin[1]);

        //--- point angle inf gauche ---
        xCm=(largeurImageCm/2)-(tailleZoneUtileCm/2);
        println("xCm="+xCm);

        xPixelCoin[2]=map(xCm,0,largeurImageCm,0,width);
        println("xPixel 2="+xPixelCoin[2]);

        yCm=(hauteurImageCm/2)+(tailleZoneUtileCm/2);
        println("yCm="+yCm);

        yPixelCoin[2]=map(yCm,0,hauteurImageCm,0,height);
        println("yPixel 2="+yPixelCoin[2]);

        //--- point angle inf droit ---
        xCm=(largeurImageCm/2)+(tailleZoneUtileCm/2);
        println("xCm="+xCm);

        xPixelCoin[3]=map(xCm,0,largeurImageCm,0,width);
        println("xPixel 3="+xPixelCoin[3]);

        yCm=(hauteurImageCm/2)+(tailleZoneUtileCm/2);
        println("yCm="+yCm);

        yPixelCoin[3]=map(yCm,0,hauteurImageCm,0,height);
        println("yPixel 3="+yPixelCoin[3]);


} // fin fonction Setup

// XXXXXXXXXXXXXXXXXXXXXX Fonction Draw XXXXXXXXXXXXXXXXXXXX

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

        //------------- Code pour port série ----
        //  myPort.write('H'); // envoie le caractère sur le port Série
        // myPort.write("chaine\n"); // envoie la chaine suivi saut ligne sur le port Série
        opencv.read(); // lecture flux vidéo
        image( opencv.image(), 0, 0 );   // affichage image video

        //--- dessine croix centrale
        stroke(rouge);
        line ((width/2)-tailleCroix,height/2,(width/2)+tailleCroix,height/2); // trait horizontal
        line (width/2,(height/2)-tailleCroix,width/2,(height/2)+tailleCroix); // trait horizontal


        //---- dessine les points des angles par calcul ---

        stroke(jaune);
        fill(violet);

        for (int i=0; i<4; i++) {

                  ellipse (xPixelCoin[i],yPixelCoin[i],5,5);  // trace point      

        }        




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

} // fin de la fonction draw()

// XXXXXXXXXXXXXXXXXXXXXX Autres Fonctions XXXXXXXXXXXXXXXXXXXXXX