We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi there,
I am working to set up a "look away photo booth" with face tracking in OpenCV. Basically: Sees face, face looks away, counts to 10, takes picture. If there is no face, it just waits for one, muwahahaha.
Now, I sort of figured out how to make a switch (if there's a more elegant solution, please do share!) that triggers when a face has been present for more than a few seconds:
/*
*/
import gab.opencv.*;
import processing.video.*;
import java.awt.*;
boolean isFace = false;
boolean wasFace = false; //boolean to see if there was a face
int prevMillis;
int count;
int numPics;
int isFaceTimer;
int goneFaceTimer;
Capture video;
OpenCV opencv;
OpenCV photocv;
PFont font;
void setup() {
size(640, 480);
numPics = 0;
video = new Capture(this, 640/2, 480/2);
opencv = new OpenCV(this, 640/2, 480/2);
opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);
video.start();
}
void draw() {
scale(2);
opencv.loadImage(video);
image(video, 0, 0 );
noFill();
stroke(0, 255, 0);
strokeWeight(3);
Rectangle[] faces = opencv.detect();
println(faces.length);
for (int i = 0; i < faces.length; i++) {
//println(faces[i].x + "," + faces[i].y);
rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height);
isFace = true;
}
if(faces.length == 0){
isFace = false;
}
if (isFace){
wasFace = false;
goneFaceTimer=0;
println("THERE IS A FACE HERE");
isFaceTimer ++;
println("FACE TIMER"+isFaceTimer);
}
else {
println("NO NO FACE");
goneFaceTimer ++;
println("NO FACE FOR THIS LONG"+goneFaceTimer);
//check that the face was there long enough. Then count to 10
if( isFaceTimer > 2 && goneFaceTimer > 0 ){
println("AAAAAAAA");
wasFace = true;
}
isFaceTimer = 0;
}
if (wasFace){
if (numPics <= 15) {
takePic();
}
}
wasFace = false;
}
void captureEvent(Capture c) {
c.read();
}
void takePic() {
saveFrame("photobooth"+numPics+".jpg");
println ("pics taken"+(numPics+1));
delay(600);
numPics += 1;
}
My problem is, this triggers the photo when I set it to 0::
else {
println("NO NO FACE");
goneFaceTimer ++;
println("NO FACE FOR THIS LONG"+goneFaceTimer);
//check that the face was there long enough. Then count to 10
if( isFaceTimer > 2 && goneFaceTimer >0 ){
println("AAAAAAAA");
wasFace = true;
}
isFaceTimer = 0;
}
but if I try to set it to 10 or any other number, it doesn't take a photo this doesn't work:
else {
println("NO NO FACE");
goneFaceTimer ++;
println("NO FACE FOR THIS LONG"+goneFaceTimer);
//check that the face was there long enough. Then count to 10
if( isFaceTimer > 2 && goneFaceTimer > 10 ){
println("AAAAAAAA");
wasFace = true;
}
isFaceTimer = 0;
}
nor this:
else {
println("NO NO FACE");
goneFaceTimer ++;
println("NO FACE FOR THIS LONG"+goneFaceTimer);
//check that the face was there long enough. Then count to 10
if( isFaceTimer > 2 && goneFaceTimer >= 10 ){
println("AAAAAAAA");
wasFace = true;
}
isFaceTimer = 0;
}
I can't seem to figure it out, and I know it has to be something simple---any help would be much appreciated!
Answers
Your problem is simple, indeed. In fact, it's in the very same if statement as the 3 you show above.
Going through it, step by step, we start our loop, and we get to "NO NO FACE". isFaceTimer is greater than 2. We're good there. goneFaceTimer, however is not yet greater or equal to 10, so we skip the if statement.
Then, all of a sudden, isFaceTimer is set to 0, every single loop that the face isn't in it. So now, even if goneFaceTimer is greater than 10, isFaceTimer will never be greater than 2 by the time goneFaceTimer reaches 10.
To fix this, you should have some boolean variable keeping track of whether or not isFaceTimer has passed 2 "ticks" (whatever your time measurement unit is), and reset when a face is seen, again.
I've indicated the changes with new comments, having removed yours, to make things clearer: