カテゴリー

福井裕司 建築発明工作ゼミ|
2. Webカメラを光センサとして使う

四谷アート・ステュディウム2008年度「建築発明工作ゼミ」(講師=福井裕司)授業サブノートの一部です。「建築発明工作ゼミ2008」ブログより転載。

授業サブノートを抜粋して、2013年度「電子工作ゼミ」で教材として使用する、“Arduino”と“Processing”を用いた実践演習の内容を2回にわたってそれぞれ紹介します。第2回は“Processing”です。ゼミの資料としてご参照ください。


>> 電子工作ゼミの講座案内はこちらです


Processing Webカメラを光センサとして使う

今回は、パソコンに接続したWebカメラを光センサとして使う応用実験を行います。点光源(LEDなど)を空間内で動かし、その軌跡をProcessingの画面上に描画してみたいと思います(身体にLEDなどの点光源をつけて、腕を動かしたり歩いたりすれば、身体の動きを連続的に描画/記録することができます)。
Processingでは、videoライブラリを用いてWebカメラを通してキャプチャし、キャプチャした画面のピクセルをひとつずつ読み込んで、設定した明るさ以上のピクセルを選択します。選択したピクセルのみを別の色で表示するプログラムになります。
以下のプログラムでは、カメラからキャプチャした画像の各ピクセルの明るさ(0~255)を調べ、そのピクセルの明るさが254以上であれば、画面上に赤で表示する内容になります。クリックすれば、黒で塗りつぶして画面をリセットすることにします。
videoライブラリの基本的な使い方は「Processing Video(Webカメラ)」を参照して下さい。

*Windowsの場合、そのままの設定ではこのVideoライブラリを使用することができません。WinVDIG 1.0.1をインストールする必要があります。

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//ライブラリを取り込む
import processing.video.*;

//オブジェクトの用意
Capture video;

//画面サイズの変数と値
int w=320;
int h=240;

void setup() {
size(w, h);
video = new Capture(this, w, h, 30);
//背景を黒にしておく
background(0);
}

void draw() {
//画面のピクセルをロードしておく
loadPixels();

//カメラ画像のピクセルをひとつずつ調べる
for(int i=0;i //ピクセルが254以上の明るさの場合
if(brightness(video.pixels[i])>=254){
//選択されたピクセルを赤にする
pixels[i]=color(255,0,0);
}
}

//ピクセル表示更新
updatePixels();
}

//キャプチャ画面の読み込み
void captureEvent(Capture video) {
video.read();
}

//マウスボタンを押したら
void mousePressed(){
//背景を黒にする
background(0);
}

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

LEDなどの点光源をカメラに対して動かせば、以下のような画像ができあがります。赤いピクセル部分が、動かした点光源の軌跡です。
capture1.png


webカメラからの映像と合成(オーバーレイ)するには、以下のようになります。ここでは、webカメラからの映像を左右鏡像反転しています(カメラによっては、セッティング画面で鏡像にできるものもあります)。カメラからの映像を鏡像にすることで、点光源を右に動かせば画面内の点光源も右に動くようになります。マウスボタンを押せば画面を黒にリセット、「s」キーを押すと画面内の映像をjpeg画像で保存、「t」キーを押すとカメラセッティング画面になります。
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

import processing.video.*;
Capture video;
int w=320;
int h=240;

//軌跡用の配列を用意しておく
int[] pix=new int[w*h];

void setup() {
size(w, h);
video = new Capture(this, w, h, 30);
//軌跡用配列の値をすべてゼロにしておく
for(int i=0;i pix[i]=0;
}
}

void draw() {
loadPixels();
for(int i=0;i if(brightness(video.pixels[i])>=254){
//ピクセルを鏡像反転するための計算
//配列に値を記憶しておく
int a=i/w;
pix[w-i%w+a*w]=255;//選択されたピクセルだけを255にする
}
//配列からの値を画面ピクセルへ代入
//選択されたピクセルを緑で画面表示
pixels[i]=color(0,pix[i],0);
}
updatePixels();

//合成するカメラ映像の処理
tint(255,128);//透明度128(50%)
scale(-1.0, 1.0);//左右反転(鏡像)
image(video, -w, 0);//映像出力
}

//カメラ映像読み込み
void captureEvent(Capture video) {
video.read();
}

//マウスボタンを押すとリセット(黒へ)
void mousePressed(){
for(int i=0;i pix[i]=0;
}
}

int num=0;//保存画像インデックスの変数

void keyPressed(){
//sキーを押すと(jpeg画像で保存)
if(key=='s'){
String s="image_" + num + ".jpg";//保存ファイル名
save(s);//画像保存
num++;//保存画像インデックスを+1しておく
}
//tキーを押すと
if(key=='t'){
video.settings();//カメラセッティング画面表示
}
}

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

「s」キーを押すことで画面をjpegフォーマットで保存できるようにsave()を用います。画像は、save()の括弧内の指定したファイル名でスケッチフォルダ内に保存されます。インデックス用の変数numを用意し、image_0.jpg、image_1.jpg、image_2.jpg...というように、保存名にはインデックス番号がつくようにします。
「t」キーを押せばsettings()によって、カメラのセッティング画面が現れます。カメラの露出やコントラストなどの設定が「オート/自動」になっている場合があるので、できれば「マニュアル/手動」に切り替えて、それぞれを固定値にしたほうが、選択するピクセルの明るさが変化せずに済むのでいいでしょう。

image_1.jpg
上画像:合成/重ね合わせられた映像
映像内の手にはボタン電池に接続されたLEDが点灯しています。
この画像は、プログラム中にある「s」キーを押して画像保存したものです。