なるように、なる

徒然なつぶやき、備忘録です。

C++にPythonを組み込むメモ(Boost.python)

C++からPythonを呼びたいのです。
逆に比べると大分ニーズが少ない。
以下を参考にさせて頂きました。
Embedded Python in C++ / C++からPythonスクリプトを呼び出す - Qiita
Boost.PythonでC++からPythonの関数を呼び出す
C++からPythonを叩きつつ、boost.numpyを使ってC++とPython間でndarrayをやりとりする - verilog書く人

初期化
Py_Initialize();
auto main_mod = boost::python::::import("__main__");
auto main_ns = main_mod.attr("__dict__");
スクリプトの読み込み
std::string script((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
boost::python::::exec(script.c_str(), main_ns);
関数の実行
auto func = main_ns["func"];
auto result = func(1.0);
Pythonからの値のパース
boost::python::::extract<double>(result)
例外処理
try {
//
} catch (boost::python::error_already_set) {
    PyErr_Print();
}
リスト/タプルで引数渡し
boost::python::list list_val;
list_val.append(1.0);
list_val.append(2.0);
auto result = main_mod.attr("func")(list_val);
タプルを受け取る
using input_iterator = boost::python::stl_input_iterator<double>;
input_iterator begin(result), end;

std::vector<double> vals(begin, end);
for (auto val : vals) {
    std::cout << val << std::endl;
}

Boost.python/Boost.numpyを使いたい

openFrameworksを使い始めました。
そうしたらC++からPythonを呼び出したくなってきた。
以下の記事を参考に、Boost.pythonをインストールしたのでその記録。

PythonからC++を呼び出してnumpyを使う - TadaoYamaokaの日記
Boost.PythonおよびBoost.NumpyをWindowsで使うまで | tatsyblog

環境
  • Windows10
  • VisualStudio2015
  • Python 3.5.3 (c:\python35)
  • Boost 1.66 (c:\boost_1_66_0)
Boostのインストール

TadaoYamaokaさんの記事の手順のとおり。完全に同じ。ビリーブ。

  1. ダウンロードしたBoostを解凍して適当に配置。
  2. Boost.pythonのビルドを有効にする。
  3. Boostをビルド。
C++からBoost.pythonを使う

今度はtatsyさんのコードを参考にした。

#include "stdafx.h"
#define BOOST_PYTHON_STATIC_LIB
#define BOOST_NUMPY_STATIC_LIB
#include <Python.h>
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
#include <iostream>

namespace py = boost::python;
namespace np = boost::python::numpy;

int main()
{
    Py_Initialize();
    np::initialize();

    // Matrix A
    py::tuple shapeA = py::make_tuple(2, 2);
    np::ndarray A = np::zeros(shapeA, np::dtype::get_builtin<double>());
    A[0][0] = 1.0;
    A[0][1] = 2.0;
    A[1][0] = 3.0;
    A[1][1] = 4.0;

    // Vector b
    py::tuple shapeB = py::make_tuple(2);
    np::ndarray b = np::zeros(shapeB, np::dtype::get_builtin<double>());
    b[0] = 3.0;
    b[1] = 7.0;

    // Prepare numpy.linalg.solve
    py::object solve = py::import("numpy").attr("linalg").attr("solve");

    // Solve
    np::ndarray x = py::extract<np::ndarray>(solve(A, b));
    int dims = x.shape(0);
    for (int i = 0; i < dims; i++) {
        std::cout << py::extract<double>(x[i]) << std::endl;
    }

    return 0;
}

無事に動きました。
先輩ありがとうございます。

タブラの音を学習させた

タブラの演奏を視覚化させるために、タブラの音を識別させることにチャレンジしています。タブラは2つの太鼓から20種類ほどの音色をだすことが出来ますので、それをひとつひとつ識別して、演奏をリアルタイムにVJみたいにしたいと思ってます。

今回識別させた音

キールフセイン先生の曲を波形を見てみましょう。このピークになっているのが太鼓の音です。

f:id:Shampagne:20171111170959p:plain

今回はこの曲の中から4種類の音を切り出してみました。

「na」

f:id:Shampagne:20171111171723p:plain

「tun」

f:id:Shampagne:20171111171539p:plain

「te」

f:id:Shampagne:20171111171602p:plain

「ge」

f:id:Shampagne:20171111171615p:plain

波形を見てみると、それぞれ個性がありますね。なんとなくいけそうな気がしません?ちなみに、私はこの作業のために曲を聴きながらそれぞれの波形を30個ずつ切り出したので、波形を見て音を識別できるようになりましたw
同じことをプログラムにもやってもらおうと思います。

どうやって識別させるか?

色々と調べてみて、いちばんやりたいことに近かったのがこちらです。

webdatareport.hatenablog.com

あとは、「実践機械学習システム」の9章(音楽ジャンル分類)を参考にしました。

要点は音のデータをMFCC (メル周波数ケプストラム係数)に変換し、それを特徴量とするということです。はっきり言ってMFCCが何かはさっぱりですが、音声認識などではメジャーな手法ということです。先人の力に頼りまくりたいと思います。

識別させてみた

実は今回、大変だったのはここまでです。どうやるかを調べるのが大変でしたが、あとは凄く簡単(株式会社ルーター様!ありがと!)。

やったことは以下。

1.元の楽曲から学習用に太鼓の音を切り出す(4種類 x 30パターン)。
2.太鼓の音が入ってない部分をノイズデータとして切り出し、1.と混ぜてデータ水増し(soxという神ライブラリを利用)。
3.wavデータをMFCCに変換。
  ※scikits.talkboxなど、MFCCを計算するライブラリは色々ある。
4.3.で得た特徴量をCNNにかける。

結果

89%まで識別できるようになりました。おぉ。

 

 Epoch loss: 0.2590 - acc: 0.8841 - val_loss: 0.2423 - val_acc: 0.8900
Test loss: 0.242288478737
Test accuracy: 0.89

 

f:id:Shampagne:20171111180943p:plain

トライアルとしては十分な成果が得られました。
次回は学習したモデルを使って実際にザキール先生の曲を再生しながら太鼓の音をリアルタイムに識別してみたいと思います。

タブラの音を認識したいのだ

みなさん、タブラという楽器を知っていますか?

知らないですよね、そうですよね。

タブラはインドの古典楽器で、手の指で叩く2つの太鼓です。

名前は聞いたことないかも知れないけど、きっとみんな音は聞いたことあるはず。

シタールとセットで、インドっぽい音楽には必ず入っています。

僕はこのタブラが大好きなんです。

まずはこれ

キールフセイン大先生

世界最高のタブラプレイヤーです。間違いないです。

www.youtube.com

あと、よく知らないんだけど、楽しくタブラを叩いてる人たちw

www.youtube.com

 

タブラとは?

matome.naver.jp

ここで説明されているように、世界一難しい楽器と言われています。

実際、何年か前にどうしても自分で演奏してみたくて、先生に習ってみたんですが、これはちょっと無理かな、、って感じになっちゃいました。

しかし、それでもタブラの魅力は僕を惹きつけ続けています。

なんでタブラの音を認識させたいか?

昨年、渋谷WWWX(というライブハウス)の杮落し公演にザキール先生が来まして、幸運なことにチケットとれたので観にいったのです。

それはそれはどえらい演奏だったのです。

もう何が起きてるか分からないけど、とにかくすごい。

逆に言うと、凄すぎてワケが分からなかったのです。

それで、時間がたつにつれて、こう思うようになったのです。

「タブラの魅力をもっと分かり易くすることはできないか?」

そして、最近vvvvや機械学習を勉強しているなかで、タブラの音を視覚化してみたいと思うようになりました。

 

次回から、タブラの視覚化チャレンジの道のりを書いていきます。

ヨガポーズの認識と表現

ヨガポーズの認識をさせてみた

KinectV2で取得したスケルトンを、CNNで学習させたモデルでポーズ推定して、ヨガポーズと一致していたらパーティクルを出すというものをvvvvで作ってみました。

 

f:id:Shampagne:20171001221633p:plain

KinectでBodyを認識して、背景をセグメンテーションし、ヨガスタジオの背景画像に重ねました。実際は、とっ散らかった自宅で撮影してます。

f:id:Shampagne:20171001221926p:plain

ウッティタ・トリコーナーサナというポーズです。
事前に学習したポーズと一致した場合、パーティクルが出てくるようにしました。

f:id:Shampagne:20171001222200p:plain

上級者用の裏面を用意しました。
ポーズの一致度が90%以上かつ5秒以上キープできた場合に、このステージに遷移します。

f:id:Shampagne:20171001222348p:plain

ヨガのポーズはたくさんあります。8400万とも言われてます。
僕が今回学習させたのはたかだか10種類。とても上級者のヨギーには満足してもらえません。なので、このモードでは、同じ姿勢をキープ出来ていると判定したら、丹田のあたりからパーティクルを出すようにしました。

表現について考える

基本的な機能を実装できたあと、「オシャレにしていこう!」と思っていろいろ付け加いったんですが、正直、力不足でした。
こんな感じにしてみたいと思っても、vvvvでうまく表現できない。他の作品みたいに細かいパーティクルをシュワシュワしたいのに、、、とか。これは練習をするしかないな、と。
それ以上に悩んだのは「何を表現するべきか」ということ。
別に新しいことをしているつもりは無いけど、では逆になぜ自分は今この作品?を作っているんだろう、と。どのようにパーティクルを出すか、どこから出すかっていうだけでも、最初は「適当にオシャレになればいいや」と思っていたけど、ある本を読んでいるときに、ストーリーが大切、という一言を読んで、目が覚めました。

僕はなんでヨガのポーズを認識させたいんだろうか、ヴィジュアライズして何を表現したのだろう。

そういう観点から考え直した後、ヨガをして深く集中したときの世界を表現し、それをいろんな人に知ってもらえたらなぁ、と思って裏面を作りました。

もっと力をつけたら、もう一度ヨガポーズの作品に取り組みたいと思います。

次はタブラにチャレンジします。

ヨガポーズの認識(仮まとめ)

いったん一区切りして、ここまでに作ったものをアップします。

作ったもの

・OpenPoseで画像からスケルトン座標の推定

・Kerasでスケルトン座標によるヨガポーズの推定

・KinectV2のvvvvプラグインカスタマイズ

・vvvvで上記の結合

提出物1

vvvvでKinectからのデータを取り込み、TCPでKerasのバックエンドとデータ通信し、結果をもとに画像にエフェクトかけてます。パーツ作りは大変だったけど、vvvvで繋げるのはすごい簡単。

f:id:Shampagne:20170820212348j:plain

 

提出物2

 Kerasに学習させた3つのポーズとマッチすると、手の位置からパーティクルが出るようにしてみました。パーティクルが出てくる位置がちょっとずれてますが。。。

youtu.be

ここまではパーツ作りを一気にやってきたので、次は完成度を高める作業をやっていこうと思います。

ヨガポーズのクラス分類

ヨガのポーズを機械学習させて、自動で識別させるようにしました。

入力データの準備

ヨガのポーズは実にたくさんあるのですが、まずは識別し易い以下の3ポーズをチョイス。

f:id:Shampagne:20170815145230j:plain

f:id:Shampagne:20170815145244j:plain

f:id:Shampagne:20170815145310j:plain

これらのポーズの画像を10枚ずつ収集して、OpenPoseでスケルトンの座標を取得しました。

ちなみに、OpenPoseとKinectV2で取得できるスケルトンは、以下のようになってます。(OpenPoseはこちらが元ネタです。)

>OpenPose

f:id:Shampagne:20170816095804p:plain

>KinectV2

f:id:Shampagne:20170816095832p:plain

 

KinectV2で取得できない目、耳、背中の位置は使用せず、14点のx,y座標を入力データとしました。また、学習のための前処理として、以下の2つを行いました。

 ・頭の位置を原点とする

 ・頭から喉(0番と1番)の距離をもとにリサイズする

こうして得られた入力データを、ちょっと加工して各ポーズ400個に水増ししました。合計1200個なので、まぁまだ少ないですが、いったん進みます。

 

機械学習

利用したのはKerasで、バックエンドはTensorFlowです。

環境構築は、このサイトにお世話になりました(ありがとうございます)。

Keras、マニュアルも分かりやすかったので、無知でしたが割合すぐに使うことができました。

ただし、無知なのでネットワークをどう組めばいいかは、よく分かりません。

なので、MNISTのサンプルをそのまま使うことにしました。

MNISTは32x32の画像を入力としています。なので、行列サイズを16x16に変更して、各行に14カ所のx,y座標をマッピングしてみました。

半信半疑の感はありましたが、学習させたモデルを使って自分のヨガポーズを分類させてみると、見事に識別できてました。

すーごーいー。
(けもふれ再放送中)