1

I am doing a background subtraction capture demo recently but I met with difficulties. I have already get the pixel of silhouette extraction and I intend to draw it into a buffer through createGraphics(). I set the new background is 100% transparent so that I could only get the foreground extraction. Then I use saveFrame() function in order to get png file of each frame. However, it doesn't work as I expected. I intend to get a series of png of the silhouette extraction with 100% transparent background but now I only get the general png of frames from the camera feed. Is there anyone could help me to see what's the problem with this code? Thanks a lot in advance. Any help will be appreciated.

import processing.video.*;

Capture video;

PGraphics pg;

PImage backgroundImage;
float threshold = 30;

void setup() {
  size(320, 240);
  video = new Capture(this, width, height);
  video.start();

  backgroundImage = createImage(video.width, video.height, RGB); 
  pg = createGraphics(320, 240);
}

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

void draw() {
  pg.beginDraw();

  loadPixels();
  video.loadPixels();
  backgroundImage.loadPixels();

  image(video, 0, 0);
  for (int x = 0; x < video.width; x++) {
    for (int y = 0; y < video.height; y++) {
      int loc = x + y * video.width;



color fgColor = video.pixels[loc];
color bgColor = backgroundImage.pixels[loc];

float r1 = red(fgColor); float g1 = green(fgColor); float b1 = blue(fgColor);
float r2 = red(bgColor); float g2 = green(bgColor); float b2 = blue(bgColor);
float diff = dist(r1, g1, b1, r2, g2, b2);


if (diff > threshold) {
  pixels[loc] = fgColor;
} else {
  pixels[loc] = color(0, 0);
}
    }}
    pg.updatePixels();
    pg.endDraw();


    saveFrame("line-######.png");
}


void mousePressed() {
  backgroundImage.copy(video, 0, 0, video.width, video.height, 0, 0, video.width, video.height);
  backgroundImage.updatePixels();
}
Jankapunkt
  • 8,128
  • 4
  • 30
  • 59
iiyeo
  • 13
  • 3
  • Can you please be more specific than saying it doesn't work how you expected? Can you please provide a [mcve] using a hard-coded image instead of a camera feed? – Kevin Workman Sep 25 '17 at 22:27
  • @Kevin Workman Thanks for your comment and I re-edit it. I intend to get a series of png of the silhouette extraction with 100% transparent background but now I only get the general png of frames from the camera feed. However, I couldn't use the image to replace the camera feed because I use the capture camera to detect the different pixels between the background and foreground. I don't know whether I've made it clear. If you have any further advice, please tell me. Thanks a lot. – iiyeo Sep 25 '17 at 22:59
  • What happens if you get rid of this line? `pixels[loc] = color(0, 0);` – Kevin Workman Sep 25 '17 at 23:30
  • The reason I ask for a [mcve] that uses a hard-coded image is I have no way of running your code. Using an image instead of a video would make it easier to help you, and it would be all the same code for an image as it is for a video. – Kevin Workman Sep 25 '17 at 23:31

1 Answers1

0

Re:

Then I use saveFrame() function in order to get png file of each frame. However, it doesn't work as I expected. I intend to get a series of png of the silhouette extraction with 100% transparent background but now I only get the general png of frames from the camera feed.

This won't work, because saveFrame() saves the canvas, and the canvas doesn't support transparency. For example, from the reference:

It is not possible to use the transparency alpha parameter with background colors on the main drawing surface. It can only be used along with a PGraphics object and createGraphics(). https://processing.org/reference/background_.html

If you want to dump a frame with transparency you need to use .save() to dump it directly from a PImage / PGraphics.

If you need to clear your PImage / PGraphics and reuse it each frame, either use pg.clear() or pg.background(0,0,0,0) (set all pixels to transparent black).

JeremyDouglass
  • 1,361
  • 2
  • 18
  • 31
  • Thanks for your advice. I change it to pg.save("image_" + millis() + ".png"); but I get a series of cumulative motion in every png. Besides, I didn't get the background subtraction. I have no idea about that. It seems that I get the foreground pixels successfully cause the cumulative motion is exactly what I'd like to extract. Unluckily, the pngs always accumulate with the previous foreground pixels. I would like to split it into each png. Counld you please give me some further advice? Thank you so much. I have been trapped for too long but have no idea. – iiyeo Oct 01 '17 at 10:18
  • Maybe I have solved the cumulative drawing issue after I added pg.background(0, 0); after pg.beginDraw();. But I get a series of png files as normal camera feed frame, not the foreground extraction. I think the key section is here: – iiyeo Oct 01 '17 at 17:50
  • here is the code:if (diff > threshold) { pixels[loc] = fgColor; } else { pixels[loc] = color(0, 0); } – iiyeo Oct 01 '17 at 17:50
  • I always get the error "NullPointerException" for the line" pg.pixels[loc] = color(0, 0); " so that I couldn't set the rest pixels as fully transparent. – iiyeo Oct 01 '17 at 17:52
  • It sounds like you need to clear the PGraphics each frame. You could set it to a new PGraphics or you could use `pg.clear()` or `pg.background(0,0,0,0)` (set all pixels to transparent black). – JeremyDouglass Oct 02 '17 at 22:17