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.
IndexProgramming Questions & HelpVideo Capture,  Movie Playback,  Vision Libraries › Multiple light tracking...need some help
Page Index Toggle Pages: 1
Multiple light tracking...need some help (Read 1180 times)
Multiple light tracking...need some help
Dec 31st, 2009, 4:24pm
 
Hi all,

I posted earlier about tracking an image, and would still like to tackle that, but for now, I am working on getting multiple light sources tracked. I have modified the brightness tracking example slightly, but am really not sure how to go about identifying if a point has already been selected as a light source.

Essentially I want the four lightest points in the video feed to be tracked. I have made a cool LED rig around a painting that I am using as my test subject Smiley

Can someone help point me in the right direction?

Thanks in advance,
Greenlig

Here is the current code -

Code:
import processing.video.*;

Capture video;
lightPoint point1, point2;

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, 30);
 noStroke();
 smooth();

 //Create a light point to visualise from the class lightPoint
 point1 = new lightPoint(0.0, 0.0, 0);
 point2 = new lightPoint(0.0, 0.0, 1);

}

void draw() {
 if (video.available()) {
   video.read();
   image(video, 0, 0, width, height); // Draw the webcam video onto the screen

   int brightestX = 0; // X-coordinate of the brightest video pixel
   int brightestY = 0; // Y-coordinate of the brightest video pixel
   float brightestValue = 0; // Brightness of the brightest video pixel

   // Search for the brightest pixel: For each row of pixels in the video image and
   // for each pixel in the yth row, compute each pixel's index in the video
   video.loadPixels();
   int index = 0;
   for (int y = 0; y < video.height; y++) {
     for (int x = 0; x < video.width; x++) {
       // Get the color stored in the pixel
       int pixelValue = video.pixels[index];
       // Determine the brightness of the pixel
       float pixelBrightness = brightness(pixelValue);
       // If that value is brighter than any previous, then store the
       // brightness of that pixel, as well as its (x,y) location
       if (pixelBrightness > brightestValue) {
         brightestValue = pixelBrightness;
         brightestY = y;
         brightestX = x;
         point1.x = brightestX;
         point1.y = brightestY;
       }
       
     
         
       index++;
     }
   }

   // Display the lightPoint objects

   // ellipse(brightestX, brightestY, 50, 50);

   point1.display();

   point2.display();

  // draw_grid(brightestX, brightestY);
 }
}

class lightPoint {

 float x = 0.0; // X-coordinate of the brightest video pixel
 float y = 0.0; // Y-coordinate of the brightest video pixel
 
 // float brightestValue = 0; // Brightness of the brightest video pixel

 boolean selected = false;

 int index;

lightPoint(float xpos, float ypos, int num) {

   x = xpos;
   y = ypos;

   index = num;

   selected = false;

 }

 void display() {

   fill(255, 204, 0, 128);
   ellipse(x, y, 50, 50);

 }

}





Original post below...
Quote:
I am a fairly new Processing user, but know enough to get around.

At the moment, I need to work out a fast system to track a simple pixelated image in a webcam feed. The main reason for this is that I would like to track it in an daylight setting, and tracking light sources isn't a good method for that.

At the moment, I am working off the Brightest Pixel tracking example that I found somewhere, but to no avail. I don't quite understand the methods I need to undertake to scan for a group of pixels of a certain colour. I have read about blob detection, but it requires libraries that don't seem to work, regardless of what I try. Also, I assume that finding a pixel of a certain colour isn't that difficult, and could be done with vanilla processing.

Would love to be pointed in the right direction by someone, as I really don't know where to start with it. The code I currently have does nothing beside track the brightest pixel using the example.


Happy new year all Cheesy
Re: Multiple light tracking...need some help
Reply #1 - Jan 12th, 2010, 10:58am
 
I did such stuff already... but now I had to realize that processing is just not the same as java. Short time after something gets interesting you got too much code. Too much public code... all in one listing...

Ok, here is my experiment with the four dots (in this I am displaying the dots on the screen):

Code:
import processing.video.*;
import fullscreen.*;

FullScreen fs;
Capture myCapture;

int w = 1680;
int h = 1050;

int boxSize = 100;

int cw = 100;
int ch = cw * 3 / 4;

int[] x = new int[4];
int[] y = new int[4];

void setup(){
size(w, h, P2D);
myCapture = new Capture(this, cw, ch, 30);

fs = new FullScreen(this);
fs.enter();
}

void draw() {
background(0);
fill(255);
rect(w - boxSize*2, boxSize, boxSize, boxSize);
rect(boxSize, h - boxSize*2, boxSize, boxSize);
rect(boxSize, boxSize, boxSize, boxSize);
rect(w - boxSize*2, h - boxSize*2, boxSize, boxSize);
noFill();
analyzeCapture();
image(myCapture, boxSize * 2, boxSize);
}

void captureEvent(Capture myCapture) {
myCapture.read();
}

void analyzeCapture(){
float[] corners = new float[4];

myCapture.loadPixels();

for(int v = 1; v < myCapture.height - 1; v++){
for(int u = 1; u < myCapture.width - 1; u++){
int index = 0;
int i = v * myCapture.width + u;

if(u > myCapture.width / 2) index += 1; // right side
if(v > myCapture.height / 2) index += 2;// bottom side

float b = brightness(myCapture.pixels[i]) +
0.5 * (brightness(myCapture.pixels[i - 1]) + brightness(myCapture.pixels[i + 1]) + brightness(myCapture.pixels[i - myCapture.width]) + brightness(myCapture.pixels[i + myCapture.width]));
if(b > corners[index]){
corners[index] = b;

x[index] = i % cw;
y[index] = i / cw;
}
}
}
}

Oh, and you may need the fullscreen library for this.

Here is another more recent code I use for some kind of pattern tracking:

Code:
import processing.video.*;
Capture myCapture;

int w = 200;
int h = w * 3 / 4;

int faceSize = 30;
int splitSides = 3;
int splitSize = faceSize / splitSides;

int faceX = w / 2 - faceSize / 2;
int faceY = h / 2 - faceSize / 2;

int testX;
int testY;
boolean retargetOccured = false;

int checkboxWidth = 7;
int checkboxHeight = 5;

int threshold = 50;
int stepping = 5;
int retargetThreshold = 200000 / stepping;

PImage pattern;
PImage test;
PFont font;

boolean initiated = false;

public void setup(){
size(w, h);
myCapture = new Capture(this, w, h, 30);
pattern = createImage(faceSize, faceSize, RGB);
test = createImage(faceSize, faceSize, RGB);
font = createFont("Arial", 10);
textFont(font);
stroke(255, 0, 0);
}

public void draw() {
background(0);
if(initiated) analyzeCapture();
image(myCapture, 0, 0);
shiftFaceBack();
if(retargetOccured){
fill(255);
rect(faceX, faceY, faceSize, faceSize);
retargetOccured = false;
}

fill(255, 0, 0);
rect(3, 3, checkboxWidth, checkboxHeight);

text("Pixel (S)tepping: " + stepping, 3, h - 25);
text("(P)ixel Threshold: " + threshold, 3, h - 14);
text("(R)etarget Threshold: " + retargetThreshold, 3, h - 3);

noFill();
rect(faceX, faceY, faceSize, faceSize);
}

void shiftFaceBack(){
if(faceX < 0) faceX = 0;
else if(faceX >= w - faceSize) faceX = w - faceSize - 1;
if(faceY < 0) faceY = 0;
else if(faceY >= h - faceSize) faceY = h - faceSize - 1;
}

float scoreTest(PImage p){
test.copy(myCapture, testX, testY, faceSize, faceSize, 0, 0, faceSize, faceSize);
test.loadPixels();
float r, g, b;
float score = 0;
for(int i = 0; i < test.pixels.length; i += stepping){
r = abs(red(test.pixels[i]) - red(p.pixels[i]));
g = abs(green(test.pixels[i]) - green(p.pixels[i]));
b = abs(blue(test.pixels[i]) - blue(p.pixels[i]));
if(r + g + b > threshold)
score += r + g + b;
}

return score;
}

public void keyPressed(){
switch(keyCode){
case 32:
if(!initiated){
copyPattern();
}
initiated = !initiated;
break;
case 37: checkboxWidth--; break;
case 38: checkboxHeight--; break;
case 39: checkboxWidth++; break;
case 40: checkboxHeight++; break;
case 65: stepping--; break;
case 69: retargetThreshold -= 1000; break;
case 79: threshold -= 5; break;
case 80: threshold += 5; break;
case 82: retargetThreshold += 1000; break;
case 83: stepping++; break;
}
}

void copyPattern(){
pattern.copy(myCapture, faceX, faceY, faceSize, faceSize, 0, 0, faceSize, faceSize);
pattern.loadPixels();
}

void captureEvent(Capture myCapture) {
myCapture.read();
}


void analyzeCapture(){
float scores[] = new float[checkboxWidth * checkboxHeight];
faceX -= checkboxWidth / 2;
faceY -= checkboxHeight / 2;

for(int v = 0; v < checkboxHeight; v++){
for(int u = 0; u < checkboxWidth; u++){
testX = faceX + u;
testY = faceY + v;
scores[v * checkboxWidth + u] = scoreTest(pattern);
}
}

int best = 0;
for(int i = 1; i < scores.length; i++)
if(scores[i] < scores[best])
best = i;


faceX += (checkboxWidth / 2) + ((best % checkboxWidth) - checkboxWidth / 2) * 2;
faceY += (checkboxHeight / 2) + ((best / checkboxWidth) - checkboxHeight / 2) * 2;

if(scores[best] > retargetThreshold){
retargetOccured = true;
copyPattern();
}
}

Use the space key to start tracking after you placed the pattern in the red square.
Page Index Toggle Pages: 1