Interactive Programming(2017)-week3

Background Subtraction

  1.  ブルーバック
  2. クロマキー

プログラムでどのような処理を行っているかその基本を知る


/**
* Background Subtraction
* by Golan Levin.
*
* Detect the presence of people and objects in the frame using a simple
* background-subtraction technique. To initialize the background, press a key.
*/
import processing.video.*;

  int numPixels;
  int[] backgroundPixels;
  Capture video;

void setup() {
  size(640, 480);
  // This the default video input, see the GettingStartedCapture
  // example if it creates an error
  //video = new Capture(this, 160, 120);

  //ビデオキャプチャ開始
  video = new Capture(this, width, height);
  // Start capturing the images from the camera
  //カメラからの画像の取得を開始
  video.start();

  //総画素数を計算し変数numPixelsへ
  numPixels = video.width * video.height;
  // Create array to store the background image
  //背景の画像データを保存するための配列を用意
  backgroundPixels = new int[numPixels];
  // Make the pixels[] array available for direct manipulation
  //ピクセルデータを直接扱うために画像のピクセルデータを用意
  loadPixels();

}

void draw() {

  //カメラがキャプチャできる状態なら......
  if (video.available()) {
    video.read(); // Read a new video frame 新規のビデオ画像を読み込み
    video.loadPixels(); // Make the pixels of video available 読み込んだ画像のピクセルデータを用意する
    // Difference between the current frame and the stored background
    //これ以下で保存してある背景画像(backgroundPixels)と新規で読み込んだ画像を比較し、違いを検出
    int presenceSum = 0;
    for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
      // Fetch the current color in that location, and also the color
      // of the background in that spot
      //新規に読み込んだ画像の画素を変数へ
      color currColor = video.pixels[i];
      //保存してある背景画像の画素を変数へ
      color bkgdColor = backgroundPixels[i];

      // Extract the red, green, and blue components of the current pixel's color
      //画素のR, G, Bを取り出す ビット演算子
      //int currR = (currColor >> 16) & 0xFF;
      float currR = red(currColor);
      //int currG = (currColor >> 8) & 0xFF;
      float currG = green(currColor);
      //int currB = currColor & 0xFF;
      float currB = blue(currColor);

      // Extract the red, green, and blue components of the background pixel's color
      //保存してある背景画像の画素からR, G, Bを取得

      //int bkgdR = (bkgdColor >> 16) & 0xFF;
      float bkgdR = red(bkgdColor);
      //int bkgdG = (bkgdColor >> 8) & 0xFF;
      float bkgdG = green(bkgdColor);
      //int bkgdB = bkgdColor & 0xFF;
      float bkgdB = blue(bkgdColor);

      // Compute the difference of the red, green, and blue values
      //取り出したR, G, Bの値の差を計算
      //int diffR = abs(currR - bkgdR);
      float diffR = abs(currR - bkgdR);
      //int diffG = abs(currG - bkgdG);
      float diffG = abs(currG - bkgdG);
      //int diffB = abs(currB - bkgdB);
      float diffB = abs(currB - bkgdB);

      // Add these differences to the running tally
      //計算した差の合計を算出
      presenceSum += diffR + diffG + diffB;
      // Render the difference image to the screen
      //差を画面に表示する
      pixels[i] = color(diffR, diffG, diffB);
      // The following line does the same thing much faster, but is more technical
      //シフト演算子
      //pixels[i] = 0xFF000000 | (diffR << 16) | (diffG << 8) | diffB;
    }

    //pixelsの配列に従って、画面に描画
    updatePixels(); // Notify that the pixels[] array has changed
    println(presenceSum); // Print out the total amount of movement
  }
}

// When a key is pressed, capture the background image into the backgroundPixels

// buffer, by copying each of the current frame's pixels into it.

//キーが押し下げられたときに、キャプギャされたカメラからの画像をbackgroundPixelsに保存
void keyPressed() {

  video.loadPixels();
  arraycopy(video.pixels, backgroundPixels);

}


背景の除去
/**
 * Background Subtraction
 * by Golan Levin.
 *
 * Detect the presence of people and objects in the frame using a simple
 * background-subtraction technique. To initialize the background, press a key.
 */

import processing.video.*;

int numPixels;
int[] backgroundPixels;
Capture video;

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

 // This the default video input, see the GettingStartedCapture
 // example if it creates an error
 //video = new Capture(this, 160, 120);
 video = new Capture(this, width, height);

 // Start capturing the images from the camera
 video.start(); 

 numPixels = video.width * video.height;
 // Create array to store the background image
 backgroundPixels = new int[numPixels];
 // Make the pixels[] array available for direct manipulation
 loadPixels();
}

void draw() {
 if (video.available()) {
 video.read(); // Read a new video frame
 video.loadPixels(); // Make the pixels of video available
 // Difference between the current frame and the stored background
 int presenceSum = 0;
 for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
 // Fetch the current color in that location, and also the color
 // of the background in that spot
 color currColor = video.pixels[i];
 color bkgdColor = backgroundPixels[i];
 // Extract the red, green, and blue components of the current pixel's color
 float currR = red(currColor);
 float currG = green(currColor);
 float currB = blue(currColor);

// int currR = (currColor >> 16) & 0xFF;
// int currG = (currColor >> 8) & 0xFF;
// int currB = currColor & 0xFF;
 // Extract the red, green, and blue components of the background pixel's color
 float bkgdR = red(bkgdColor);//(bkgdColor >> 16) & 0xFF;
 float bkgdG = green(bkgdColor);//(bkgdColor >> 8) & 0xFF;
 float bkgdB = blue(bkgdColor);//bkgdColor & 0xFF;
 // Compute the difference of the red, green, and blue values
 float diffR = abs(currR - bkgdR);
 float diffG = abs(currG - bkgdG);
 float diffB = abs(currB - bkgdB);

 // Add these differences to the running tally
 presenceSum += diffR + diffG + diffB;
 // Render the difference image to the screen
 float threshold = map(mouseX, 0, width,0, 255 );
 float diffSum = diffR+diffG+diffB;
 if( diffSum < threshold){
 pixels[i] = color(0, 0, 0);
 }else{

 pixels[i] = color(currR, currG, currB);
 }
 // The following line does the same thing much faster, but is more technical
 //pixels[i] = 0xFF000000 | (diffR << 16) | (diffG << 8) | diffB;
 }
 updatePixels(); // Notify that the pixels[] array has changed
 // println(diffR+diffG+diffB); // Print out the total amount of movement
 }
}

// When a key is pressed, capture the background image into the backgroundPixels
// buffer, by copying each of the current frame's pixels into it.
void keyPressed() {
 video.loadPixels();
 arraycopy(video.pixels, backgroundPixels);
}

 

写真と合成

/**
 * Background Subtraction
 * by Golan Levin.
 *
 * Detect the presence of people and objects in the frame using a simple
 * background-subtraction technique. To initialize the background, press a key.
 */

import processing.video.*;

int numPixels;
int[] backgroundPixels;
Capture video;
PImage img;

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

 // This the default video input, see the GettingStartedCapture
 // example if it creates an error
 //video = new Capture(this, 160, 120);
 video = new Capture(this, width, height);
 img = loadImage("fuji.JPG");

 // Start capturing the images from the camera
 video.start(); 

 numPixels = video.width * video.height;
 // Create array to store the background image
 backgroundPixels = new int[numPixels];
 // Make the pixels[] array available for direct manipulation
 loadPixels();
}

void draw() {
 if (video.available()) {
 video.read(); // Read a new video frame
 video.loadPixels(); // Make the pixels of video available
 // Difference between the current frame and the stored background
 int presenceSum = 0;
 for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
 // Fetch the current color in that location, and also the color
 // of the background in that spot
 color currColor = video.pixels[i];
 color bkgdColor = backgroundPixels[i];
 // Extract the red, green, and blue components of the current pixel's color
 float currR = red(currColor);
 float currG = green(currColor);
 float currB = blue(currColor);

// int currR = (currColor >> 16) & 0xFF;
// int currG = (currColor >> 8) & 0xFF;
// int currB = currColor & 0xFF;
 // Extract the red, green, and blue components of the background pixel's color
 float bkgdR = red(bkgdColor);//(bkgdColor >> 16) & 0xFF;
 float bkgdG = green(bkgdColor);//(bkgdColor >> 8) & 0xFF;
 float bkgdB = blue(bkgdColor);//bkgdColor & 0xFF;
 // Compute the difference of the red, green, and blue values
 float diffR = abs(currR - bkgdR);
 float diffG = abs(currG - bkgdG);
 float diffB = abs(currB - bkgdB);

 // Add these differences to the running tally
 //presenceSum += diffR + diffG + diffB;
 // Render the difference image to the screen
 float threshold = map(mouseX, 0, width,0, 255 );
 float diffSum = diffR+diffG+diffB;
 if( diffSum< threshold){
 pixels[i] = img.pixels[i];
 }else{

 pixels[i] = color(currR, currG, currB);
 }
 // The following line does the same thing much faster, but is more technical
 //pixels[i] = 0xFF000000 | (diffR << 16) | (diffG << 8) | diffB;
 }
 updatePixels(); // Notify that the pixels[] array has changed
 // println(diffR+diffG+diffB); // Print out the total amount of movement
 }
}

// When a key is pressed, capture the background image into the backgroundPixels
// buffer, by copying each of the current frame's pixels into it.
void keyPressed() {
 video.loadPixels();
 arraycopy(video.pixels, backgroundPixels);
}

今日の課題 – Color Trackingのプログラムを作成する

  1. Tracking Brightnessのソースコードを参考に、画面の緑の物体を追跡するプログラムを作成する。
  2. 画面上にellipse3つを表示させ、そのそれぞれが赤、青、緑を追跡するプログラムを作成する。
  3. キー入力で、’R’キーで赤、’B’キーで青、’G’キーで緑を追跡するよう、切り替えられるプログラムを作成する。

3までできたら3のソースコードに学籍番号と名前をコメント文として入れ、提出する。

 

ピクチャリウム