We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
Pixel Differences (Read 1945 times)
Pixel Differences
Jan 17th, 2010, 12:27pm
 
Hey,

The Background Subtraction tutorial is the only source of code that I've found in the past few days that is the closest to what I wish to get.

Essentially what I would want is to capture a frame and have that frame be a static image (compared to their current code making that image black); then any difference in the frame (whether its color, movement) to be turned to black.

I know that this forum might get this question or ones like it a lot, but I've been searching like a jackal trying to find something similar but I haven't come up with anything.

For any reference this is the code I'm looking at modifying:

Code:
import processing.video.*;

color black = color(0);
int numPixels;
int[] backgroundPixels;
Capture video;

void setup() {
 // Change size to 320 x 240 if too slow at 640 x 480
 size(640, 480, P2D);
 
 video = new Capture(this, width, height, 24);
 numPixels = video.width * video.height;
 // Create array to store the background image
 backgroundPixels = new int[numPixels];
 // Make the pixels[] array available for direct manipulation
 loadPixels();
}

void draw() {
 if (video.available()) {
   video.read(); // Read a new video frame
   video.loadPixels(); // Make the pixels of video available
   // Difference between the current frame and the stored background
   int presenceSum = 0;
   for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
     // Fetch the current color in that location, and also the color
     // of the background in that spot
     color currColor = video.pixels[i];
     color bkgdColor = backgroundPixels[i];
     // Extract the red, green, and blue components of the current pixel’s color
     int currR = (currColor >> 16) & 0xFF;
     int currG = (currColor >> 8) & 0xFF;
     int currB = currColor & 0xFF;
     // Extract the red, green, and blue components of the background pixel’s color
     int bkgdR = (bkgdColor >> 16) & 0xFF;
     int bkgdG = (bkgdColor >> 8) & 0xFF;
     int bkgdB = bkgdColor & 0xFF;
     // Compute the difference of the red, green, and blue values
     int diffR = abs(currR - bkgdR);
     int diffG = abs(currG - bkgdG);
     int diffB = abs(currB - bkgdB);
     // Add these differences to the running tally
     presenceSum += diffR + diffG + diffB;
     // Render the difference image to the screen
     //pixels[i] = color(diffR, diffG, diffB);
     // The following line does the same thing much faster, but is more technical
     pixels[i] = 0xFF000000 | (diffR << 16) | (diffG << 8) | diffB;
   }
   updatePixels(); // Notify that the pixels[] array has changed
 }
}

// When a key is pressed, capture the background image into the backgroundPixels
// buffer, by copying each of the current frame’s pixels into it.
void keyPressed() {
 video.loadPixels();
 arraycopy(video.pixels, backgroundPixels);
}

Re: Pixel Differences
Reply #1 - Jan 17th, 2010, 7:40pm
 
Thanks to anyone who has overlooked at the code at least: I've been trying to ask the program to load a movie - compare that movie's pixels against the live feed of a webcam and make it come up with the difference from both.

Code:
import processing.video.*;

int numPixels;
int camPixels;
int[] backgroundPixels;
// int[] cam;
Movie cam;
Capture video;

void setup() {
// Change size to 320 x 240 if too slow at 640 x 480
size(640, 480, P2D);

video = new Capture(this, width, height, 24);
numPixels = video.width * video.height;
// Create array to store the background image
camPixels = cam.width * cam.height;
cam = new Movie(this, "cam.mov");
cam.loop();
backgroundPixels = new int[camPixels];
// Make the pixels[] array available for direct manipulation
loadPixels();
}

void draw() {
if (video.available()) {
video.read(); // Read a new video frame
video.loadPixels(); // Make the pixels of video available
image(cam, 0, 0);
// Difference between the current frame and the stored background
int presenceSum = 0;
for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
// Fetch the current color in that location, and also the color
// of the background in that spot
color currColor = video.pixels[i];
color bkgdColor = backgroundPixels[i];
// color bkgdColor = backgroundPixels[i];
// Extract the red, green, and blue components of the current pixel’s color
int currR = (currColor >> 16) & 0xFF;
int currG = (currColor >> 8) & 0xFF;
int currB = currColor & 0xFF;
// Extract the red, green, and blue components of the background pixel’s color
int bkgdR = (bkgdColor >> 16) & 0xFF;
int bkgdG = (bkgdColor >> 8) & 0xFF;
int bkgdB = bkgdColor & 0xFF;
// Compute the difference of the red, green, and blue values
int diffR = abs(currR - bkgdR);
int diffG = abs(currG - bkgdG);
int diffB = abs(currB - bkgdB);
// Add these differences to the running tally
presenceSum += diffR + diffG + diffB;
// Render the difference image to the screen
//pixels[i] = color(diffR, diffG, diffB);
// The following line does the same thing much faster, but is more technical
pixels[i] = 0xFF000000 | (diffR << 16) | (diffG << 8) | diffB;
}
updatePixels(); // Notify that the pixels[] array has changed
}
}

// When a key is pressed, capture the background image into the backgroundPixels
// buffer, by copying each of the current frame’s pixels into it.
void keyPressed() {
video.loadPixels();
arraycopy(video.pixels, backgroundPixels);
}



I continue to get a NullPointerException at line 17 : "camPixels = cam.width * cam.height;" and no image of anytime seems to be showing up.
Re: Pixel Differences
Reply #2 - Jan 17th, 2010, 8:18pm
 
Your setup must be arranged like this:

Code:

void setup() {
// Change size to 320 x 240 if too slow at 640 x 480
size(320, 240, P2D);

video = new Capture(this, width, height, 24);
numPixels = video.width * video.height;
// Create array to store the background image
cam = new Movie(this, "cam.mov");
cam.read();
cam.loop();
camPixels = cam.width * cam.height;
backgroundPixels = new int[camPixels];
// Make the pixels[] array available for direct manipulation
loadPixels();
}


Don't forget that your movie file (cam.mov) must be the same resolution as your video capture device.
Re: Pixel Differences
Reply #3 - Jan 17th, 2010, 9:36pm
 
This definitely had interesting results. It has both videos of the looping as one input and the actual video camera feed on top of the same time. But the difference isn't exactly what I was looking for - but its interesting all the same.

Code:
import processing.video.*;
int numPixels;
int camPixels;
int[] backgroundPixels;
Capture video;
Movie cam;

void setup() {
size(640, 480, P2D);

video = new Capture(this, width, height, 24);
numPixels = video.width * video.height;
// Create array to store the background image
cam = new Movie(this, "cam.mov");
cam.loop();
camPixels = cam.width * cam.height;
// Make the pixels[] array available for direct manipulation
loadPixels();
}

void draw() {
if (video.available()) {
video.read(); // Read a new video frame
image(cam, 0, 0);
video.loadPixels(); // Make the pixels of video available
// Difference between the current frame and the stored background
int presenceSum = 0;
for (int i = 0; i < cam.width * cam.height; i++) { // For each pixel in the video frame...
// Fetch the current color in that location, and also the color
// of the background in that spot
color currColor = cam.pixels[i];
color bkgdColor = video.pixels[i];

pixels[i] = color(currColor - bkgdColor);
}
updatePixels(); // Notify that the pixels[] array has changed
}
}

// When a key is pressed, capture the background image into the backgroundPixels
// buffer, by copying each of the current frame’s pixels into it.


Re: Pixel Differences
Reply #4 - Jan 19th, 2010, 5:28am
 
Looks like I might have to go ahead to MAX MSP and see if I can find a more elegant solution. Thanks for the help though.

-H
Re: Pixel Differences
Reply #5 - Jan 30th, 2010, 12:11pm
 
Hey everyone, I was able to get the video differencing to work. I was speaking to a friend of mine and he was able to write a simple if { else statement that completed everything. Over at the Baltimore Node I got additional help and they added another line that would adjust the threshold on the fly and display the number on the output. I figure I'll place the code here if anyone wants to use it for their own projects.
Code:
// Completed on 1/22/10 by Scott Geiser & Hector Leiva
// with template used by Golan Levin.



import processing.video.*;

int numPixels;
int[] previousFrame;
Capture video;
int threshold;
PFont font;


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();
threshold=70;
// The font must be located in the sketch's
// "data" directory to load successfully
font = loadFont("Serif-20.vlw");
textFont(font);
}

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

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);

//This checks if the sum of the differences in the 3 pixel colors is less than some threshold
//Increasing the threshold will remove aliasing effects but lower the contrast

if ((abs(diffR) + abs(diffG) + abs(diffB)) < threshold)
{
pixels[i] = color(currR, currG, currB);
}
else
{
pixels[i] = 0xff000000;
}
}
updatePixels();

text("thres"+threshold, 15, 30);
//fill(0, 102, 153);
}
}

void keyPressed()
{
if(key == 'u')
{
threshold++;
}else if(key == 'd')
{
threshold--;
}else{
video.read();
video.loadPixels();
for (int i=0 ;i < numPixels; i++)
{
previousFrame[i] = video.pixels[i];
}
}
}

Page Index Toggle Pages: 1