MRが楽しい

MRやVRについて学習したことを書き残す

hololensでOpenCVForUnityのサンプルを実行する

前回に引き続き、OpenCVForUnityに関する調査です。
・HoloLensでOpenCVの画像処理を利用する
 http://bluebirdofoz.hatenablog.com/entry/2017/04/23/015907

HoloLensWithOpenCVForUnityExampleに含まれるシーンファイルをbuildSettingsで下記のように読み込みます。
f:id:bluebirdofoz:20170424012950j:plain
すると、以下の8つのシーンがサンプルとして確認可能です。

・HoloLensWithOpenCVForUnityExample
 - サンプルの選択画面を表示するサンプルシーン
・ShowLicense
 - ライセンス情報画面を表示するサンプルシーン
・HoloLensWebCamTextureAsyncDetectFaceOverlayExample
 - 顔認識を行いテクスチャを表示するサンプルシーン
・HoloLensWebCamTextureAsyncDetectFaceExample
 - 顔認識を行いテクスチャを表示するサンプルシーン
・HoloLensPhotoCaptureExample
 - カメラ撮影を行い顔認識の画像処理を行ったファイルを出力するサンプルシーン
・HoloLensCoicFilterExample
 - 画面全体にコミックフィルタをかけて映像を表示するサンプルシーン
・HoloLnesArUcoWebCamTextureExample
 - 現在のカメラ撮像を小窓表示でリアルタイムに表示するサンプルシーン
・HoloLensAnonymousFaceExamle
 - 顔認識を行い顔を隠すように画像を表示するサンプルシーン

HoloLensWithOpenCVForUnityExampleとShowLicenseはアプリ操作画面とライセンス画面のため、実質6つのサンプルが試せます。
ビルドすると以下のようにサンプルシーンを選んで試すことができます。
f:id:bluebirdofoz:20170424013039j:plain

予期せず、まだ触れていなかったUnityのシーン遷移を試すことになりました。下記のスクリプトでシーン遷移しています。
HoloLensWithOpenCVForUnityExample.cs

// ShowLicenseシーンへの遷移
public void OnShowLicenseButton ()
{
    #if UNITY_5_3 || UNITY_5_3_OR_NEWER
    SceneManager.LoadScene ("ShowLicense");
    #else
    Application.LoadLevel ("ShowLicense");
    #endif
}


大別すると顔認識、全体フィルタ、小窓表示の3パターンです。
あくまでOpenCVForUnityの使い方を紹介するサンプルのようで、OpenCVの機能自体を色々試すようなサンプルはありません。
OpenCV未経験の自分はOpenCVでどういう事ができるかをそもそも知らないので、少しがっくり。
有識者にhololensではOpenCVのどんな機能を利用すると面白そうかを聞いてみる方が良いかも。

因みにHoloLensWebCamTextureAsyncDetectFaceOverlayExampleとHoloLensWebCamTextureAsyncDetectFaceExampleの違いはまだ判りません。
動作的には同じに見えるので、違いを知るには処理コードを確認する必要がありそうです。


肝心のOpenCVの利用箇所を見てみました。例えば、顔認識してるのはこのスクリプトの辺りかな?
HoloLensAnonymousFaceExample.cs

/// <summary>
/// The gray mat.
/// </summary>
Mat grayMat;

/// <summary>
/// The cascade.
/// </summary>
CascadeClassifier cascade;

private Mat grayMat4Thread;
private CascadeClassifier regionCascade;
(…中略…)
/// <summary>
/// Raises the web cam texture to mat helper inited event.
/// </summary>
public void OnWebCamTextureToMatHelperInited ()
{
    Mat webCamTextureMat = webCamTextureToMatHelper.GetDownScaleMat(webCamTextureToMatHelper.GetMat ());
    
    processingAreaRect = new OpenCVForUnity.Rect ((int)(webCamTextureMat.cols ()*(outsideClippingRatio.x - clippingOffset.x)), (int)(webCamTextureMat.rows ()*(outsideClippingRatio.y + clippingOffset.y)),
(int)(webCamTextureMat.cols ()*(1f-outsideClippingRatio.x*2)), (int)(webCamTextureMat.rows ()*(1f-outsideClippingRatio.y*2)));
    processingAreaRect = processingAreaRect.intersect (new OpenCVForUnity.Rect(0,0,webCamTextureMat.cols (),webCamTextureMat.rows ()));
(…中略…)
    grayMat = new Mat (webCamTextureMat.rows (), webCamTextureMat.cols (), CvType.CV_8UC1);
    regionCascade = new CascadeClassifier ();
    regionCascade.load (Utils.getFilePath ("lbpcascade_frontalface.xml"));

    initThread ();
}

OpenCVForUnityだからと特別な記法は必要なさそうなので、OpenCVを触った事がある人なら一目で何をしているかは分かりそう。
しかし、如何せん私はOpenCVをこれまで全く触ったことがないため、大苦戦中です。

本コードを利用しているHoloLensAnonymousFaceExamleを実行すると、顔の位置に画像が表示されました。
f:id:bluebirdofoz:20170424013340j:plain
サンプル中のキャプチャが撮れない問題ですが、やはりカメラのコントロールを奪われていることが原因のようです。
以下のwebCamTextureToMatHelperを停止すればキャプチャできることを確認しました。
HoloLensAnonymousFaceExample.cs

/// <summary>
/// Raises the stop button event.
/// </summary>
public void OnStopButton ()
{
    webCamTextureToMatHelper.Stop ();
}

姑息な手ですが、以下のようにキーボード操作で呼べるようにしておくと楽です。
ただカメラのコントロールを止めているので、顔認識のアップデートは止まりますし、小窓表示は映像が表示されません。

public GameObject quad = null; // Quadオブジェクトを設定
private HoloLensAnonymousFaceExample anonymousFace = null;
// 初期化
void Start()
{
    anonymousFace = quad.GetComponent<HoloLensAnonymousFaceExample>();
}
void Update()
{
    // Xキーを入力したらStop
    if (Input.GetKey(KeyCode.X))
    {
        anonymousFace.OnStopButton();
    }
}