Photo timer, can't figure it out

edited March 2017 in Kinect

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!

Tagged:

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:

    import gab.opencv.*;
    import processing.video.*;
    import java.awt.*;
    
    boolean isFace = false;
    boolean wasFace = false;
    int prevMillis;
    int count;
    int numPics;
    
    int isFaceTimer;
    int goneFaceTimer;
    boolean faceFound; //The variable that confirms that isFaceTimer has passed 2.
    
    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++) {
        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++;
        faceFound = false; //This variable, faceFound, will stay false after the if(isFace), unless isFaceTimer > 2.
        if (isFaceTimer > 2) faceFound = true;
        println("FACE TIMER"+isFaceTimer);
      } else {    
        println("NO NO FACE");
        goneFaceTimer++; 
        println("NO FACE FOR THIS LONG"+goneFaceTimer);
        if (faceFound && goneFaceTimer > 10 ) { //Here's the revised if statement, using faceFound.
          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;
    }
    
Sign In or Register to comment.