How do I get an image to persist for a given time in a loop?

edited May 2016 in Kinect

Hi, what I'm trying to do here is have the image(faceImage, 0, 0) stay on for longer than a fraction of a second. I know I need to use some kind of timer, but all my previous attempts with an if timer or a while() have failed so far. Thanks in advance.

import gab.opencv.*;
import processing.video.*;
import java.awt.*;

Capture video;
OpenCV faceCV;
PImage faceImage;

int faceCounter = -1;

int offset = 40;

void setup() {
  size(640, 480);
  video = new Capture(this, width/divider, height/divider);
  faceCV = new OpenCV(this, width/divider, height/divider);
  faceCV.loadCascade("haarcascade_frontalface_default.xml");
  video.start();
}

void draw() {
  if (video.available()) {
    video.read();
    faceCV.loadImage(video);
  }

  pushMatrix();
  image(video, 0, 0);
  popMatrix();

  Rectangle[] faces = faceCV.detect();

  for (int i = 0; i < faces.length; i++) {
    if (faces[i].width > 120) {
      faceCounter++;
      video.save("data/memory"+faceCounter+".png");
      if (faceCounter > offset-1 && faceCounter%offset  == 0) {
        faceImage = loadImage("memory"+(faceCounter-offset)+".png");
        pushMatrix();
        image(faceImage, 0, 0);
        popMatrix();
      }
    }
  }
}

Answers

  • edited February 2015

    remember

    remember that the screen that you see is only updated once, when the end of draw() is reached.

    this means all that happens in the for-loop gets added up to one image.

    This image gets displayed at the end of draw(). Not throughout.

    No wonder you can't see your images.

    solution

    draw() runs ~60 times per second.

    so one solution is to get rid of the for loop and use the fact that draw() loops in itself automatically instead.

    you would have to handle i then "manually" (i++; if (i>faces.length) i=0; etc. declare i before setup() )

    also look into frameRate() to slow things down.

    to have a real timer use millis() please

    Chrisir ;-)

  • Yes, using the if loop was the way to go, however, I didn't need to rework the entire for loop as an if loop:

    The two relevant excerpts:

    if (imageAvailable == true) {
        pushMatrix();
        scale(-1*divider, 1*divider);
        tint(255, 255);
        image(faceImage, -faceImage.width, 0);
        println("DISPLAYING memory"+(faceCounter-offset));
        popMatrix();
        if (timer == timeLimit) {
          imageAvailable = false;
          timer = 0;
          println("Timer's up!");
        }
        timer++;
      } else {
        displayBlack();
      }
    

    and

    for (int i = 0; i < faces.length; i++) {
        if (faces[i].width > 120) {
          faceCounter++;
          video.save("data/memory"+faceCounter+".png");
          println("SAVED memory"+faceCounter);
          if (faceCounter > offset-1 && faceCounter%offset  == 0) {
            faceImage = loadImage("memory"+(faceCounter-offset)+".png");
            imageAvailable = true;
          }
        }
      }
    
  • If I were you I wouldn't load an image in a for-loop in draw() - it slows things down quite a bit. Can't you retrieve faceImage directly from the screen via get()

    should be much faster...

Sign In or Register to comment.