メインコンテンツまでスキップ
バージョン: 0.23.2

画像トラッキング

はじめに

このサンプルでは、現実世界の画像を検出し、その画像の位置と向きをトラッキングする方法を紹介します。

画像トラッキングの基本的な情報や、AR FoundationAR Tracked Image Managerコンポーネントの機能については、Unityのドキュメントを参照してください。

機能の有効化

この機能を使用するには、以下のOpenXRのプロジェクト設定でImage Trackingにチェックする必要があります。
Project Settings > XR Plug-in Management > OpenXR (Androidタブ) alt text

サンプルのインポート

まだサンプルをインポートしていない場合は、以下の手順でインポートすることができます。

  1. 基本パッケージのインポート
  2. 基本サンプルのインポート

サンプルシーンは以下の場所に存在します。
Assets/Samples/Snapdragon Spaces/0.XX.0/Core Samples/Scenes/Image Tracking Sample/Image Tracking Sample.unity

使用方法

画像ターゲットは、XR Reference Image Libraryを通して、基盤となる XRプラグインに供給されます。

Reference Image Libraryでは以下の設定項目があります。

  • Name:トラッキングする画像を識別するための名前
  • Specify Size:画像のサイズ
  • Keep Texture at Runtime:実行時にテクスチャを保持する(Trueに設定する必要がある)

これにより、画像トラッキングのための画像データをSnapdragon Spaces Servicesに渡すことができます。

サンプルでは画像ターゲットの高さは26cmです。正確なトラッキングを行うには正しいサイズを指定する必要があります。Specify Sizeを有効にすることで、サイズを指定できます。 alt text

WARNING

画像ターゲットに使用している画像のImport Settingsでは、FormatをRGB 24 bitに設定する必要があります。別のFormatの場合、画像トラッキングは動作しません。 alt text

TIP

画像ターゲットは紙に印刷することをおすすめします。
スマートフォン等の画面に画像ターゲットを表示する場合、画面輝度が明るすぎてARグラスのカメラ側では白飛びして認識できない可能性があります。

TIP

TR Castのような画面共有や録画アプリを使用する場合、画像トラッキングのようなカメラ映像を必要とする機能は動作しない可能性があります。

ARSessionOriginのGameObjectにARTrackedImageManagerを追加すると、Snapdragon Spacesパッケージに含まれるImage Tracking Subsystemが有効になります。このコンポーネントは以下の項目を設定できます。

  • Serialized Library:上記で作成した RuntimeReferenceimageLibrary
  • Max Number Of Moving Images:トラッキングする最大の画像枚数
  • Tracked Image Prefab:トラッキングされた画像の検出時にスポーンするプレハブを指定します。例として、プレハブにはトラッキングされた画像の向きを示すギズモの3Dモデルが指定されています。 alt text

トラッキング画像の変更を検知するために、ARTrackedImageManagerのメソッドをサブスクライブすることで、以下の簡略化したコード例にあるようにトラッキングの状態とトラッキング画像の位置に対して適切なUI情報が設定されます。

    ...

private Dictionary<TrackableId, ...> _trackedImages = new Dictionary<TrackableId, ...>();

public override void OnEnable() {
...
FindObjectOfType<ARTrackedImageManager>().trackedImagesChanged += OnTrackedImagesChanged;
}

public override void OnDisable() {
...
FindObjectOfType<ARTrackedImageManager>().trackedImagesChanged -= OnTrackedImagesChanged;
}

private void OnTrackedImagesChanged(ARTrackedImagesChangedEventArgs args) {
foreach (var trackedImage in args.added) {
if (trackedImage.referenceImage.name == "Spaces Town") {
_trackedImages.Add(trackedImage.trackableId, ...);
...
}
}

foreach (var trackedImage in args.updated) {
var info = _trackedImages[trackedImage.trackableId];
...
}

foreach (var trackedImage in args.removed) {
_trackedImages.Remove(trackedImage.trackableId);
...
}
}

オプションのSpaces Reference Image Configuratorコンポーネントは、ARTrackedImageManagerと同じGameObjectに追加することもできます。このコンポーネントでは、トラッキング画像の追加設定を行えます。 alt text

トラッキングモード

Tracking Modeでは、画像ごとにトラッキングモードを設定できます。

  • Dynamic (Default):Dynamicモードは、トラッキングされた画像の位置がフレームごとに更新され、移動中のターゲットと静止したターゲットの両方で機能します。トラッキングされた画像が見つからない場合、位置や姿勢は報告されません。このモードでは、他のトラッキングモードに比べて消費電力が高くなります。Spaces Reference Image Configuratorコンポーネントが見つからない場合、全てのトラッキング画像はデフォルトでこのトラッキングモードを使用します。
  • Static:Staticモードは、静止した画像をトラッキングするのに役立ち、消費電力の削減とパフォーマンスの向上につながります。たとえば、床や壁に貼り付けられた画像がこれに該当します。このモードは、画像が見えなくなった後も、引き続き表示される必要があるARオブジェクトを表示し続けるのに便利です。Staticモードでトラッキングされた画像の位置は、画像が移動したか視界から外れたかに関係なく、更新されることはありません。
  • Adaptive:Adaptiveモードは静止した画像で動作しますが、トラッキングされた画像が動いた場合は、およそ5フレームごとに定期的に画像の位置を更新します。HMDが移動した場合、画像の位置はディスプレイのリフレッシュレートに合わせて更新されます。視界から外れた画像のトラッキングは最終的に失われます。このモードは、消費電力とトラッキング精度のバランスをとります。
トラッキングモードトラッキングの開始タイミング画像位置の更新間隔トラッキングの終了タイミング
Dynamic (default)画像がカメラ画角内に入った時全てのフレーム画像がカメラ画角外に出た時
Static画像がカメラ画角内に入った時更新無し新しい画像がトラッキングされた場合
Adaptive画像がカメラ画角内に入った時5フレームごと画像がカメラ画角外に出た時

アプリを起動すると、トラッキングされた画像は Spaces Reference Image Configuratorコンポーネントで定義されたトラッキングモードを使用します。

    public SpacesReferenceImageConfigurator referenceImageConfigurator;
private Dictionary<TrackableId, ...> _trackedImages = new Dictionary<TrackableId, ...>();
...

string referenceImageName = ...; // referenceImageName to change Tracking Mode for
TrackableId trackableId = ...; // a TrackableId for an existing tracked instance of this image
...

// first, stop tracking any instances of the tracked image for which the Tracking Mode should be updated.
// if tracking is not stopped, the instance can (but is not guaranteed to) continue to be tracked using the old Tracking Mode for some time
referenceImageConfigurator.StopTrackingImageInstance(referenceImageName, trackableId);
...

// then, set the desired tracking mode for all future instances of the tracked image with that referenceImageName
referenceImageConfigurator.SetTrackingModeForReferenceImage(referenceImageName, SpacesImageTrackingMode.DYNAMIC);
referenceImageConfigurator.SetTrackingModeForReferenceImage(referenceImageName, SpacesImageTrackingMode.STATIC);
referenceImageConfigurator.SetTrackingModeForReferenceImage(referenceImageName, SpacesImageTrackingMode.ADAPTIVE);

実行時にトラッキング画像を変更する

シーンを切り替えることなく、AR Tracked Image Managerが使用する参照画像ライブラリ(トラッキングする画像)を実行時に変更することが可能です。そのためには、以下の点について考慮する必要があります。

  • ライブラリの変更を有効にするには、Image Tracking subsystemを再起動する必要があります。これは、AR Tracked Image Managerコンポーネントを再び有効にすることで実現できます。
  • コンポーネントのSyncTrackingModes関数を使用して、新しいライブラリ用にSpaces Reference Image Configuratorでトラッキングモードを再同期する必要があります。引数として、参照画像名と最初のトラッキングモードのDictionary<string, SpacesImageTrackingMode>を指定します。
WARNING

ライブラリを交換する際、Spaces Reference Image Configuratorでトラッキングモードの再適用を行わなず、前のライブラリに参照イメージ名が見つからない場合、SetTrackingModeForReferenceImage関数が失敗します。
このような場合、Dynamicモードが参照画像のデフォルトのトラッキングモードになります。

以下のサンプルコードでは、実行時に異なる参照画像ライブラリにスワップする関数 SwapTargetLibraryを実装しています。まず、Tracked Image Managerコンポーネントを無効にし、Spaces Reference Image ConfiguratorコンポーネントのSyncTrackingModes関数でトラッキングモードを再同期します。参照画像名と最初のトラッキングモードのDictionary<string, SpacesImageTrackingMode>は、補助関数CreateTrackingModesDictionaryによって提供されます。最後に、新しい参照ライブラリがAR Tracked Image Managerコンポーネントに適用され、後者が再度有効になります。

public ARTrackedImageManager TrackedImageManager;
public SpacesReferenceImageConfigurator ReferenceImageConfigurator;

void SwapTargetLibrary(XRReferenceImageLibrary library)
{
TrackedImageManager.enabled = false;
ReferenceImageConfigurator.SyncTrackingModes(CreateTrackingModesDictionary(library));
TrackedImageManager.referenceLibrary = library;
TrackedImageManager.enabled = true;
}

Dictionary<string, SpacesImageTrackingMode> CreateTrackingModesDictionary(XRReferenceImageLibrary library)
{
Dictionary<string, SpacesImageTrackingMode> trackingModes = new Dictionary<string, SpacesImageTrackingMode>();
foreach (var referenceImage in library)
{
trackingModes[referenceImage.name] = SpacesImageTrackingMode.DYNAMIC;
}

return trackingModes;
}