少し進んだスケッチのトップに戻る    印刷する

ポーズとインタラクションする(PoseNet)

カメラがとらえた画像から身体を検知し、目や腕、足の位置などにインタラクティブに応答するProcessingスケッチを作成します。ここでは、機械学習を使った身体のモーションキャプチャシステムのPoseNetを使います。

RunwayML

PoseNetはRunwayMLが学習済みモデルを提供しています。
RunwayMLは機械学習システムを自分のプログラムから容易に使えるように、操作のためのインターフェイスと計算量の多い機械学習システムを実行するコンピュータGPU(Graphics Processing Unit)を提供しているプロジェクトです。画像合成、物体検知、テキスト合成などさまざまな学習済みモデルが利用できます。
RunwayMLを介して、ローカル(自分のコンピュータ上)で機械学習システムを実行するのは無料ですが、RunwayMLが提供するGPUを使う場合は、GPU Creditが必要。Creditは買う必要があり、1分あたり5セント(US)。

次のようにRunwayMLからPoseNetを使う準備をします。

PoseNet

PoseNetは17のキーポイントを検出し、その結果をposes配列(JSONArray)に入れて送信します。
その構造は次の通りです。
  "scores": 精度の平均
  "poses": 配列 [pose, pose, pose, …]
                └─keypointsの配列 [keypoint, keypoint, keypoint, …]
                                      └─位置情報 [x位置, y位置]
keypoints配列のインデックスと部位の名前は次の通りです。

PoseNetからの情報を使うサンプル

Processingのスケッチで、PoseNetからOSCを介してデータを受け取り、処理をするには次のようにします。 リストA5_1は、ポーズを検知し、目、鼻、手首の位置情報使って鼻、目、手首の位置を描くスケッチです。スケッチを実行する前に、Runwayアプリを実行、あるいはRunwayのWeb版を起動後、PoseNetをモデルとしたワークスペースで、モデルを実行します。
PoseNetSketch
【リストA5-1】
import processing.video.*; //カメラ画像を表示する場合
import oscP5.*;  //(1)
import netP5.*;  //(1)

String runwayHost = "127.0.0.1";
int runwayPort = 57100; //PoseNetのデータ送信ポート
OscP5 oscP5;            //(2)
NetAddress myBroadcast; //(3)
JSONObject data;
Capture cam;  //カメラ画像を表示する場合

void setup() {
  size(640, 480);
  OscProperties properties = new OscProperties();  //(4)
  properties.setRemoteAddress(runwayHost, 57200); //PoseNetが動くホストのIP
  properties.setListeningPort(57200);   //PoseNetからのデータを受けるポート
  properties.setDatagramSize(99999999); //データバッファのパケットサイズを大きく
  properties.setSRSP(OscProperties.ON); //送信と受信のポート番号を同じにする
  oscP5 = new OscP5(this, properties);  //(5)ポート57200で聞く
  myBroadcast = new NetAddress(runwayHost, runwayPort);//(6)PoseNetホスト
  connect();  //(9)PoseNetと接続
  cam = new Capture(this, 640, 480);  //カメラ画像を表示する場合
  cam.start();                        //カメラ画像を表示する場合
}

void draw() {
  if (cam.available() == true) {      //カメラ画像を表示する場合
    cam.read();
  }
  image(cam, 0, 0, width, height);
  if (data != null) {
    JSONArray poses = data.getJSONArray("poses");
    if (poses.size()>0) {
      JSONArray human = poses.getJSONArray(0); //配列posesの先頭要素(ひとりめ)
      JSONArray nose = human.getJSONArray(0);  //先頭は鼻
      float x = nose.getFloat(0);
      float y = nose.getFloat(1);
      JSONArray eyeL = human.getJSONArray(1); //左目
      JSONArray eyeR = human.getJSONArray(2); //右目
      //両目の間隔で鼻に描く円の大きさを変える
      float d = dist(eyeL.getFloat(0), eyeL.getFloat(1),
                     eyeR.getFloat(0), eyeR.getFloat(1));
      fill(255, 0, 0);
      ellipse(x*width, y*height, d*width, d*width);

      x = eyeL.getFloat(0);  //左目
      y = eyeL.getFloat(1);
      fill(255);
      ellipse(x*width, y*height, 25, 25);
      fill(0);
      ellipse(x*width, y*height, 10, 10);
      x = eyeR.getFloat(0);  //右目
      y = eyeR.getFloat(1);
      fill(255);
      ellipse(x*width, y*height, 25, 25);
      fill(0);
      ellipse(x*width, y*height, 10, 10);
      //手首
      fill(255, 255, 0);
      ellipse(human.getJSONArray(9).getFloat(0)*width,
              human.getJSONArray(9).getFloat(1)*height, 25, 25);
      ellipse(human.getJSONArray(10).getFloat(0)*width,
              human.getJSONArray(10).getFloat(1)*height, 25, 25);
    }
  } else {
    println("data is null");
  }
}
void oscEvent(OscMessage message) {  //(10)OSCからデータが来ると実行される
  if (!message.addrPattern().equals("/data")) return;
  String dataString = message.get(0).stringValue(); //JSON形式の文字列
  data = parseJSONObject(dataString);
  println(data);
  println("/////////////////////////////");
}
void connect() {  //(7) connectメソッドを定義
  OscMessage m = new OscMessage("/server/connect");
  oscP5.send(m, myBroadcast);
}
void disconnect() {  //(8) disconnectメソッドを定義
  OscMessage m = new OscMessage("/server/disconnect");
  oscP5.send(m, myBroadcast);
}

演習問題


ポーズ
【問題A5-1】リストA5_1を変更して、複数の人のポーズを検知したら、その人数だけ、目、鼻、手首が描かれるようにしてみよう。



ポーズ
【問題A5-2】 Processingサンプルの[Topics][Simulate]のSimpleParticleSystemのParticle.pdeとParticleSystem.pdeを使い、手首の位置から噴水のように粒子が噴き出すスケッチを作ってみよう。

arigat アットマーク acm.org / copyright © info