開発環境
言語
- 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());
}
}