i thought it would be a useful exercise to try and find the definitive and most optimal way of motion tracking.
first test is frame differencing, then finding an average point as the motion point.
framerate (2ghz powerbook ) = 46fps
i made some speed savings by precalculating the grid.
obviously making the source video smaller would increase speed too..
anyone see any way of speeding up the code even more?
Code:
float fpscount, count;
void setup(){
size(640,480);
precalc();
initVid();
}
void draw(){
motion();
getFrameRate();
}
import processing.video.*;
Capture myCapture;
color newPixel;
color[] prevFrame;
float speed = 10;
float sensitivity = 0.64;
float targetX, targetY, myX, myY, avX, avY;
int cxLoc, cyLoc;
int counter=0;
int totalBlocks=0;
int[] cX= new int[5000];
int[] cY= new int[5000];
// precalculate screen grid
void precalc(){
for(int y = 0; y < 30-1; y++){
for(int x = 0; x < 40-1; x++){
cX[counter] = x*(width/40);
cY[counter] = y*(height/30);
counter++ ;
}
}
totalBlocks=counter;
}
void initVid () {
String s = "IIDC FireWire Video";
myCapture = new Capture ( this, width, height, 4);
prevFrame = new color[width*height];
}
void captureEvent ( Capture myCapture ) {
myCapture.read();
}
void motion() {
image(myCapture,0,0);
avX = 0;
avY = 0;
counter = 0;
for(int i = 0; i < totalBlocks; i++){
if(motionTest(i,width/40,height/30)==true){
avX += cX[i];
avY += cY[i];
counter ++;
fill(255,0,0);
ellipse(cX[i], cY[i],6,6);
}
}
if (avY<=0) avY=myY;
if (avX<=0) avX=targetX;
if (avY>0 && avX>0 && counter>0){
targetX=width-avX/counter;
targetY=avY/counter;
//print (targetY+" ");
}
myY += (targetY-myY)/speed;
myX += (targetX-myX)/speed;
}
boolean motionTest(int j,int tw, int th){
int dc=0; // counter to track number of differences
// ave. out a square
for(int y=0;y<th;y++){
for(int x=0;x<tw;x++){
int srcPos=((cY[j]+y)*width)+(cX[j]+x);
newPixel = myCapture.pixels[srcPos];
if(abs(red(newPixel)-red(prevFrame[srcPos]))>25) dc++;
prevFrame[srcPos]=newPixel; // update prevFrame w/ current pixel clr
}
}
if(dc>(sensitivity*(tw*th))){ return true; } else{ return false; }
}
void getFrameRate(){
fpscount+=frameRate;
count++;
println("fps:"+ round(frameRate)+ " ave.: "+ round(fpscount/count));
}