Blending with BackgroundSubtraction using OpenCV

edited August 2014 in Library Questions

Hello everyone!

I was working on this project of mine and I seem to have hit a bit of an impasse. The specific intended workings of my program can hopefully be better explained in the comments of the code below, but the general jist of it, assuming that it is possible of course, is that I want to use a still image to mask over the Background Subtraction created by OpenCV.

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

File f1;
boolean take_snapshot = false;
boolean pictureJustTaken = false;
//boolean faceDetect = false;

final static float print_wait = 2000;
final static float photo_wait = 5000;
float timer1, timer2 = 0.0;
int startTimer;
float alphaFade = 100.0;
public int faceCount, headCount;

public myCapture video;
OpenCV opencv;

String screenPath, buffer0;
PImage img, buffer;

void setup() {
  size(640, 480, P2D);
  video = new myCapture(this, 640/2, 480/2);
  opencv = new OpenCV(this, 640/2, 480/2);
  opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);

  opencv.startBackgroundSubtraction(5, 3, 0.5);

  // timers for the screencap functions
  timer1 = millis();
  timer2 = millis();

  // Creates a new folder for screencap storage if it doesn't already exist.
  screenPath = sketchPath("images");
  f1 = new File(screenPath);
  f1.mkdir();

  buffer0 = screenPath + "/buffer.png";
  buffer = loadImage(buffer0);
  if (buffer == null) {
    buffer = createImage(width/2, height/2, ARGB);
    buffer.save(buffer0);
  }
}

void draw() {
  background(0);

  // draw the video feed
  img = video.get_image();
  scale(2);
  opencv.loadImage(img);
  hint(DISABLE_DEPTH_TEST);
  set(0, 0, img);
  hint(ENABLE_DEPTH_TEST);

  opencv.updateBackground();
  opencv.dilate();
  opencv.erode();

  if (millis() - timer1 > print_wait) {
    println(frameRate);  // print framerate here to test speed
    timer1 = millis();
  }

  Rectangle[] faces = opencv.detect();
  faceCount = faces.length;

  // If no faces are detected, then the camera should take a picture, 
  // save it to a .png, and refresh it (ie. take a new one) every few seconds.
  // However, if a face is detected, then stop refreshing the picture in the 
  // .png and use that picture to mask out the foreground elements.
  if (faceCount > 0) {
    // Mask over the foreground elements (namely the contours) with image
    // data stored in the .png.
    buffer.loadPixels();
    img.mask(buffer);
    buffer.updatePixels();

    for (Contour contour : opencv.findContours()) {
      contour.draw();
    }
    // However, the image mask should use the alpha channel to help create 
    // a fading effect so that the foreground data looks like it is
    // fading out of existence.
  } else {
    // take a picture every few seconds and save it to a .png file.
    if ((take_snapshot) && (pictureJustTaken == false)) take_picture();
    if (pictureJustTaken) {
      if (millis() - timer2 > photo_wait) {
        pictureJustTaken = false;
        timer2 = millis();
      }
    }
  }  
}

public void take_picture() {
  // Takes screenshots from capture feed.
  img.loadPixels();
  buffer = img.get();
  buffer.save(buffer0);
  img.updatePixels();

  take_snapshot = false;
  pictureJustTaken = true;
  startTimer = millis();
}

public void stop() {
  video.stop();
  super.stop();
}

Please note that this code also requires the "myCapture.java" class for the video class to work properly:

import processing.core.PImage;
import processing.core.PApplet;
import processing.core.PConstants;
import processing.video.*;

public class myCapture {
  private Capture cam;
  private int _w, _h;
  private PImage _img;

  public myCapture(PApplet pa, int w, int h) {
    _w = w;
    _h = h;
    cam = new Capture(pa, _w, _h, 30);
    cam.start();
  }

  public myCapture(PApplet pa, int w, int h, int fps) {
    _w = w;
    _h = h;
    cam = new Capture(pa, _w, _h, fps);
    cam.start();
  }

  public PImage get_image() {
    if (cam.available() == true) {
      cam.read();
    }
    PImage tmp = cam.get();
    return tmp;
  }

  public String[] getDevices() {
    String[] devices = Capture.list();
    if (devices.length == 0) {
      System.out.println("I can't find any cameras");
    }
    System.out.println(devices);
    return devices;
  }

  public void stop() {
    cam.stop();
  }
}

I'm very well aware that there are likely a lot of other errors here, but any help that you could provide would be greatly appreciated.

Thank you all very much in advance.

Sign In or Register to comment.