開発環境
言語
- Processing 3.1.1
eclipseを使用し、core.jarをインポートした環境でコーディングしているため、ProcessingのIDEでは実行できません。
参考URL
http://hiroyukitsuda.com/archives/1721
- java 1.8.0_91
API
- Video
動画ファイル、ライブカメラ等の映像を扱う機能を提供
https://processing.org/reference/libraries/video/index.html
- OpenCV for Processing
画像処理・画像解析および機械学習等の機能を提供
OS
- macOS sierra 10.12.6
参考サイト
光り輝くパーティクルを作ってみよう
参考著書
Nature of Code -Processingではじめる自然現象のシミュレーション
フロー
1.setup
1.1 動画ファイルを指定
1.2 検知対象を設定
1.3 再生設定
2.draw
2.1 画面の明るさを指定調整し、モノクロで表示
2.2 OpenCVが検知した対象を配列に格納
2.3 検知した対象の頭上に発光する粒子を表示
2.4 全ての検知対象をラインで接続
コード
package detection.phase2; import java.awt.Rectangle; import gab.opencv.OpenCV; import processing.core.PApplet; import processing.video.Movie; public class WalkerDetection extends PApplet { Movie movie; OpenCV openCV; Rectangle[] detectsFromOCV; //---発光処理------------------------------------------- final int LIGHT_DISTANCE = 500*500; //光が届く距離 final int BORDER = 1000; //発光する計算範囲(短形) float baseR,baseG,baseB; //光の色 float baseRAdd,baseGAdd,baseBAdd; //色の加算量 final float RED_ADD = 2.7F; //赤色 final float GREEN_ADD = 2.2F; //緑色 final float BLUE_ADD = 3.5F; //青色 float lightPower; //光の大きさ public void settings() { size(1280, 720); } public void setup() { //光色の初期化 baseR = 50; baseRAdd = RED_ADD; baseB = 100; baseBAdd = BLUE_ADD; baseG = 150; baseGAdd = GREEN_ADD; //動画ファイルを指定 movie = new Movie(this, "umeda_rain.m4v"); openCV = new OpenCV(this, width,height); //検知対象に歩行者を指定 openCV.loadCascade(OpenCV.CASCADE_PEDESTRIAN); //ループ再生 movie.loop(); movie.play(); //再生スピード movie.speed(0.3F); } public void draw() { //動画をメモリに展開 image(movie, 0, 0); openCV.loadImage(movie); //画面の明るさを調整。モノクロ表示とする。 openCV.brightness(-80); image(openCV.getOutput(), 0, 0 ); //OpenCVで検知したオブジェクトを配列に格納 detectsFromOCV = openCV.detect(); //--光の色を変更 baseR += baseRAdd*5; baseB += baseBAdd*5; baseG += baseGAdd*5; //色が範囲外になった場合は、色の加算値を逆転させる colorOutCheck(); //各ピクセルの色の計算 int tRed = (int)baseR; int tGreen = (int)baseG; int tBlue = (int)baseB; //綺麗に光を出すために二乗する tRed *= tRed; tGreen *= tGreen; tBlue *= tBlue; //各ピクセルの色の計算 loadPixels(); //各particleの周囲のピクセルの色について、加算を行う for(int i=0;i<detectsFromOCV.length;i++){ //particleの影響範囲を計算 int left = max(0,(int) (detectsFromOCV[i].getCenterX()-BORDER)); int right = min(width,(int) (detectsFromOCV[i].getCenterX()+BORDER)); int top = max(0,detectsFromOCV[i].y-BORDER); int bottom = min(height,detectsFromOCV[i].y+BORDER); //particle影響範囲の色を加算する for(int y = top;y<bottom;y++){ for(int x=left;x<right;x++){ int pixelIndex = x + y * width; //ピクセルから、赤・緑・青の要素を取りだす int r = pixels[pixelIndex] >> 16 & 0xFF; int b = pixels[pixelIndex] >> 8 & 0xFF; int g = pixels[pixelIndex] & 0xFF; //パーティクルとピクセルとの距離を計算する float dx = (float) (detectsFromOCV[i].getCenterX() -x); float dy = (detectsFromOCV[i].y + (detectsFromOCV[i].height/9)) - y; float distance = (dx * dx) + (dy * dy); //三平方の定理 //ピクセルとパーティクルの距離が一定以内であれば、色の加算を行う if(distance < LIGHT_DISTANCE){ if(distance < 1){ distance = 1; } //検知対象の大きさに比例したパーティクルとする lightPower = detectsFromOCV[i].width/30; r += tRed * lightPower/distance; g += tGreen * lightPower/distance; b += tBlue * lightPower/distance; } //ピクセルの色を変更する pixels[pixelIndex] = color(r,g,b); } } } updatePixels(); //検知対象をラインで接続する stroke(255,150); strokeWeight(2); for(int i=0;i<detectsFromOCV.length-1;i++){ for(int j=i+1;j<detectsFromOCV.length;j++){ line((float)detectsFromOCV[i].getCenterX(), (float)(detectsFromOCV[i].y + detectsFromOCV[i].height/9), (float)detectsFromOCV[j].getCenterX(), (float)(detectsFromOCV[j].y + detectsFromOCV[j].height/9) ); } } } //映像フレーム毎に自動呼び出しされるイベント public void movieEvent(Movie m) { //現在のフレームを読み込み m.read(); } //色の値が範囲外に変化した場合は符号を変える private void colorOutCheck() { if (baseR < 10) { baseR = 10; baseRAdd *= -1; } else if (baseR > 255) { baseR = 255; baseRAdd *= -1; } if (baseG < 10) { baseG = 10; baseGAdd *= -1; } else if (baseG > 255) { baseG = 255; baseGAdd *= -1; } if (baseB < 10) { baseB = 10; baseBAdd *= -1; } else if (baseB > 255) { baseB = 255; baseBAdd *= -1; } } //キー押下 public void keyPressed() { //Spaceキー if(key == ' '){ //一時停止 movie.pause(); } //ENTERキー if(key == ENTER){ //再生 movie.play(); } } public static void main(String[] args) { PApplet.main(WalkerDetection.class.getName()); } }