Upload
atsushi-tadokoro
View
1.110
Download
4
Embed Size (px)
Citation preview
SSAW08 後期第9回
作品制作のヒントProcessing + Videoライブラリ2008年11月18日
今日の内容
• ProcessingのVideoライブラリを使ってみる• Processingでビデオのデータをあつかうことができるようになる
• カメラの映像をリアルタイム処理• QuickTime形式の動画を読み込んで処理• 動画を生成
• 今日は主にカメラのリアルタイム処理を中心に
カメラのキャプチャー:基本
• コンピュータに接続されたカメラの情報を取得するには• VideoライブラリのCaptuerクラスを使用する• カメラの情報の取得の手順• Videoライブラリのインポート (processing.video.*)• setup() 内で
• Captuerクラスをインスタンス化 (video)• draw() 内で
• カメラが使用可能か確認• 使用可能であれば
• カメラのキャプチャーした情報をとりだし (video.read)• とりだした画像(PImage)を、ステージに描画
カメラのキャプチャー:基本
import processing.video.*;Capture video;
void setup() { size(640, 480); //カメラの読込み video = new Capture(this, width, height);}
void draw() { //カメラが使用可能か? if (video.available() == true) { //カメラ画像の読込み video.read(); //画面に描画する image(video, 0, 0); }}
カメラのキャプチャー:基本
カメラの画像をピクセル単位で処理する
• カメラから取得されたイメージを処理したい• カメラから取り出したイメージ(PImage)のデータをピクセル単位でと
りだす必要がある• 「イメージオブジェクト.loadPixels()」でピクセル情報をとりだす• とりだした結果は、「イメージオブジェクト.pixels」配列に格納される
• 例 Captureクラスのインスタンスがvideoの場合video.read();video.loadPixels();
• 読み出したピクセルを上下左右に反転させて表示してみる
カメラの画像をピクセル単位で処理する
import processing.video.*;int cols, rows;Capture video;
void setup() { size(640, 480, P3D); frameRate(30); video = new Capture(this, width, height);}
void draw() { if (video.available()) { //ビデオ情報の読込み video.read(); //ピクセル情報を配列(pixels)に格納する video.loadPixels(); //行(i)、列(j)の順にピクセルのとりだし for (int i = 0; i < width ; i++) { for (int j = 0; j < height; j++) { int loc = i + j*width; color c = video.pixels[loc]; //上下に反転 set(width-i, height-j, c); } } }}
カメラの画像をピクセル単位で処理する
ビデオミラー
• カメラから取得された情報を利用して、画像を合成してみる• 画面の半分だけ左右に反転してみる
ビデオミラー
import processing.video.*;int cols, rows;Capture video;
void setup() { size(640, 480, P3D); frameRate(30); colorMode(RGB, 255, 255, 255, 100); video = new Capture(this, width, height, 12);}
void draw() { if (video.available()) { video.read(); video.loadPixels(); for (int i = 0; i < width / 2; i++) { for (int j = 0; j < height; j++) { int loc = i + j*width; set(i, j, video.pixels[loc]); set(video.width - i - 1, j, video.pixels[loc]); } } }}
ビデオミラー
ビデオミラー
• さらに横にも分割し、それぞれを上下に反転• 万華鏡?
ビデオミラー
import processing.video.*;int cols, rows;Capture video;
void setup() { size(640, 480, P3D); frameRate(30); video = new Capture(this, width, height, 12); background(0);}
void draw() { if (video.available()) { video.read(); video.loadPixels(); for (int i = 0; i < width / 2; i++) { for (int j = 0; j < height / 2; j++) { int loc = i + j*width; set(i, j, video.pixels[loc]); set(video.width - i - 1, j, video.pixels[loc]); set(i, video.height - j - 1, video.pixels[loc]); set(video.width - i - 1, video.height - j - 1, video.pixels[loc]); } } }}
ビデオミラー
ビデオの色情報を操作する
• ピクセルのRGB値を取得• R(赤):red(video.pixels[loc]);• G(緑):green(video.pixels[loc]);• B(青):blue(video.pixels[loc]);
• この値を操作すると、色情報を変化させることが可能• 例、RGBの値を反転
ビデオの色情報を操作する
import processing.video.*;int cols, rows;Capture video;
void setup() { size(640, 480, P3D); frameRate(30); colorMode(RGB, 255, 255, 255, 100); video = new Capture(this, width, height);}
ビデオの色情報を操作する
void draw() { if (video.available()) { video.read(); video.loadPixels(); for (int i = 0; i < width ; i++) { for (int j = 0; j < height; j++) { int loc = i + j*width; float r = red(video.pixels[loc]); float g = green(video.pixels[loc]); float b = blue(video.pixels[loc]); color c = color(255 - r, 255 - g, 255 - b); set(i, j, c); } } }}
ビデオの色情報を操作する
ピクセレート
• 取得したビデオのRGB値をもとに、図形を描画する• ビデオの画像を反映し、ピクセレートされた画像を生成できる• 様々な形で試してみる
• ellipse• rect• line
ピクセレート
import processing.video.*;int cellSize = 20;int cols, rows;Capture video;
void setup() { size(640, 480); frameRate(30); cols = width / cellSize; rows = height / cellSize; video = new Capture(this, width, height); smooth(); background(0);}
ピクセレート
void draw() { if (video.available()) { video.read(); video.loadPixels(); for (int i = 0; i < cols; i++) { for (int j = 0; j < rows; j++) { int x = i*cellSize; int y = j*cellSize; int loc = x + y*video.width; float r = red(video.pixels[loc]); float g = green(video.pixels[loc]); float b = blue(video.pixels[loc]); color c = color(r, g, b, 10); pushMatrix(); translate(x+cellSize/2, y+cellSize/2); noStroke(); fill(c); float radius = brightness(c)/255 * cellSize * 2; ellipse(0,0,radius,radius); popMatrix(); } } }}
ピクセレート
ピクセレート
import processing.video.*;int cellSize = 20;int cols, rows;Capture video;
void setup() { size(640, 480); frameRate(30); cols = width / cellSize; rows = height / cellSize; video = new Capture(this, width, height); smooth(); background(0);}
ピクセレート
void draw() { if (video.available()) { video.read(); video.loadPixels(); for (int i = 0; i < cols; i++) { for (int j = 0; j < rows; j++) { int x = i*cellSize; int y = j*cellSize; int loc = x + y*video.width; float r = red(video.pixels[loc]); float g = green(video.pixels[loc]); float b = blue(video.pixels[loc]); color c = color(r, g, b, 10); pushMatrix(); translate(x+cellSize/2, y+cellSize/2); noStroke(); fill(c); float radius = brightness(c)/255 * cellSize * 2; ellipse(0,0,radius,radius); popMatrix(); } } }}
ピクセレート
トラッキング
• ビデオの角ピクセルの明度を比較• 一番明るい場所を求める• その場所に図形を描画• 明い場所をトラッキングできる
トラッキング
import processing.video.*;Capture video;
void setup() { size(640, 480); video = new Capture(this, width, height); noStroke(); smooth();}
void draw() { if (video.available()) { video.read(); image(video, 0, 0, width, height); int brightestX = 0; int brightestY = 0; float brightestValue = 0; video.loadPixels(); int index = 0; for (int y = 0; y < video.height; y++) { for (int x = 0; x < video.width; x++) {
トラッキング
int pixelValue = video.pixels[index]; float pixelBrightness = brightness(pixelValue); if (pixelBrightness > brightestValue) { brightestValue = pixelBrightness; brightestY = y; brightestX = x; } index++; } } fill(255,0,0,128); ellipse(brightestX, brightestY, 100, 100); }}
トラッキング
スリットスキャン
• 映像の一部をスリット状に読み取って、時間の経過を表現する• スキャナーで映像を読みとっているような状態
スリットスキャン
import processing.video.*;Capture video;
int videoSliceX;int drawPositionX;
void setup() { size(900, 480); video = new Capture(this, 640, 480); videoSliceX = video.width / 2; drawPositionX = 0; background(0);}
void draw() { if (video.available()) { video.read(); //ビデオのピクセル情報を取得 video.loadPixels(); //画面全体のピクセル情報を取得 loadPixels(); for (int y = 0; y < video.height; y++){ //描画する位置のピクセルのインデックスを算出 int setPixelIndex = y*width + drawPositionX;
スリットスキャン
//ビデオから読みだすピクセルのインデックスを算出 int getPixelIndex = y*video.width + videoSliceX; //画面の特定の位置のピクセルをビデオから読みとったピクセルに変更 pixels[setPixelIndex] = video.pixels[getPixelIndex]; } updatePixels(); //描画する場所をずらす drawPositionX++; if (drawPositionX > width - 1) { drawPositionX = 0; } }}
スリットスキャン