realsenseをいじくりまわしている今日この頃です。
僕がrealsenseをいじる場合、主に二つの使い方があります。
一つはrealsenseそのもののSDKを用いて情報を引き出す場合。
もう一つはrealsenseから画像を引っ張りだしてopenCV(c++)で画像処理をする場合。
で。実際画像処理などをした場合何らかのデータが引っ張りだすことができます。
このデータを用いてなにかを作りたい場合、あなたならどうしますか?
私はUnityに流し込んでやろうと思いました。
realsenseの場合はUnity用のパッケージがSDKに付属しています。それを使うのも一つの手です。
しかし、自分でopenCVなどを用いて処理をかけた場合はどうやってUnityに流しこんであげようかなと考えたときに僕が思いついたのは2つ。
1. c++のネイティブコードを書いたソースをdllにしてUnityに呼び出させる。
- c++/CLIを用いてラッパー関数を用意してからUnityに呼びださせる。
で一応両方作ったんですけど、後者がいまいちちゃんと動いてくれなかったので今回は1つ目の方法を紹介したいと思います。
そのうちc++/CLI使った方法もソースあげたいと思います。
環境はwin10でvisual studio 2015です。
(あとから拡張しようと思って若干余計な文字があります。)
ビルドしたdllはAssets\Plugins\x86_64に放り込んでおきます。そしてスクリプトをboxにでも貼り付けてみてください。
再生を押すといい感じに動くことでしょう。
ざっと解説。
c#のstart()から見ていきます。
c++のdllを使ってc#から呼び出すときには基本的に関数を呼び出すのが基本的な手法。
そこでrealSenseのインターフェースクラスを用意してそれをnewする関数を用意。
でインスタンスのアドレスをvoid*型でC#のIntPtr型でc#の方受け止めます。
それをやってるのがrealsensePtr=getCamera()。
でそのあとUnity側で画像を扱うクラスのインスタンスを用意して、ピクセル配列を取得します。
その配列をGCHadle(~, GCHandleType.Pinned)でガベージコレクションの働きでメモリを動かないように固定。
でメモリを固定したら配列のアドレスをpixel_ptrにぶち込みます。
ここまでstart()の中身。
次にUpdate()。
cameraUpdate()にポインタを投げ込んで更新させています。
それだけ。
最後にOnApplicationQuit()。
これはアプリが終了するときに勝手に呼ばれる関数で、
GCHandleで固定したメモリを開放しているのと、自分で作ったRealsenseInterfaceクラスのインスタンスのアドレスを破棄しています。
ざっとこんな感じです。
調べていてちょっと驚いたのですが、UnityはColor32のほうがColorより速いそうです。へー。
使うときは裏で32に変換してるからとかそういった理由らしい。
今回はrealsenseでやりましたがopenCVのVideoCaptureクラスとかを使っても同じような方法で実装することができます。