一覧に戻る

Android ネイティブAPIの物体のトラッキング

2017.07.01AndroidネイティブAPI

概要

Wikitude SDKでは、AR体験として任意のオブジェクトを認識してトラッキングする機能が提供されています。

この機能は、インスタントトラッキングにも使用されるWikitudeのSLAMエンジンに基づいています。
物体のトラッキング機能では、事前に定義された物体を認識できます。
  • おもちゃ
  • 記念碑と像
  • 産業用の機器
  • 用具
  • 家庭用品など

物体個々の特徴に影響される点はありますが、形状が変化しない性質のパーツで構成されているような物体は、本機能で認識できます。

Object Trackingサンプル

Object Trackingサンプルでは、Wikitude SDK ネイティブ APIで提供される物体のトラッキングがどのように機能するかを大まかに理解することができます。
おもちゃの消防車をトラッキングし、ARオブジェクトとしてストロークキューブとオクルーダキューブを追加して、その使用方法を説明しています。
 
物体のトラッキングは、トラッキングしたい任意の物体を撮影したビデオから抽出された3Dマップデータを使用して実現します。
画像認識型ARではWikitude Target Collection(.wtc)を認識に使用しますが、物体のトラッキングではWikitude Object Target Collection(.wto)を使用します。
 
開発中のアプリで物体のトラッキング機能を使用するには、アクティビティにObjectTrackerListenerインターフェイスを実装する必要があります。
サンプルでは、ARオブジェクトとしてGLRendererクラスを使用して作成したObjectTrackerとStrokedCubeおよびOccluderCubeを表示しています。
public class ObjectTrackingActivity extends Activity implements ObjectTrackerListener, ExternalRendering
Wikitude SDKのインスタンスを生成し初期化した後、リソースとしてfiretruck_map.wtoファイルを設定したTargetCollectionResourceのインスタンスを生成します。
それをTrackerManagerのcreateObjectTrackerメソッドに渡してObjectTrackerを作成し、アクティビティをリスナーとして設定します。
mTargetCollectionResource = mWikitudeSDK.getTrackerManager().createTargetCollectionResource("file:///android_asset/firetruck_map.wto", new TargetCollectionResourceLoadingCallback() {
    @Override
    public void onError(int errorCode, String errorMessage) {
        Log.v(TAG, "Failed to load target collection resource. Reason: " + errorMessage);
    }

    @Override
    public void onFinish() {
        mWikitudeSDK.getTrackerManager().createObjectTracker(mTargetCollectionResource, ObjectTrackingActivity.this, null);
    }
});

onObjectRecognizedメソッドでは、SrokedCubeインスタンスとOccluderCubeインスタンスを生成し、認識されたターゲットの名前でレンダラーに登録します。

@Override
public void onObjectRecognized(ObjectTracker tracker, final ObjectTarget target) {
    [...]

    StrokedCube strokedCube = new StrokedCube();
    OccluderCube occluderCube = new OccluderCube();

    mGLRenderer.setRenderablesForKey(target.getName(), strokedCube, occluderCube);
}

これに対応して、ターゲットをロストしたときにはStrokedCubeとOccluderCubeのインスタンス登録を解除します。

@Override
public void onObjectLost(ObjectTracker tracker, final ObjectTarget target) {
    [...]

    mGLRenderer.removeRenderablesForKey(target.getName());
}
StrokedCubeとOccluderCubeはonObjectTrackedメソッド内で更新されます。これらのインスタンスは、指定されたターゲット名を使用してレンダラーから取得されます。
ObjectTargetパラメーターに格納された情報を使用して描画が更新されます。Y軸上の0.5オフセットは、この特定のマップの中心ではなく、オブジェクトの底部にある原点を基点とします。
@Override
public void onObjectTracked(ObjectTracker tracker, final ObjectTarget target) {
    StrokedCube strokedCube = (StrokedCube)mGLRenderer.getRenderableForKey(target.getName());
    if (strokedCube != null) {
        strokedCube.projectionMatrix = target.getProjectionMatrix();
        strokedCube.viewMatrix = target.getViewMatrix();

        strokedCube.setYTranslate(0.5f);

        strokedCube.setXScale(target.getTargetScale().getX());
        strokedCube.setYScale(target.getTargetScale().getY());
        strokedCube.setZScale(target.getTargetScale().getZ());
    }

    OccluderCube occluderCube = (OccluderCube)mGLRenderer.getOccluderForKey(target.getName());
    if (occluderCube != null) {
        occluderCube.projectionMatrix = target.getProjectionMatrix();
        occluderCube.viewMatrix = target.getViewMatrix();

        occluderCube.setYTranslate(0.5f);

        occluderCube.setXScale(target.getTargetScale().getX());
        occluderCube.setYScale(target.getTargetScale().getY());
        occluderCube.setZScale(target.getTargetScale().getZ());
    }
}

onTargetsLoadedとonErrorLoadingTargetsを実装して、ロードプロセスに関して、任意の処理を実装できます。サンプルでは単純にログを出力しています。

@Override
public void onTargetsLoaded(ObjectTracker tracker) {
    Log.v(TAG, "Object tracker loaded");
}

@Override
public void onErrorLoadingTargets(ObjectTracker tracker, int errorCode, final String errorMessage) {
    Log.v(TAG, "Unable to load image tracker. Reason: " + errorMessage);
}
カメラに消防車を映すと、消防車の周りにオレンジの立方体が表示されます。
OccluderCubeは常に立方体と同じ位置に重なっているので、OccluderCubeに遮られて、StrokedCubeのカメラから遠い側の縁を見ることはできません。