NyARToolkit for UnityでNFTを利用したマーカーの認識
画像の準備
NyARToolkitのパッケージに含まれるサンプルSimpleNftは NFT(Natural Feature Tracking)を利用したマーカー認識のサンプルです。 NFTとは自然特徴点を利用した物体認識のことで、この技術を利用することで、一般的な画像をマーカーとして扱うことができます (詳しくはThe Sixwish Projectを参照)。 ここでは、下記の下記の「犬の画像(001.png)」と 「うさぎの画像(002.png)」を マーカーとして利用することに挑戦します。 画像サイズは300x300ピクセル、画像フォーマットは透過背景のPNGです。 また、犬の画像を認識すると赤色の立方体、うさぎの画像を認識すると青色の立方体を表示させることにします。
SimpleNftフォルダをコピーし、フォルダに含まれるC#スクリプトをARPictureCamera、 シーンをARPictureSceneにファイル名を変更した状態を前提とします(詳細はNYARToolkit for Unityの導入を参照)。
パターンファイルの作成
上記の2種類の画像から、マーカーのパターンファイルを作成します。 パターンファイルの作成には、NyARToolkitのパッケージに含まれるNftFileGeneratorを利用します (詳しくはNyARToolkit Projectを参照)。 [Data]-[Tools]にあるNftFileGeneratorをダブルクリックするとプログラムが起動します。 importをクリックし、特徴点を抽出したいJPGやPNGなどの画像を指定します(透過より背景白の方が認識精度が高いようです)。 次に、Make Feature Setをクリックし、特徴点を抽出します。 このとき、Source DPIやIset DPIsなどのパラメータは特に変更する必要はないようですが、 特徴点数が多すぎたり、少なすぎる場合にはFSET parameterを調節すると良いようです。
抽出されたパターンは赤い四角や青い円で表示されます。 パターンを保存するにはExportをクリックし、適当なファイル名で保存します。 ここでは、「犬の画像」のパターンファイルをpatt_001.bytes、 「うさぎの画像」のパターンファイルをpatt_002.bytesというファイル名で保存します。 これらのパターンファイルは、AssetsのResourcesフォルダにコピーしておきます。
マーカーオブジェクトの作成
SimpleNftはマーカーを認識すると赤色の立方体を表示します。 ここでは、2種類のマーカーに応じて、赤色の立方体に加え、青色の立方体を作成しておきます。
まずは、シーンのARPictureSceneをダブルクリックし、HierarchyにあるMarkerObjectを複製します。 スクリプトからこれのオブジェクトを操作するため、2つのマーカーオブジェクトには共通のタグ(Tag)を設定します (Gameobject.FindGameObjectsWithTag(String tag)メソッドでタグからオブジェクトを取得することが可能)。 タグ名は自由に設定することができますが、ここではMarkerObjectとしておきます。
次に、Assetsで赤色と青色のマテリアルを作成します。 [Create]-[Materials]をクリックしてマテリアルを作成し、Albedoに赤色と青色を設定します。 ここでは、マテリアルの名前をRedとBlueにしておきます。 これらのマテリアルはMarkerObjectの直下にあるCubeのMaterialsに設定しておきます。
マーカーが認識されたときに表示されるのは、上記のCubeオブジェクトです。 Cubeの**サイズ(Scale)や位置(Position)**はマーカーの大きさに合わせて調整する必要がありますが、 ここでは、サイズの値をX=80、Y=80、Z=80、位置をX=-80、Y=80、Z=40に修正しておきます。
スクリプトの修正
最後にC#スクリプトのARPictureCameraを修正します。
まずは、2つのマーカーオブジェクトを配列で取得します。 マーカーオブジェクトはMarkerObjectというタグが設定されていることを利用します。
private GameObject[] objects = new GameObject[2];
objects = GameObject.FindGameObjectsWithTag("MarkerObject");
同様に2つのパターンを基にマーカーIDを配列で取得します。 **Resources.Load()**メソッドは、Resourcesフォルダ内にあるファイルを探索し取得するメソッドです。
private int[] mids = new int[2]; //マーカーID
mids[0] = this._ns.addNftTarget(new MemoryStream(((TextAsset)Resources.Load("patt_001", typeof(TextAsset))).bytes), 160);
mids[1] = this._ns.addNftTarget(new MemoryStream(((TextAsset)Resources.Load("patt_002", typeof(TextAsset))).bytes), 160);
最後に、**update()**メソッドで、マーカーが認識された場合に、マーカーオブジェクトをアクティブに変更します。 逆に、マーカーが認識されなかった場合は、マーカーオブジェクトを非アクティブに変更します。 マーカーオブジェクトは、**setTransform()**メソッドで、マーカーが検出された位置に表示されます。
for (int i=0; i<mids.Length; i++) {
if (this._ns.isExist(mids[i])) {
if (objects[i].activeSelf == false){
objects[i].SetActive(true);
}
this._ns.setTransform(mids[i], objects[i].transform);
} else {
objects[i].SetActive(false);
}
}
全ソースコードを下記に示します。 コードの詳細は、付しているコメントを参考にしてください。
プログラムを実行して、「犬の画像」を認識すると青い立方体、「うさぎの画像」を認識すると赤い立方体が表示されることを確認してください。 これでイラストなど一般的な画像をマーカーとして利用することができるようになりました。