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.