http://code.feralj.fr/2015/06/28/frame-differencing-avec-processing-round-2/

 

Ci-dessous, un petit programme qui utilise le frame differencing pour activer du son, plus ou moins fort.

Dans le domaine de la vision numérique, j’avais lu plus tôt que les nombreux algorithmes de détection (de contours, de fond, de visage…) ne se basent pas sur des images colorées RVB mais bien sur la luminosité d’une image. Les informations noir et blanc suffisent, et sont moins lourdes à exécuter. En prenant compte de cela, j’ai changé à l’intérieur de la boucle du code :

color present = cam.pixels[i];
color passe = imagePasse.pixels[i];

float rougePresent = red(present);
float vertPresent = green(present);
float bleuPresent = blue(present);

float rougePasse = red(passe);
float vertPasse = green(passe);
float bleuPasse = blue(passe);

float diff = dist(rougePresent, vertPresent, bleuPresent, rougePasse, vertPasse, bleuPasse);

par:

color present = cam.pixels[i];
color passe = imagePrec.pixels[i];

float lumPresent = brightness(present);
float lumPasse = brightness(passe);

float diff = dist(lumPresent, lumPresent, lumPasse, lumPasse);

C’est quand même plus conçis comme ça.

Note « Bon à savoir »: float diff = dist(lumPresent, lumPresent, lumPasse, lumPasse); Ça correspond à faire une norme euclidienne de la valeur « lumPresent ».

J’ai également ajouté un seuil de sensibilité qui ne prend pas en compte des petits changements bénins de la capture (le bruit d’image) avec une bête condition qui dit « si le taux de changement est inférieur à la variable seuil, alors autant ignorer cette différence »:

if(diff < seuil){ diff = 0; }

J’ai déclaré ma variable seuil à 15 dans l’en-tête de mon programme.

Également, j’ai remarqué que l’animation qui représentait la quantité de mouvement de la capture était un peu frénétique; Pour supprimer ces sauts brutaux et « lisser » un peu l’animation, je suis passé par une petite moyenne pondérée (merci au Mooc du CNAM) que voici:

Capture d’écran 2015-06-28 à 12.20.03

Et ça me fait quelque chose comme ça (j’ai déclaré mon variable alpha en haut du programme. J’ai mis sa valeur à 0.5, à vous de voir ce qui vous arrange):

float moyenneMouvement = mouvement/cam.pixels.length;
r = (1 – alpha) * moyenneMouvement + alpha * r; //adoucit l’animation

À alpha = 0, notre animation n’est pas adoucie, et la réaction est immédiate.
À alpha = 0.9 notre animation est très adoucie, mais il y a du retard et peu de sensibilité.

Et voilà ci-dessous le code complet ou bien à télécharger ici.

import processing.video.*;Capture cam;
int seuil = 15;
PImage imagePrec;float alpha = 0.4;
float r = 0;void setup(){
size(320, 240);
cam = new Capture(this, 320, 240);
cam.start();
imagePrec = createImage(width, height, RGB);
}void captureEvent(Capture cam){
cam.read();
}void draw(){
background(0);
image(cam, 0, 0);

imagePrec.copy(cam, 0, 0, width, height, 0, 0, width, height);
float mouvement = 0;

cam.loadPixels();
imagePrec.loadPixels();
for(int i = 0; i < cam.pixels.length; i++){
color present = cam.pixels[i];
color passe = imagePrec.pixels[i];
float lumPresent = brightness(present);
float lumPasse = brightness(passe);
float diff = dist(lumPresent, lumPresent, lumPasse, lumPasse);
if(diff < seuil){
diff = 0;
}
mouvement += diff;
}
float moyenneMouvement = mouvement/cam.pixels.length;
r = (1 – alpha) * moyenneMouvement + alpha * r;
ellipse(width/2,height/2,r*2,r*2);
}

EDIT : voici le .zip d’un programme qui permet de déclencher du son au mouvement. Hop! Cadeau!