ねののお庭。

かりかりもふもふ。

openCVとUnityとc++と。

realsenseをいじくりまわしている今日この頃です。

僕がrealsenseをいじる場合、主に二つの使い方があります。

一つはrealsenseそのもののSDKを用いて情報を引き出す場合。

もう一つはrealsenseから画像を引っ張りだしてopenCV(c++)で画像処理をする場合。

で。実際画像処理などをした場合何らかのデータが引っ張りだすことができます。

このデータを用いてなにかを作りたい場合、あなたならどうしますか?

私はUnityに流し込んでやろうと思いました。

 

realsenseの場合はUnity用のパッケージがSDKに付属しています。それを使うのも一つの手です。

しかし、自分でopenCVなどを用いて処理をかけた場合はどうやってUnityに流しこんであげようかなと考えたときに僕が思いついたのは2つ。

1.  c++のネイティブコードを書いたソースをdllにしてUnityに呼び出させる。

  1. 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クラスとかを使っても同じような方法で実装することができます。