Outils pour utilisateurs

Outils du site


wiki:projets:tracking-processing:tracking-processing

Projets processing

OpenCV: Il s'agit d'une librairie processing utilisant un flux d'images pour identifier et tracker des objets, des formes ou des visages en temps réel grâce à ses algorithmes.On utilise les pixels pour reconnaître des paternes qui sont interprétés selon les besoins. Dans ces programmes, c'est le visage de face que l'on reconnait, chaque visage est inscrit dans son tableau pour qu'on lui attribue du code, relatif à sa position sur l'écran.

✔ Yeux qui suivent

int nb = 10;
float mx;
float my;

eye [] eye = new eye[nb];

import gab.opencv.*;
import processing.video.*;
import java.awt.*;

Capture video;
OpenCV opencv;

void setup() {
  fullScreen();
  video = new Capture(this, 640/2, 480/2);
  opencv = new OpenCV(this, 640/2, 480/2);
  opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); 
  video.start();

  for (int i=0; i<eye.length; i++) {
    eye[i]=new eye();
    eye[i].eyesetup();
  }
}

void draw() {
  opencv.loadImage(video);
  background(0);

  Rectangle[] faces = opencv.detect();
  for (int i = 0; i < faces.length; i++) {

    mx = (((faces[i].x+faces[i].width/2)))*5;
    my = ((faces[i].y+faces[i].height/2))*5;
  }

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

    eye[i].update();
    eye[i].display();
    eye[i].blink();
  }
fill(255,0,0);
 ellipse(mx,my,10,10);
}

void captureEvent(Capture c) {
  c.read();
}


class eye {
  float x;
  float y;
  float midx;
  float midy;
  float langle;
  float ldist;
  float lx;
  float ly;
  int time = 900;
  int size;
  eye() {
  }
  void update() {
    langle = atan2(mx-x, my-y);
    ldist = dist(mx, my, x, y);
    lx = sin(langle)*ldist/30;
    ly = cos(langle)*ldist/70;
  }
  void display() {
    pushMatrix();
    scale(-1, 1);
    translate(-width, 0);
    noStroke();
    fill(255);
    ellipse(x, y, 100, size);
    fill(0);

    ellipse(x+lx, y+ly, 50, 50);
    popMatrix();
  }
  void eyesetup() {
    x=floor(random(width));
    y=floor(random(height));
  }
  void blink() {
    time++; 
    if (size<100) {
      size+=10;
    }
    if (time>1000) {
      size = 0;
      time = floor(random(800));
      x=floor(random(width));
      y=floor(random(height));
    }
  }
}

✔ Yeux qui suivent v2

Pareil mais cette c'est une paire de yeux attribuée à chaque visage qui suit indépendamment cette fois-ci

//import des librairies
import gab.opencv.*;
import processing.video.*;
import java.awt.*;
//initialise openCV
Capture video;
OpenCV opencv;

int nb = 5; //nombre max de paires de yeux

eye [] eye = new eye[nb]; //déclare la classe

void setup() {
  fullScreen(); //plein écran
  video = new Capture(this, 640/2, 480/2); //déclare vidéo comme capture webcam
  opencv = new OpenCV(this, 640/2, 480/2); //déclare openCV 
  opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); //déclare le type de tracking
  video.start(); //lance la vidéo

  for (int i = 0; i < nb; i++) {
    eye[i] = new eye(); //instancie les différentes paires
    eye[i].set(); //donne des positions aléatoires
  }
}

void draw() {
  opencv.loadImage(video);//lance la vidéo
  image(video, 0, 0);//positionne l'image
  background(0);//fond noir
  Rectangle[] faces = opencv.detect();//tracking du visage

  for (int i = 0; i < nb; i++) { //boucle for effective pour chaque paire
    eye[i].shut(); //change l'état des yeux pour les fermer
  }
  for (int i = 0; i < faces.length; i++) { //boucle for pour chaque instance de visage

    eye[i].mx = (((faces[i].x+faces[i].width/2)*6)*-1+width); //définit la position d'un visage sur x
    eye[i].my = ((faces[i].y+faces[i].height/2)*4.5);//définit la position d'un visage sur y
//ces valeurs sont ajustées pour transformer la taille de la capture vers un écran 1920x1080
    eye[i].open(); //change l'état des yeux pour les fermer(si le visage n'est pas détecté on reste sur la valeur donné par eye.shut)
    eye[i].update(); //calcule la position de la pupille
  }
  for (int i = 0; i < nb; i++) {//boucle for effective pour chaque paire
    eye[i].opening();//selon l'état des yeux, va ouvrir ou les fermer
    eye[i].display(); // affiche les différents éléments
    //eye[i].debug(); //pour voir où est positionné le visage sur l'écran
  }
}

void captureEvent(Capture c) {
  c.read(); //lit la vidéo, nécessaire pour OpenCV
}

class eye { //classe pour chaque paire de yeux
  float x; //positionnement de la paire sur l'écran sur x
  float y;//positionnement de la paire sur l'écran sur y
  float mx;//positionnement du visage sur l'écran sur x 
  float my;//positionnement du visage sur l'écran sur y
  float langle;
  float ldist;
  float lx;//valeur vers laquelle la rétine doit se déplacer par rapport au centre pour viser un visage sur x
  float ly;//valeur vers laquelle la rétine doit se déplacer par rapport au centre pour viser un visage sur y
  boolean shutch;//état de l'oeil; ouvert ou fermé
  float shut;//valeur y de l'ellipse qui crée l'oeil
  float pupil;//taille de la rétine
  eye() {
  }

  void shut() {
    shutch = false; //change l'état de la paire sur fermé
  }
  
  void open() {
    shutch = true; // change l'état de la paire sur ouvert
  }
  
  void opening() {
    if (shutch) { //si la paire est ouverte
      if (shut<100) { //si sa taille ne dépasse pas 100
        shut+=10; //ouvre progressivement la paire
      }
    } else { // si la paire est fermée
      if (shut>0) {// si sa taille est supérieure à 0
        shut+=-10; // ferme progressivement la paire
      }
      if (shut<10) { // si les yeux sont fermés
        x = random(200, -200+width); //attribue de nouvelles coordonnées à la paire sur x
        y = random(200, -200+height); //attribue de nouvelles coordonnées à la paire sur y
      }
    }
  }

  void update() {
    langle = atan2(mx-x, my-y); //calcule l'angle vers lequel la rétine doit s'orienter
    ldist = dist(mx, my, x, y); //calcule la distance entre la paire et le visage
    lx = sin(langle)*ldist/30;
    ly = cos(langle)*ldist/30;
  }
  void set() {
    x = random(200, -200+width); //donne des positions aléatoires sur x
    y = random(200, -200+height); //donne des positions aléatoires sur y
  }

  void display() {
    noStroke(); //pas de contours
    fill(255); //remplir en blanc
    ellipse(x-100, y, 100, shut); //premier globe blanc décalé sur la gauche
    ellipse(x+100, y, 100, shut); //deuxième globe blanc décalé sur la droite
    fill(0); //remplir en noir
    ellipse(x+lx-100, y+ly, pupil, pupil); //premiere rétine positionnée par rapport 
    ellipse(x+lx+100, y+ly, pupil, pupil);
    if (shutch) { //si l'oeil est ouvert la rétine est à 50
      pupil=50;
    } else { //sinon si l'oeil est fermé elle est sur 0
      if (shut<10) {
        pupil = 0;
      }
    }
  }
  void debug() { //affiche la position d'un visage
    fill(255, 0, 0);
    ellipse(mx, my, 50, 50);
  }
}

✔ MutiPONG

Version jouable ici »»» https://guyomarch.neocities.org//MUTIPONG.html

/* @pjs preload="MUTI.png"; */

int x;
int y;
int deplacementX;
int deplacementY;
PImage img;
int xp;
int yp;
int xpp;
int ypp;
int score1 = 0;
int score2 = 0;

void setup() {
  img = loadImage("MUTI.png");
  size(900, 900);

  x = 200;  // commençons au centre de l'écran
  y = 200;

  deplacementX = 9;
  deplacementY = -3; 
  xp = 0+50;
  xpp = width-50;

  noStroke();
  fill(0, 0, 0);
}


void draw() {
  mouse();
  auto();
  nettoyer();
  bouger();
  rebondir();
  dessiner();
  image(img, x-50, y-50);
  fill(255);
  rect(xp, yp, 20, 60);
  rect(xpp, ypp, 20, 60);
  textSize(32);
  text((score1), width/2-100, 30); 
  text((score2), width/2+100, 30);
}

void mouse(){
 yp = mouseY; 
}

void auto() {

  if (y<ypp+30) {
    ypp+=-5;
  } else if (y>ypp+30) {
    ypp+=+4;
  }
}

void keyPressed() {

  if (key == 'q' == true) {
    yp= yp+10;
  } else if (key == 'a') {
    yp= yp-10;
  }


  if (key == 'm') {
    ypp= ypp+10;
  } else if (key == 'p') {
    ypp= ypp-10;
  }
}

void nettoyer() {  
  fill(0);
  rect(0, 0, width, height);
}


void rebondir() {

  if ( (x > width-70 && x < width-50 && y>ypp && y<ypp+60 ) || (x < 70 && x > 50 && y>yp && y<yp+60) ) {
    deplacementX = -deplacementX;
    deplacementY = floor(random(-5, 5));
  }

  if ( (y > width && deplacementY > 0) || (y < 0 && deplacementY < 0) ) { 
    deplacementY = -deplacementY;
  }
  if (x < 0) {
    x= height/2;
    y=width/2;
    score2++;
  }
  if (x > width) {
    x= height/2;
    y=width/2;
    score1++;
  }
}



void bouger() {
  x = x + deplacementX;
  y = y + deplacementY;
}


void dessiner() {
  fill(255);
  ellipse(x, y, 20, 20);
}

✔ Cercle qui fait des formes

Un cercle qui suit la souris, ça fait de belles formes

float t;
float t2;
float CELL_SIZE = 50;
float a;
float b;

void setup() {
  fullScreen();
  background(0);
}
void draw() {
  //translate(width/2, height/2);
  t+=0.01;
  t2+=0.001;


noStroke();
  fill(0, 50);
  rect(0, 0, width, height);
  pushMatrix();
  translate(width/2, height/2);

  //scale(2,2);

  //rotate(t);
  for (float y = 0; y<2400; y+=CELL_SIZE) {
    PVector p = new PVector(x1(t+y), (y1(t+y)));
    for (int i = 0; i<200; i++) {

      float oldX = p.x;
      float oldY = p.y;

      float angle = noise(p.x /200, p.y /200 )*PI*(mouseX/100);
      //float angle = noise(x1(t+y)/p.x/200,(y1(t+y))/p.y/200)*PI*10;

      float vx = cos(angle)*mouseY/100;
      float vy = sin(angle)*mouseY/100;
      p.x+=vx;
      p.y+=vy;
      strokeWeight(0.01);
      stroke(255);
      stroke(x1(t+y),y1(t+y),-x1(t+y)+-y1(t+y));
      line(oldX, oldY, p.x, p.y);
    }
  }
  noStroke();
  fill(0);
  //ellipse(0, 0, 300, 300);
  popMatrix();
}

float x1(float t) {
  return cos(t/2)*300;
}
float y1(float t) {
  return sin(t/2)*300;
}

✔ Et encore

Pareil, c'est joli

color c;
float a;
int b;
int d;
int aa =1;
int bb=2;
int dd=3;
float r;
float s=60;
int ss=1;

void setup() {
  fullScreen();
  background(0);
}
void draw() {
  pushMatrix();

  translate(width/2, height/2);
  rotate(r+=0.01);
  scale(s/100);
  for (int i = -width; i <width; i+=100) { 
    for (int i2 = -height; i2 <height; i2+=100) {
      noStroke();
      fill(c);
      strokeWeight(1);
      ellipse(i+i, i2+i2, s, s);
    }
  }


  c = color(a, b, d);
  a+=aa;
  b+=bb;
  d+=dd;
  s+=ss;
  if (a>255 || a < 0) {
    aa=-aa;
  }
  if (b>255 || b < 0) {
    bb=-bb;
  }
  if (d>255 || d < 0) {
    dd=-dd;
  }
  if (s>100 || s<60) {
    ss=-ss;
  }
  popMatrix();
}

✔ Parametric

Un code utile pour comprendre la fonction retour

float t;
int NUM_LINES = 20;


void setup() {
  size(1000, 1000);
  background(20);
}

void draw() {
  background(20, 20, 20);
  stroke(200, 200, 200);
  strokeWeight(1);

  translate(width/2, height/2);
  scale(3, 3);


  for (int i = 0; i < NUM_LINES; i++) {
    PVector p = new PVector(x1(t+i), y1(t+i));
    PVector p2 = new PVector(x2(t+i), y2(t+i));
    float oldX = p.x;
    float oldY = p.y;
    float angle = noise(p.x /200 + t, p.y /200)*PI*2;


    float vx = cos(angle)*20;
    float vy = sin(angle)*15;
    p.x+=vx;
    p.y+=vy;
    line(oldX, oldY,p2.x,p2.y);
  }
  t++;
}

float x1(float t) {
  return cos(t/10)*50;
}
float y1(float t) {
  return sin(t/10)*60+sin(t/20)*40;
}
float x2(float t) {
  return cos(t/20)*70;
}
float y2(float t) {
  return sin(t/10)*40+sin(t/5)*15;
}

Sources: https://www.openprocessing.org/sketch/622355 utilisation des lignes de code pour le calcul du déplacement de la rétine. https://www.youtube.com/watch?v=LaarVR1AOvs&t=555s utilisation de la fonction retour. https://www.youtube.com/watch?v=DuhH6s-afNQ&t=27s utilisation du noise.

wiki/projets/tracking-processing/tracking-processing.txt · Dernière modification: 2019/05/22 18:15 (modification externe)