Target
1. Webカメラで動画取得
2. その動画にシンプルな背景差分を適用
Environment
- OS
- java
- webcam-capture
- web camera
Develop
ライブラリの準備
Webカメラの制御に「
webcam-capture」というライブラリを利用している。
インストールはダウンロードして解凍するだけ。
- 上記リンクからダウンロード
- 解凍
- 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