33
SSAW08 後期第9回 作品制作のヒント Processing + Videoライブラリ 2008年11月18日

Ssaw08 1118

Embed Size (px)

Citation preview

Page 1: Ssaw08 1118

SSAW08 後期第9回

作品制作のヒントProcessing + Videoライブラリ2008年11月18日

Page 2: Ssaw08 1118

今日の内容

• ProcessingのVideoライブラリを使ってみる• Processingでビデオのデータをあつかうことができるようになる

• カメラの映像をリアルタイム処理• QuickTime形式の動画を読み込んで処理• 動画を生成

• 今日は主にカメラのリアルタイム処理を中心に

Page 3: Ssaw08 1118

カメラのキャプチャー:基本

• コンピュータに接続されたカメラの情報を取得するには• VideoライブラリのCaptuerクラスを使用する• カメラの情報の取得の手順• Videoライブラリのインポート (processing.video.*)• setup() 内で

• Captuerクラスをインスタンス化 (video)• draw() 内で

• カメラが使用可能か確認• 使用可能であれば

• カメラのキャプチャーした情報をとりだし (video.read)• とりだした画像(PImage)を、ステージに描画

Page 4: Ssaw08 1118

カメラのキャプチャー:基本

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); }}

Page 5: Ssaw08 1118

カメラのキャプチャー:基本

Page 6: Ssaw08 1118

カメラの画像をピクセル単位で処理する

• カメラから取得されたイメージを処理したい• カメラから取り出したイメージ(PImage)のデータをピクセル単位でと

りだす必要がある• 「イメージオブジェクト.loadPixels()」でピクセル情報をとりだす• とりだした結果は、「イメージオブジェクト.pixels」配列に格納される

• 例 Captureクラスのインスタンスがvideoの場合video.read();video.loadPixels();

• 読み出したピクセルを上下左右に反転させて表示してみる

Page 7: Ssaw08 1118

カメラの画像をピクセル単位で処理する

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); } } }}

Page 8: Ssaw08 1118

カメラの画像をピクセル単位で処理する

Page 9: Ssaw08 1118

ビデオミラー

• カメラから取得された情報を利用して、画像を合成してみる• 画面の半分だけ左右に反転してみる

Page 10: Ssaw08 1118

ビデオミラー

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]); } } }}

Page 11: Ssaw08 1118

ビデオミラー

Page 12: Ssaw08 1118

ビデオミラー

• さらに横にも分割し、それぞれを上下に反転• 万華鏡?

Page 13: Ssaw08 1118

ビデオミラー

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]); } } }}

Page 14: Ssaw08 1118

ビデオミラー

Page 15: Ssaw08 1118

ビデオの色情報を操作する

• ピクセルのRGB値を取得• R(赤):red(video.pixels[loc]);• G(緑):green(video.pixels[loc]);• B(青):blue(video.pixels[loc]);

• この値を操作すると、色情報を変化させることが可能• 例、RGBの値を反転

Page 16: Ssaw08 1118

ビデオの色情報を操作する

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);}

Page 17: Ssaw08 1118

ビデオの色情報を操作する

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); } } }}

Page 18: Ssaw08 1118

ビデオの色情報を操作する

Page 19: Ssaw08 1118

ピクセレート

• 取得したビデオのRGB値をもとに、図形を描画する• ビデオの画像を反映し、ピクセレートされた画像を生成できる• 様々な形で試してみる

• ellipse• rect• line

Page 20: Ssaw08 1118

ピクセレート

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);}

Page 21: Ssaw08 1118

ピクセレート

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(); } } }}

Page 22: Ssaw08 1118

ピクセレート

Page 23: Ssaw08 1118

ピクセレート

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);}

Page 24: Ssaw08 1118

ピクセレート

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(); } } }}

Page 25: Ssaw08 1118

ピクセレート

Page 26: Ssaw08 1118

トラッキング

• ビデオの角ピクセルの明度を比較• 一番明るい場所を求める• その場所に図形を描画• 明い場所をトラッキングできる

Page 27: Ssaw08 1118

トラッキング

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++) {

Page 28: Ssaw08 1118

トラッキング

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); }}

Page 29: Ssaw08 1118

トラッキング

Page 30: Ssaw08 1118

スリットスキャン

• 映像の一部をスリット状に読み取って、時間の経過を表現する• スキャナーで映像を読みとっているような状態

Page 31: Ssaw08 1118

スリットスキャン

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;

Page 32: Ssaw08 1118

スリットスキャン

//ビデオから読みだすピクセルのインデックスを算出 int getPixelIndex = y*video.width + videoSliceX; //画面の特定の位置のピクセルをビデオから読みとったピクセルに変更 pixels[setPixelIndex] = video.pixels[getPixelIndex]; } updatePixels(); //描画する場所をずらす drawPositionX++; if (drawPositionX > width - 1) { drawPositionX = 0; } }}

Page 33: Ssaw08 1118

スリットスキャン