ズッキーニのプログラミング実験場

プログラミング + アカデミック + 何か面白いこと。 記載されているものは基本的に私が所属する団体とは関係がありません。

   Jan 18

[Java][Webカメラ][背景差分]Webカメラで撮っている動画に簡単な背景差分を適用してみる

by zuqqhi2 at 2015年1月18日
Pocket

Target

1. Webカメラで動画取得
2. その動画にシンプルな背景差分を適用

Environment

  • OS
    • Windows 7 Enterprise SP1
  • java
    • 1.7.0_51-b13
  • webcam-capture
    • 0.3.10
  • web camera
    • PC購入時に本体についていたもの

Develop

ライブラリの準備

Webカメラの制御に「webcam-capture」というライブラリを利用している。
インストールはダウンロードして解凍するだけ。

  1. 上記リンクからダウンロード
  2. 解凍
  3. 3つのjarファイル(bridj-0.6.2.jar, slf4j-api-1.7.2.jar, webcam-capture-0.3.10.jar)をプロジェクトに追加

今回はIDEは特に利用しないため、以下のように配置した。

.
├── BackgroundSubtraction.java
├── BackgroundSubtraction.class
└── lib
      ├── bridj-0.6.2.jar
      ├── slf4j-api-1.7.2.jar
      └── webcam-capture-0.3.10.jar

1 directories, 5 files

ソースコード

import java.awt.image.BufferedImage;
import java.awt.Graphics2D;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.io.*;

import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamUtils;
import com.github.sarxos.webcam.util.ImageUtils;
import com.github.sarxos.webcam.WebcamPanel;
import com.github.sarxos.webcam.WebcamResolution;
import com.github.sarxos.webcam.WebcamImageTransformer;

public class BackgroundSubtraction implements WebcamImageTransformer {
  private BufferedImage background = null;
  
  public static int getR(int c) { return c>>16&0xff; }
  public static int getG(int c) { return c>>8&0xff;  }
  public static int getB(int c) { return c&0xff;       }
  public static int rgb(int r,int g,int b)  { return 0xff000000 | r <<16 | g <<8 | b; }
  
  // Get background image
  public void takePicture() throws IOException {
    Webcam webcam = null;
    webcam = Webcam.getDefault();
    if (webcam != null) {
      System.out.println("Webcam : " + webcam.getName());
      WebcamUtils.capture(webcam, "capture", ImageUtils.FORMAT_PNG);
    } else {
      System.out.println("Failed: Webcam Not Found Error");
      System.exit(1);
    }
    
    try {
      background = ImageIO.read(new File("./capture.png"));
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
  }
  
  @Override
  public BufferedImage transform(BufferedImage image) {
    int         width  = image.getWidth();
    int         height = image.getHeight();
    BufferedImage newImage = new BufferedImage(width, height, 5);

    // Background Subtraction Part
    for (int i = 0; i < width; i++) {
      for(int j = 0; j < height; j++) {
        int c = image.getRGB(i,j);
        int fr = getR(c);
        int fg = getG(c);
        int fb = getB(c);
        
        c = background.getRGB(i,j);
        int br = getR(c);
        int bg = getG(c);
        int bb = getB(c);
        int dist = Math.abs(fr - br) + Math.abs(fg - bg) + Math.abs(fb - bb);

        // Using only color value difference
        // In actual situation, more sophisticated technique is needed.
        if (dist > 50) {
          newImage.setRGB(i, j, image.getRGB(i,j));
        } else {
          // Background color is white
          newImage.setRGB(i, j, rgb(255,255,255));
        }
      }
    }
    
    return newImage;
  }

  public BackgroundSubtraction() {
    try {
      takePicture();
    } catch(IOException e) {
      System.out.println("Failed to take screenshot");
      System.exit(1);
    }
    
    Webcam webcam = Webcam.getDefault();
    webcam.setImageTransformer(this);
    
    WebcamPanel panel = new WebcamPanel(webcam);
    panel.setFPSDisplayed(true);
    panel.setFillArea(true);
    panel.setDisplayDebugInfo(true);
    //panel.setImageSizeDisplayed(true);
    panel.setMirrored(true);
    
    javax.swing.JFrame frame = new javax.swing.JFrame("BackgroundSubtraction");
    frame.add(panel);
    frame.setResizable(true);
    frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }
  
  public static void main(String[] args) {
    new BackgroundSubtraction();
  }
}

コンパイルと実行

以下のコマンドでコンパイルと実行ができる。

javac -cp .\lib\webcam-capture-0.3.10.jar;.\lib\bridj-0.6.2.jar;.\lib\slf4j-api-1.7.2.jar BackgroundSubtraction.java
java -cp .;.\lib\webcam-capture-0.3.10.jar;.\lib\bridj-0.6.2.jar;.\lib\slf4j-api-1.7.2.jar BackgroundSubtraction

Demo

backgroundsubtraction

Related Posts

Pocket

You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.