Son et video : déclencher un son grâce à la webcam

Cette application simple, régulièrement demandée, permet de démarrer un son lorsque que du mouvement est détecté.

Précédent | 26/26

Deux librairies : video et minim

La librairie video, incluse dans Processing, s’occupe de la partie webcam. Le code ici utilisé pour la vidéo est le "frame differencing", la comparaison de l’image captée par la webcam avec celle qui a été capturée juste avant, et de compter les pixels qui sont différents.

Pour éviter les sautes trop brusques et les déclenchement inopportuns, une moyenne est faite sur une vingtaine de frames, moins d’une seconde donc.
Il y a aussi un seuil de déclenchement, car même si rien ne se passe, les images capturées par la caméra sont légèrement différentes. Ce seuil est de 2 millions. Ce n’est pas deux millions de pixels mais deux millions de valeurs de couleurs.
Ce seuil peut être augmenté ou réduit avec les flèches haut et bas.

Minim est la librairie qui s’occupe de jouer le son. les fonction play, pause et cue son utilisées pour lire, stopper et ramener le son au début.

Voici le code prêt à l’emploi :

/**
* Frame Differencing
* by Golan Levin.
*
* Quantify the amount of movement in the video frame using frame-differencing.
* lecture de son sur base de mouvement
Les fleche up and down permettent de régler le seuil
shift permet d'afficher la moyenne de mouvement
*/
// librairie video
import processing.video.*;
Capture video;

//Librairie minim
import ddf.minim.*;
AudioPlayer player;
Minim minim;

boolean playing=false;

// les premiers frames produisent beaucoup de differencing
// une moyenne négative évite un déclenchement au démarrage
float averagemove=-10000000;
int seuil=2000000; // seuil de déclenchement
int numPixels;
int[] previousFrame;

void setup() {
 size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
 // Uses the default video input, see the reference if this causes an error
 video = new Capture(this, width, height, 24);
 numPixels = video.width * video.height;
 // Create an array to store the previously captured frame
 previousFrame = new int[numPixels];
 loadPixels();

 minim = new Minim(this);
 player = minim.loadFile("son.mp3", 2048);
 // play the file
 player.pause();
 fill(255,0,0); // couleur par defaut - rouge
}

void draw() {
 if (video.available()) {
   video.read(); // Read the new frame from the camera
   video.loadPixels(); // Make its pixels[] array available

   int movementSum = 0; // Amount of movement in the frame
   for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
     color currColor = video.pixels[i];
     color prevColor = previousFrame[i];
     // Extract the red, green, and blue components from current pixel
     int currR = (currColor >> 16) & 0xFF; // Like red(), but faster
     int currG = (currColor >> 8) & 0xFF;
     int currB = currColor & 0xFF;
     // Extract red, green, and blue components from previous pixel
     int prevR = (prevColor >> 16) & 0xFF;
     int prevG = (prevColor >> 8) & 0xFF;
     int prevB = prevColor & 0xFF;
     // Compute the difference of the red, green, and blue values
     int diffR = abs(currR - prevR);
     int diffG = abs(currG - prevG);
     int diffB = abs(currB - prevB);
     // Add these differences to the running tally
     movementSum += diffR + diffG + diffB;

     // Save the current color into the 'previous' buffer
     previousFrame[i] = currColor;
   }

   // calcul d'une moyenne
   averagemove=((averagemove *20) + movementSum)/21;

   if(averagemove > 1500000 && playing==false) {
     player.play();
     println("demarre");
     playing=true;
     fill(0,255,0); // vert
   }
   else if(player.position() > player.length()-1100) {
     println("stop");
      player.pause();
     player.cue(0);
     
     playing=false;
     fill(255,0,0); // rouge
   }
   rect(0,0,width,height);
 }
}

void keyPressed() {
 if (key == ' ' && playing==true) {
   println("stop");
   player.pause();
   player.cue(0);
   averagemove=0;

   playing=false;
   fill(255,0,0);
 }

 if (key == CODED) {
   if (keyCode == UP) {
     seuil+=100000;
     println("seuil : " + seuil);
   }
   else if (keyCode == DOWN) {
     seuil -=100000;
     if(seuil < 100000) {
       seuil=100000;
     }
     println("seuil : " + seuil);
   }
   else if (keyCode  == SHIFT) {
     println("mouvement : " + averagemove);
   }
 }
}

Forum

  • Son et video : déclencher un son grâce à la webcam par miestormen , 22 avril 2010

    hej hej,

    quand j’essaye le code, il me dit :
    expecting DOT, found prevideo
    et me souligne en jaune ceci :
    int[] previousFrame ;

    ...?

  • Son et video : déclencher un son grâce à la webcam par Stéphane Noel , 10 juin 2010

    Ha oui, il faut déplacer l’inclusion des librairies vers le haut. Je corrige.