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
Color tracking in frame differencing (Read 1535 times)
Color tracking in frame differencing
Oct 6th, 2009, 4:12pm
 
Hi everyone!
I am trying to implement color detection in my code but i'm not sure how to do it..

here's my code:

import processing.video.*;
// Size of each cell in the grid
int cellSize = 8;
// Number of columns and rows in our system
int cols, rows;
// Variable for capture device
Capture video;

int firsttime = 0;
int numPixels;
int[] previousFrame;
int[] differenceFrame;

void setup() {
 size(640, 480, P3D);
 frameRate(30);
 cols = width / cellSize;
 rows = height / cellSize;
 colorMode(RGB, 255, 255, 255, 100);
 println(cols);
 println(rows);

 // Uses the default video input, see the reference if this causes an error
 video = new Capture(this, cols, rows, 30);
 numPixels = video.width * video.height;
 // Create an array to store the previously captured frame
 previousFrame = new int[numPixels];
 differenceFrame = new int[numPixels];
 loadPixels();
 
 background(0);
}

void draw() {
 float corx,  cory;
 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
   if (firsttime < 10) {
     firsttime++;
     for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
       previousFrame[i] = video.pixels[i];
     }
   }
   
   fill(color(255, 255, 255, 5));
   noStroke();
   rectMode(CORNER);    
   rect(0,0,width, height);
   
   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;
     // Render the difference image to the screen
     //differenceFrame[i] = color(diffR, diffG, diffB);
     // The following line is much faster, but more confusing to read
     differenceFrame[i] = 0xff000000 | (diffR << 16) | (diffG << 8) | diffB;
     // Save the current color into the 'previous' buffer
     previousFrame[i] = currColor;
     
   // To prevent flicker from frames that are all black (no movement),
   // only update the screen if the image has changed.
 }
   // To prevent flicker from frames that are all black (no movement),
   // only update the screen if the image has changed.
   if (movementSum >= 0) {
     for (int i = 0; i < cols; i++) {
       for (int j = 0; j < rows; j++) {
         int x = i*cellSize;
         int y = j*cellSize;
         int loc = (video.width - i - 1) + j*video.width; // Reversing x to mirror the image
         
         if ((brightness(differenceFrame[loc]) >= 20) && (brightness(previousFrame[loc]) < brightness(get(x+cellSize/2, y+cellSize/2)) )) {
           float r = red(video.pixels[loc]);
           float g = green(video.pixels[loc]);
           float b = blue(video.pixels[loc]);
           color c = color(r, g, b, 50);
           pushMatrix();
           translate(x+cellSize/2, y+cellSize/2);
           rotate((2 * PI * brightness(c) / 125.0));
           rectMode(CENTER);
           noFill();
           stroke(c);
           corx =0+random(-cellSize,cellSize);
           cory =0+random(-cellSize,cellSize);
           
           line(corx, cory,
            corx+pow(brightness(differenceFrame[loc])/20,2)+cellSize, cory+ pow(brightness(differenceFrame[loc])/20,2)+cellSize);
           popMatrix();
    }
   }
  }
 }
}
}

How would i proceed so that it would only detect the color red?
Re: Color tracking in frame differencing
Reply #1 - Oct 7th, 2009, 1:45am
 
your code extracts the r,g and b component of each pixel, right? so, in order to track red stuff, you should check for pixels with a r predominance or for pixels with r,g,b values equal to 255+-n,0+-n,0+-n, where n is an offset you can setup.

another way would be to move to hsv colorspace and check the hue.
Re: Color tracking in frame differencing
Reply #2 - Nov 3rd, 2009, 2:47pm
 
You should interrogate each pixel and determine whether it is red enough. A red point has red componet say four times greater than green and same thing to blue. Then sum the x coordinates of all such red points and divide the sum by the number of points that are found to be red. There you have the center of your red points, just x coordinate. Do the same for y. If you have a physics teacher/friend, ask them to explain to you center of mass. It's the same concept. You do this tracking for every frame you receive. If you want motion detection, just take the current center of red point and subtract the center from your past frame. Don't mess around differencing between frames. I've got a tracking program written for this purpose. It's very long but I could split out the tracking part (still long) if you need it.
Page Index Toggle Pages: 1