一覧に戻る

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

2018.07.08AndroidネイティブAPI

物体とシーンの認識の紹介

以下のセクションでは、Wikitude JavaScript SDKの物体のトラッキング機能について紹介し、拡張現実体験のために任意の物体を認識してトラッキングする方法を示します。この機能は、あらゆる種類の環境をトラッキングするためにSDK全体で使用されるWikitudeのSLAMエンジンに基づいた機能です。 物体の認識とトラッキングにより、あらかじめ定義された物体やシーン全体を検出できます。認識に適した物体には以下のものが含まれます。

  • おもちゃ
  • 記念碑と像
  • 産業用の機器
  • 用具
  • 家庭用品など

認識機能は、変化や動的な部分の数が限られている物体に最適です。

シーンの認識

SDK 8では、物体認識エンジンを使用して、テーブルくらいのサイズを超える大きな構造を認識することができます。シーン認識という名前は特にこれを反映しています。新しい画像ベースの変換方法では、サイズが大きなターゲットオブジェクトを使用でき、認識とトラッキングができます。

  • 部屋
  • 建物
  • 広場や中庭

単純な物体のトラッキング

単純な物体のトラッキングでは、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 Native SDKのインスタンスを生成し初期化した後、リソースとしてfiretruck.wtoファイルを設定したTargetCollectionResourceのインスタンスを生成します。 それをTrackerManagerのcreateObjectTrackerメソッドに渡してObjectTrackerを作成し、アクティビティをリスナーとして設定します。

final TargetCollectionResource targetCollectionResource = wikitudeSDK.getTrackerManager().createTargetCollectionResource("file:///android_asset/firetruck.wto");
wikitudeSDK.getTrackerManager().createObjectTracker(targetCollectionResource, ObjectTrackingActivity.this, null);

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

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

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

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

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

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

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

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

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

        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, WikitudeError error) {
    Log.v(TAG, "Unable to load image tracker. Reason: " + error.getMessage());
}
カメラに消防車を映すと、消防車の周りにオレンジの立方体が表示されます。
OccluderCubeは常に立方体と同じ位置に重なっているので、OccluderCubeに遮られて、StrokedCubeのカメラから遠い側の縁を見ることはできません。

拡張オブジェクトトラッキング

拡張トラッキングは、ターゲットごとに個別に設定できるオプションのモードです。 このモードでは、ターゲットオブジェクトが既に表示されていない状態でも、Wikitude SDKはその環境に対してスキャンを継続します。したがって、トラッキングは元のターゲットオブジェクトの境界を超えて拡張されます。この機能のパフォーマンスは、デバイスのコンピューティングパワー、背景テクスチャ、およびオブジェクトなどのさまざまな要因によって決定されます。
前のサンプルに基づいて、トラッカーの拡張トラッキングを有効にするには、どのターゲットを拡張する必要があるかを定義する文字列配列を指定する必要があります。このサンプルでは、このトラッカー内のすべてのターゲットが拡張されるようにワイルドカード*を設定しています。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    final TargetCollectionResource targetCollectionResource = wikitudeSDK.getTrackerManager().createTargetCollectionResource("file:///android_asset/firetruck.wto");
    ObjectTrackerConfiguration trackerConfiguration = new ObjectTrackerConfiguration();
    trackerConfiguration.setExtendedTargets(new String[]{"*"});
    objectTracker = wikitudeSDK.getTrackerManager().createObjectTracker(targetCollectionResource, ExtendedObjectTrackingActivity.this, trackerConfiguration);
}

ObjectTrackerListenerには、拡張トラッキングの品質を更新するonExtendedTrackingQualityChangedメソッドが含まれています。このサンプルでは、品質のインジケータを表示するための使用方法を示します。

@Override
public void onExtendedTrackingQualityChanged(final ObjectTracker tracker, final ObjectTarget target, final int oldTrackingQuality, final int newTrackingQuality) {
    EditText trackingQualityIndicator = findViewById(R.id.tracking_quality_indicator);
    switch (newTrackingQuality) {
        case -1:
            trackingQualityIndicator.setBackgroundColor(Color.parseColor("#FF3420"));
            trackingQualityIndicator.setText(R.string.tracking_quality_indicator_bad);
            break;
        case 0:
            trackingQualityIndicator.setBackgroundColor(Color.parseColor("#FFD900"));
            trackingQualityIndicator.setText(R.string.tracking_quality_indicator_average);
            break;
        default:
            trackingQualityIndicator.setBackgroundColor(Color.parseColor("#6BFF00"));
            trackingQualityIndicator.setText(R.string.tracking_quality_indicator_good);
    }
    trackingQualityIndicator.setVisibility(View.VISIBLE);
}

拡張トラッキングを停止するにはObjectTracker.stopExtendedTracking()を使用できます。

@Override
public void onRenderExtensionCreated(final RenderExtension renderExtension) {

    ...

    stopExtendedTrackingButton = findViewById(R.id.stop_extended_tracking_button);
    stopExtendedTrackingButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            objectTracker.stopExtendedTracking();
        }
    });
}