How to flip example ''Frame Differencing'' (pushMatrix doesn't work)

edited December 2014 in How To...

Hello to all. I'm preety new on Processing and maybe I'm missing something really basic here. The very simple idea here is to flip the image from a webcam in the example ''Frame Differencing'' that can be found in the Examples/Lybraries/Video/Capture. I mixed it a bit with other example: Mirror. But that one didn't affected it nor for bad or for good. Then I tried to use pushMatrix, and it worked for the flipping thing, but then the frame differencing didn't work anymore. Although the sketch ran without errors in both cases. The last detail is that for my intentions is important to use P2D, to use blendMode in a later implementation. I thank you all in advance, and below is the sketch:

/**
 * Frame Differencing by Golan Levin. + a little bit from  * Mirror by Daniel Shiffman.  
 * Quantify the amount of movement in the video frame using frame-differencing.
 */
import processing.video.*;

int numPixels;
int[] previousFrame;
Capture video;

void setup() {
  size(640, 480, P2D);
  background(255, 0, 0);
  frameRate(30);
  colorMode(RGB, 255, 255, 255, 100);
  video = new Capture(this, width, height);
  video.start();
  loadPixels();  
  numPixels = video.width * video.height;
  previousFrame = new int[numPixels];
}

void draw() {
  if (video.available()) {
    video.read();
    video.loadPixels(); // Make its pixels[] array available
    int movementSum = 0;

    for (int x = 0; x < video.width; x++) {
      for (int y = 0; y < video.height; y++) {
        int loc = (video.width - x - 1) + y*video.width; // Reversing x to mirror the image

        color currColor = video.pixels[loc];
        color prevColor = previousFrame[loc];
        int currR = (currColor >> 16) & 0xFF;
        int currG = (currColor >> 8) & 0xFF;
        int currB = currColor & 0xFF;
        int prevR = (prevColor >> 16) & 0xFF;
        int prevG = (prevColor >> 8) & 0xFF;
        int prevB = prevColor & 0xFF;
        // Compute the difference of the red, green, and blue values
        int diffR = abs(currR - prevR);
        int diffG = abs(currG - prevG);
        int diffB = abs(currB - prevB);
        // Add these differences to the running tally
        movementSum += diffR + diffG + diffB;
        // Render the difference image to the screen
        pixels[loc] = color(diffR, diffG, diffB);
        // Save the current color into the 'previous' buffer
        previousFrame[loc] = currColor;
      }
    }
    // To prevent flicker from frames that are all black (no movement),
    // only update the screen if the image has changed.
    if (movementSum > 20) {
      updatePixels();
      println(movementSum);
    }
  }
  //  pushMatrix();
  //  scale(-1.0, 1.0);
  //  image(video, -video.width, 0);
  //  popMatrix();**
}
Tagged:

Answers

  • Answer ✓
    scale(-1,1);
    translate(200,0);
    image....?
    
  • Thanks Chrisir. That also works to flip the image but makes the 'frame differencing' not to work. I think I'm close to another solution. I'll post it here later

  • edited December 2014

    I got stuck again. So close! I changed the line that had no effect at all:

    int loc = (video.width - x - 1) + y*video.width; // Reversing x to mirror the image

    to the line:

    video.pixels[y*video.width+x] = video.pixels[y*video.width+(video.width-(x+1))];
    

    and now I have a mirror divided in the middle. I tried to follow the logic of it, but I did not understand why is working like that. Of course I messed the parameter. I got interesting results, but not what I was looking for.

  • Answer ✓

    to do a copying pixel by pixel I think you need to leave the source video unchanged and instead write the coping into a new image. -

    because otherwise you change the video you are still reading from. Not good.

  • Well, I'm not sure if this is what you said, but I made something that solved the case. Thank you, Chrisir! The whole code ended like this:

    import processing.video.*;
    
    int numPixels;
    int[] previousFrame;
    Capture video;
    PImage videoFlip;
    
    void setup() {
      size(640, 480, P2D);
      background(255, 0, 0);
      frameRate(30);
      colorMode(RGB, 255, 255, 255, 100);
      video = new Capture(this, width, height);
      video.start();
    
      videoFlip = new PImage(video.width, video.height);
      loadPixels();  // I don't know why this is needed here if I have to load the pixels again in the draw func.
      numPixels = video.width * video.height;
      previousFrame = new int[numPixels];
    
    }
    
    void draw() {
      if (video.available()) {
        video.read();
      }
        video.loadPixels(); // Make its pixels[] array available
        int movementSum = 0;
        for (int x = 0; x < video.width; x++) {
          for (int y = 0; y < video.height; y++) {
            videoFlip.pixels[y*video.width+x] = video.pixels[y*video.width+(video.width-(x+1))];
            int loc = y*videoFlip.width + x;
            color currColor = videoFlip.pixels[loc];
            color prevColor = previousFrame[loc];
            int currR = (currColor >> 16) & 0xFF;
            int currG = (currColor >> 8) & 0xFF;
            int currB = currColor & 0xFF;
            int prevR = (prevColor >> 16) & 0xFF;
            int prevG = (prevColor >> 8) & 0xFF;
            int prevB = prevColor & 0xFF;
            int diffR = abs(currR - prevR);
            int diffG = abs(currG - prevG);
            int diffB = abs(currB - prevB);
            // Add these differences to the running tally
            movementSum += diffR + diffG + diffB;
            // Render the difference image to the screen
            pixels[loc] = color(diffR, diffG, diffB);
            // Save the current color into the 'previous' buffer
            previousFrame[loc] = currColor;
          }
        }
        if (movementSum > 20) {
          updatePixels();
          println(movementSum);
        }
    }
    
  • I should mention that part of the solution was on this post:

    http://forum.processing.org/one/topic/mirroring-a-webcam-in-a-sketch.html

Sign In or Register to comment.