Ici un cercle poursuit le point le plus brillant et relativement rouge. On pourrait juste choisir de traquer le point le plus lumineux juste avec la fonction brightness()…

tracking

Comme dans le chapitre « Frame differencing« , une moyenne pondérée pour lisser la trajectoire de la poursuite de l’objet.

 

import processing.video.*;

int x, y;
//VALEURS LISSEES
float X, Y;
float alpha = 0.6; //PETITE ASTUCE 😉
float seuil = 240;

Capture cam;

void setup() {
  size(640, 420, P2D);
  cam = new Capture(this);
  cam.start();
}

void draw() {
  if (cam.available()) {
    cam.read();
    cam.loadPixels();
    float luminositeMax = 0;
    int indexPixelLePlusBrillant = 0; 
    for (int i = 0; i < cam.pixels.length; i++) { 
      if (red(cam.pixels[i]) > luminositeMax && 
          green(cam.pixels[i]) < seuil  && 
          blue(cam.pixels[i]) < seuil) {
        luminositeMax = red(cam.pixels[i]);
        indexPixelLePlusBrillant = i;
        x = indexPixelLePlusBrillant % cam.width;
        y = indexPixelLePlusBrillant / cam.width;
        //ASTUCE POUR LISSAGE
        X = (1 - alpha) * x + alpha * X; //adoucit l’animation
        Y = (1 - alpha) * y + alpha * Y; //adoucit l’animation
      }
    }
    cam.updatePixels();
  }
  image(cam, 0, 0);

  ellipse(X, Y, 20, 20);
}

Améliorer la poursuite: traiter l’image (mais s’excuser aussitôt)

Selon la caméra, l’environnement filmé, la poursuite d’un point lumineux ou d’un objet coloré par exemple est plus ou moins réussi. Avant de commencer à traquer les pixels les plus [rouges][lumineux][bleus].etc on pourrait supprimer le maximum d’informations inutiles dans l’image. Cas concret: je veux poursuivre ce post-it orange.

Je veux donc traquer que des couleurs dans la tranche des orangés. L’espace colorimétrique RGB (synthèse additive) n’est pas forcément le plus approprié pour cela, nous voulons sélectionner, non pas une couleur particulière (si il y a des changements de lumière selon l’heure, ou l’éclairage) mais une tranche de couleurs au sein de l’espace HSB ( = Hue, saturation, brightness = Teinte, saturation, luminosité).

B_Cercle-Cromtic

Le orange dans cette espace colorimétrique plus intuitif est borné entre le rouge et le jaune. Ci-dessous un petit programme qui retourne la valeur des teintes des couleurs de l’esace HSB.

void setup() {
  size(360, 200);
  colorMode(HSB, 360, 100, 100);
}

void draw(){
  for (int i = 0; i < 360; i++) {
    stroke(i, 100, 100);
    line(i, 0, i, 200);
  }
  text(mouseX, width/2, height/2);
}

Grâce à ce petit programme je sais que les orangés se situe grossièrement entre 5 et 60 (à affiner ou pas).

Le programme ci-dessous qui ignore les couleurs qui ne sont pas orangées (les pixels deviennent noir dans ce cas là) sinon ils deviennent blancs.

import processing.video.*;

Capture cam;
PImage camTraitee;

int nombreCouleurs = 32;
int d = 360 / nombreCouleurs;
color[] couleurs = new color[nombreCouleurs];

void setup(){
  size(640, 420, P2D);
  for (int i = 0; i < nombreCouleurs; i++) {
    couleurs[i] = color(i * d, 100, 100);
  }
  cam = new Capture(this, 320, 210);
  cam.start();
  camTraitee = new PImage(320, 210, RGB);
}

void draw(){
  if(cam.available()){
    cam.read();
    camTraitee.copy(cam, 0, 0, cam.width, cam.height, 0, 0, cam.width, cam.height);
    camTraitee.loadPixels();
    for(int i = 0; i < camTraitee.pixels.length-1; i++){ 
        if(hue(camTraitee.pixels[i]) >= 5 && hue(camTraitee.pixels[i]) <= 60 
        && saturation(camTraitee.pixels[i]) > 50){
        camTraitee.pixels[i] = color(255);
      } else {
        camTraitee.pixels[i] = color(0);
      }
      //Suppr Bruit
      if(camTraitee.pixels[i] == color(255)){
        if(camTraitee.pixels[i+1] == color(0)){
          camTraitee.pixels[i] = color(0);
        }
      }
    }
    cam.updatePixels();
    camTraitee.updatePixels();
  }
  image(cam, 0, 0);
  image(camTraitee, 320, 0);
}

Également, il y a du bruit visuel qui peut fausser les résultats…

//Suppr Bruit
if(camTraitee.pixels[i] == color(255)){
if(camTraitee.pixels[i+1] == color(0)){
camTraitee.pixels[i] = color(0);
}
}

…Cela permet d’ignorer les pixels esseulés qui peuvent s’afficher à cause du bruit. De façon plus optimale, on pourrait appliquer un flou gaussien par convolution de la matrice comme dirait Laurel, suivi de Hardi.

Capture d’écran 2016-06-02 à 14.56.42

La même chose avec une feuille jaune…

trackingJaune

Maintenant, on peut tracker les points qui ne sont pas noirs (ici blancs ou jaune)… 😉 À suivre: Segmentation.