Issues with TargetRegion in frame differencing
in
Core Library Questions
•
4 months ago
Hi all
Im working with sound and spaces and trying to set an installation, based on webcam triggers.
I was wondering if anyone can help.
I have 5 targetRegions to trigger and play a file, however only one is actually being triggered.
If anyone can point out where Im going wrong thats would be awesome.
Many thanks
Rina
- import processing.video.*;
- // minim stuff
- import ddf.minim.*;
- Minim minim;
- AudioPlayer player;
- //
- // webcam stuff
- int numPixels;
- int[] previousFrame;
- Capture video;
- //
- // target regions specified as a rectangle x,y,width,height
- int[] targetRegion_1 = { 0,0, 50,480 };
- int[] targetRegion_2 = { 100,0, 50,480 };
- int [] targetRegion_3 = {200,0, 50, 480};
- int [] targetRegion_4 = {300,0, 50, 480};
- int [] targetRegion_5 = {400, 0, 50, 480};
- //int [] targetRegion_6 = {500, 0, 50, 480};
- // amount of delay before allowing trigger
- int totDelay = 5; // just using cycles, not time
- int delayCounter = 0;
- // to determine when sound has finished
- boolean isPlaying=false;
- String soundFileName = "spotsound1.mp3";
- // amount of change required before trigger active, not true percentage
- float thresholdPercentage = 2.0;
- 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();
- noFill();
- // minim stuff
- minim = new Minim(this);
- // load a file, give the AudioPlayer buffers that are 2048 samples long
- player = minim.loadFile(soundFileName, 2046);
- // play the file
- // player.play(); // actually, not here, only start after motion
- }
- void draw() {
- if (video.available())
- {
- // When using video to manipulate the screen, use video.available() and
- // video.read() inside the draw() method so that it's safe to draw to the screen
- video.read(); // Read the new frame from the camera
- video.loadPixels(); // Make its pixels[] array available
- float movementAsPercentage_1 = checkMovement(targetRegion_1[0],targetRegion_1[1],targetRegion_1[2],targetRegion_1[3]);
- float movementAsPercentage_2 = checkMovement(targetRegion_2[0],targetRegion_2[1],targetRegion_2[2],targetRegion_2[3]);
- float movementAsPercentage_3 = checkMovement(targetRegion_3[0],targetRegion_3[1],targetRegion_3[2],targetRegion_3[3]);
- float movementAsPercentage_4 = checkMovement(targetRegion_4[0],targetRegion_4[1],targetRegion_4[2],targetRegion_4[3]);
- float movementAsPercentage_5 = checkMovement(targetRegion_5[0],targetRegion_5[1],targetRegion_5[2],targetRegion_5[3]);
- //float movementAsPercentage 6 = checkMovement(targetRegion_6[0],targetRegion_6[1],targetRegion_6[2],targetRegion_6[3]);
- if(!player.isPlaying())
- {
- if(isPlaying) // so the sound has just finished
- {
- delayCounter=0; // start delay before allowing restart of playing sound
- isPlaying=false;
- }
- }
- if(movementAsPercentage_1>0 || movementAsPercentage_2>0 || movementAsPercentage_3>0 || movementAsPercentage_4>0 || movementAsPercentage_5>0)
- {
- // println(movementAsPercentage); // for debugging...
- updatePixels();
- }
- //
- // add one to delay counter if in delay period
- if(delayCounter<totDelay)
- {
- delayCounter++;
- }
- if(movementAsPercentage_1 > thresholdPercentage || movementAsPercentage_2 > thresholdPercentage || movementAsPercentage_3 > thresholdPercentage || movementAsPercentage_4 > thresholdPercentage || movementAsPercentage_5 > thresholdPercentage) // if movement detected
- {
- noFill();
- stroke(255,0,0); // red box if in delay period
- // if not in the delay period
- // check if reached delay before allowing trigger
- if(delayCounter==totDelay)
- {
- stroke(255,255,0); // yellow box=triggered but already playing sound
- // if the sound is not already playing
- if(!player.isPlaying())
- {
- stroke(0,255,0); // green box = start sound
- // then play the sound from the beginning (0)
- isPlaying=true;
- player.play(0);
- }
- }
- // draw the rectangle around the region
- rect(targetRegion_1[0],targetRegion_1[1],targetRegion_1[2],targetRegion_1[3]);
- rect(targetRegion_2[0],targetRegion_2[1],targetRegion_2[2],targetRegion_2[3]);
- rect(targetRegion_3[0],targetRegion_3[1],targetRegion_3[2],targetRegion_3[3]);
- rect(targetRegion_4[0],targetRegion_4[1],targetRegion_4[2],targetRegion_4[3]);
- rect(targetRegion_5[0],targetRegion_5[1],targetRegion_5[2],targetRegion_5[3]);
- //rect(targetRegion_6[0],targetRegion_6[1],targetRegion_6[2],targetRegion_6[3]);
- }
- else
- {
- if(player.isPlaying())
- {
- noFill();
- stroke(155,155,155); // grey box = sound is playing
- rect(targetRegion_1[0],targetRegion_1[1],targetRegion_1[2],targetRegion_1[3]);
- rect(targetRegion_2[0],targetRegion_2[1],targetRegion_2[2],targetRegion_2[3]);
- rect(targetRegion_3[0],targetRegion_3[1],targetRegion_3[2],targetRegion_3[3]);
- rect(targetRegion_4[0],targetRegion_4[1],targetRegion_4[2],targetRegion_4[3]);
- rect(targetRegion_5[0],targetRegion_5[1],targetRegion_5[2],targetRegion_5[3]);
- //rect(targetRegion_6[0],targetRegion_6[1],targetRegion_6[2],targetRegion_6[3]);
- }
- // player.pause();
- }
- }
- }
- //=========================
- // returns the amount of movement in the specified region as a percentage(ish)
- float checkMovement(int x, int y, int w, int h)
- {
- int movementSum = 0; // Amount of movement in the frame
- for(int ypos = 0;ypos < video.height; ypos ++)
- {
- for(int xpos = 0;xpos < video.width; xpos ++)
- {
- int index = xpos + (ypos * video.width);
- color currColor = video.pixels[index];
- if( xpos >= x && xpos < x+w && ypos >= y && ypos < y+h)
- {
- color prevColor = previousFrame[index];
- 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);
- //
- movementSum += diffR + diffG + diffB;
- // Render the difference image to the screen
- pixels[index] = color(diffR, diffG, diffB);
- // The following line is much faster, but more confusing to read
- //pixels[i] = 0xff000000 | (diffR << 16) | (diffG << 8) | diffB;
- // Save the current color into the 'previous' buffer
- }
- else
- {
- // if this pixel isnt in our area of interest, just show current video frame colour
- pixels[index] = currColor;
- }
- // keep the current pixel colour for comparison next time
- previousFrame[index] = currColor;
- }
- }
- int totalPossibleMovement = w*h*255*3; // width * height (of area of interest) * 255 (is the max difference per colour) * 3 (number of colour channels eg:rgb)
- float percentage = (float)movementSum / (float)totalPossibleMovement;
- percentage = percentage * 100.0f;
- return percentage;
- }
- void stop()
- {
- // always close Minim audio classes when you are done with them
- player.close();
- // always stop Minim before exiting
- minim.stop();
- super.stop();
- }
1