Borenstein's OpenCV for Processing

edited June 2015 in Library Questions

Hello, everyone!

I've been working on some OpenCV code using Borenstein's excellent (but not amazingly well documented) OpenCV library.

The purpose of this code is to display four images in the window; going clockwise from top left, these are: 1) the live feed from the camera, 2) the live feed run through the .threshold() function, 3) the difference between the current frame and the previously displayed frame, displayed in black and white pixels, and 4) the previous frame.

I'm sure this is blindingly obvious to someone who's not written the code, but I've been looking at it on and off the last few days and I'm not making any progress!

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

PImage thisFrame, lastFrame, frameDiff;

Capture video;
OpenCV opencv;

int x = 1; // this will be set to zero after the first iteration, and is used to initiate conditionals to prevent errors
int noiseReduxFactor = 20; // this variable sets the window either side of the brightness threshold
int brightnessThreshold = 80;

void setup() {
  size(640,480);

  video = new Capture(this, 320, 240);
  opencv = new OpenCV(this, 320, 240);

  video.start();

}

void draw() {
  opencv.loadImage(video);
  opencv.gray();
  opencv.threshold(brightnessThreshold);
  thisFrame = opencv.getOutput();

  image(video,0,0);
  image(thisFrame,321,0);
  if(x==0) {
    image(lastFrame,0,241);
    image(frameDiff,321,241);

    thisFrame.loadPixels();
    lastFrame.loadPixels();
    frameDiff.loadPixels();

    for(int x=0;x>lastFrame.width;x++) {
      for(int y=0;y>lastFrame.height;y++) {
        int loc = x+y*lastFrame.width;
        if(thisFrame.pixels[loc] <= lastFrame.pixels[loc]+noiseReduxFactor/2 && thisFrame.pixels[loc] >= lastFrame.pixels[loc]-noiseReduxFactor/2) {
          frameDiff.pixels[loc] = color(0,0,0);
        } else {
          frameDiff.pixels[loc] = color(255,255,255);
        }
        lastFrame.pixels[loc] = thisFrame.pixels[loc];
      }
    }
  } else { // this is to prevent errors on the first iteration of the draw() loop
    frameDiff = thisFrame;
    lastFrame = thisFrame;
    x = 0;
  }

  delay(100);

}

void captureEvent(Capture c) {
  c.read();
}

Thanks for your help!

Struan

Answers

  • I spotted a few odd things. In draw(), you have

    for(int x=0;x>lastFrame.width;x++) {
    

    You probably mean instead:

    for(int x=0;x<lastFrame.width;x++) {
    

    Similar for the inner for y loop.

  • Thanks! Unfortunately that's not fixed the error...

  • Answer ✓

    Ok, here are the remaining issues.

    You need thisFrame, lastFrame, and frameDiff to be 3 separate images in memory. But when you run draw() for the first frame:

    frameDiff = thisFrame;
    lastFrame = thisFrame; 
    

    These two lines set all three to be the same locations in memory.

    What you need to do:

    1) in setup(), allocate 3 new images for the 3 frames:

    thisFrame = createImage(320, 240, RGB);
    // etc etc for lastFrame and frameDiff
    

    2) in draw(), in the else part, comment out the two lines I pointed out at the beginning.

    3) In draw(), in the if part, at the end of the nested for loop, you need to call updatePixels() on the two frames you wrote.

    I think that should fix your sketch. (Worked for me.) I would also remove the delay(100). It's bad practice to use delay() when you need a delay. Call frameRate() in setup() if you want to slow down draw().

  • edited June 2015

    Thank you! Much appreciated.

    That's working very well now, thanks again!

Sign In or Register to comment.