https://gyazo.com/399be0179fc2bc72d21c82d597d18d35

画像の準備

NyARToolkitのパッケージに含まれるサンプルSimpleNftNFT(Natural Feature Tracking)を利用したマーカー認識のサンプルです。 NFTとは自然特徴点を利用した物体認識のことで、この技術を利用することで、一般的な画像をマーカーとして扱うことができます (詳しくはThe Sixwish Projectを参照)。 ここでは、下記の下記の「犬の画像(001.png)」と 「うさぎの画像(002.png)」を マーカーとして利用することに挑戦します。 画像サイズは300x300ピクセル、画像フォーマットは透過背景のPNGです。 また、犬の画像を認識すると赤色の立方体、うさぎの画像を認識すると青色の立方体を表示させることにします。

https://gyazo.com/ea8d174fc70bc754fa32fb9b5391b6d8

https://gyazo.com/5ad97af3ed708c91251ef897ca34d73a

SimpleNftフォルダをコピーし、フォルダに含まれるC#スクリプトをARPictureCamera、 シーンをARPictureSceneにファイル名を変更した状態を前提とします(詳細はNYARToolkit for Unityの導入を参照)。

パターンファイルの作成

上記の2種類の画像から、マーカーのパターンファイルを作成します。 パターンファイルの作成には、NyARToolkitのパッケージに含まれるNftFileGeneratorを利用します (詳しくはNyARToolkit Projectを参照)。 [Data]-[Tools]にあるNftFileGeneratorをダブルクリックするとプログラムが起動します。 importをクリックし、特徴点を抽出したいJPGやPNGなどの画像を指定します(透過より背景白の方が認識精度が高いようです)。 次に、Make Feature Setをクリックし、特徴点を抽出します。 このとき、Source DPIIset DPIsなどのパラメータは特に変更する必要はないようですが、 特徴点数が多すぎたり、少なすぎる場合にはFSET parameterを調節すると良いようです。

https://gyazo.com/5888670b05712f1852cabbce0a0576a9

抽出されたパターンは赤い四角青い円で表示されます。 パターンを保存するにはExportをクリックし、適当なファイル名で保存します。 ここでは、「犬の画像」のパターンファイルをpatt_001.bytes、 「うさぎの画像」のパターンファイルをpatt_002.bytesというファイル名で保存します。 これらのパターンファイルは、AssetsResourcesフォルダにコピーしておきます。

https://gyazo.com/5c7da4b00d6c7139796c4c21b2f84c53

https://gyazo.com/c306e5bf17af2bceb25bc0967b23cfa5

マーカーオブジェクトの作成

SimpleNftはマーカーを認識すると赤色の立方体を表示します。 ここでは、2種類のマーカーに応じて、赤色の立方体に加え、青色の立方体を作成しておきます。

まずは、シーンのARPictureSceneをダブルクリックし、HierarchyにあるMarkerObjectを複製します。 スクリプトからこれのオブジェクトを操作するため、2つのマーカーオブジェクトには共通のタグ(Tag)を設定します (Gameobject.FindGameObjectsWithTag(String tag)メソッドでタグからオブジェクトを取得することが可能)。 タグ名は自由に設定することができますが、ここではMarkerObjectとしておきます。

https://gyazo.com/2e6532cca4d4e4d1d30c3a6355246732

次に、Assetsで赤色と青色のマテリアルを作成します。 [Create]-[Materials]をクリックしてマテリアルを作成し、Albedoに赤色と青色を設定します。 ここでは、マテリアルの名前をRedBlueにしておきます。 これらのマテリアルはMarkerObjectの直下にあるCubeMaterialsに設定しておきます。

https://gyazo.com/5c51275d39fcb86e09f1d073fb320011

マーカーが認識されたときに表示されるのは、上記のCubeオブジェクトです。 Cubeサイズ(Scale)位置(Position)はマーカーの大きさに合わせて調整する必要がありますが、 ここでは、サイズの値をX=80、Y=80、Z=80、位置をX=-80、Y=80、Z=40に修正しておきます。

https://gyazo.com/5d1a3c61b18ceb85e4cf06bd3b504851

スクリプトの修正

最後に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);
    }
}

全ソースコードを下記に示します。 コードの詳細は、付しているコメントを参考にしてください。

プログラムを実行して、「犬の画像」を認識すると青い立方体、「うさぎの画像」を認識すると赤い立方体が表示されることを確認してください。 これでイラストなど一般的な画像をマーカーとして利用することができるようになりました。

https://gyazo.com/1a4c1907e1278c7a03536496f7076574

https://gyazo.com/2d0bef457c6ce380589daeb6a8f5808a

参考書籍