jump to navigation

ProcessingでWebカメラ動画万華鏡

2009-07-21 00:19 Posted by
nase
in : プログラミング
3colors.jpg

VimでProcessingを書く環境が整ったので、早速思いつきでひとつ作ってみました。

WebCamからの動画インプットをリアルタイムで万華鏡風に表示します。

Processingの機能のおかげで3Dっぽい視点移動も実現できました。

WebCamをお持ちの方はローカルに保存してお試しください。WebCamが無い場合はアプレットで動作する静的画像版も用意してあります。

WebCam Kaleidoscope

ソースは大体100行程度。とりあえず6角形をひとつ作ってみて、それを並べる形で実装しました。左ドラッグで画像表示位置の調整、右ドラッグで視点の三次元移動ができます。

mangekyo_webcam_s.jpg
Processing WebCam動画万華鏡

なお、WindowsでProcessingのVideoプラグインを使うためには別途WinVDIGというソフトがインストールされている必要があります。(参考→Processing で Webcam を使って遊ぶ。[基本編] - trial and error)

import processing.video.*;

int hen = 100;
float takasa = hen * sqrt(3) / 2;
boolean hanten = false;
int texture_x = 0;
int texture_y = 0;
float camera_x = 0;
float camera_y = 0;
Capture cap;

void setup() {
  size(1024, 768, P3D);
  noStroke();
  frameRate(10);
  cap = new Capture(this, 320, 240);
  camera_x = width/2.0;
  camera_y = height/2.0;
  perspective();
}

void draw() {
  background(#000000);
  camera(camera_x, camera_y, (height/2.0) / tan(PI*60.0 / 360.0) / 2, width/2.0, height/2.0, 0, 0, 1, 0);
  if(cap.available()) {
    cap.read();
    for(int i=0 ; takasa * i < height + takasa ; i++) {
      if (i % 2 == 0) {
        pushMatrix();
        translate(hen / 2, takasa * i);
        sankaku6();
        for(int j=3 ; hen * j < width ; j+=3) {
          translate(hen * 3, 0);
          sankaku6();
        }
        popMatrix();
      }else{
        for(int j=2 ; hen * j < width + hen ; j+=3) {
          pushMatrix();
          translate(hen * j, takasa * i);
          sankaku6();
          popMatrix();
        }
      }
    }
  }
}

void sankaku6() {
  for(int i=0 ; i < 360 ; i += 60) {
    pushMatrix();
    if (hanten) {
      rotateY(radians(180));
      hanten = false;
    }else{
      hanten = true;
    }
    rotate(radians(i));
    sankaku1();
    popMatrix();
  }
}

void sankaku1() {
  beginShape(TRIANGLES);
  texture(cap);
  vertex(0, 0, hen / 2 + texture_x, 0 + texture_y);
  vertex(hen / 2, takasa, hen + texture_x, takasa + texture_y);
  vertex(-hen / 2, takasa, 0 + texture_x, takasa + texture_y);
  endShape();
}

void mouseDragged() {
  if(mouseButton == LEFT) {
    texture_x += mouseX - pmouseX;
    if (texture_x < 0) {
      texture_x = 0;
    }else if (texture_x > cap.width - hen) {
      texture_x = cap.width - hen;
    }
    texture_y += mouseY - pmouseY;
    if (texture_y < 0) {
      texture_y = 0;
    }else if (texture_y > cap.height - hen) {
      texture_y = cap.height - hen;
    }
  } else if (mouseButton == RIGHT) {
    camera_x += mouseX - pmouseX;
    if (camera_x < 0) {
      camera_x = 0;
    }else if (camera_x > width) {
      camera_x = width;
    }
    camera_y += mouseY - pmouseY;
    if (camera_y < 0) {
      camera_y = 0;
    }else if (camera_y > height) {
      camera_y = height;
    }
  }
}

静的画像版はProcessingのエクスポート機能でアプレットに書き出しました。次のリンクから開きます。(要Javaプラグイン)

Processing万華鏡(kaleidoscope_static_image.pde)

こちらも同じく左ドラッグで画像表示位置の調整、右ドラッグで視点を移動します。ソースはリンク先ページ下部でリンクされているのでそちらを参照してください。ちなみに表示している画像はこれです。

参考書籍

Built with Processing [改訂版] Built with Processing [改訂版]

例によってこちらの書籍を大変参考にさせていただきました。Videoプラグインもばっちり紹介されてます。


ロジクール キューカム S7500 QCAM-130XH ロジクール キューカム S7500 QCAM-130XH

この万華鏡を作りたいが為にWebCamを購入しました。どうやらこちらのモデルが定番の様子。


Comments»

1. k_taroh - 2011-12-20

今,Processingを使用してwebカメラのプログラムしているんですが、読み込んだイメージの画面に上下反転とワープ(極座標)のようなエフェクトをかけたいんですが、ワープ(極座標)の方が上手くいかなくて苦労しています。よかったら教えていただけませんか?

import processing.video.*;
int cols, rows;
Capture cam;
void setup() {
size(screen.width, screen.height, P3D);
background(0, 0, 0);
frameRate(30);
cam = new Capture(this, 432,729);
}
void draw() {
if (cam.available()) {
//ビデオ情報の読込み
cam.read();
filter(BLUR,3);//ぼかし
filter()
//ピクセル情報を配列(pixels)に格納する
cam.loadPixels();
//行(i)、列(j)の順にピクセルのとりだし
for (int i = 0; i < 432; i++) {
for (int j = 0; j < 729; j++) {
int loc = i + j*432;
color c = cam.pixels[loc];
//上下に反転
set( 1050-i, 850-j, c);
}
}
}
}

2. nase - 2011-12-21

すみません。よく分からないので他をあたってください。


*Comments and trackbacks will appear after it is approved by the administrator.