画像トラッキング
はじめに
このサンプルでは、現実世界の画像を検出し、その画像の位置と向きをトラッキングする方法を紹介します。
画像トラッキングの基本的な情報や、AR Foundation
のAR Tracked Image Manager
コンポーネントの機能については、Unityのドキュメントを参照してください。
機能の有効化
この機能を使用するには、以下のOpenXRのプロジェクト設定でImage Trackingにチェックする必要があります。
Project Settings > XR Plug-in Management > OpenXR (Androidタブ)
サンプルのインポート
まだサンプルをインポートしていない場合は、以下の手順でインポート することができます。
サンプルシーンは以下の場所に存在します。
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
を有効にすることで、サイズを指定できます。
画像ターゲットに使用している画像のImport Settings
では、FormatをRGB 24 bitに設定する必要があります。別のFormatの場合、画像トラッキングは動作しません。
画像ターゲットは紙に印刷することをおすすめします。
スマートフォン等の画面に画像ターゲットを表示する場合、画面輝度が明るすぎてARグラスのカメラ側では白飛びして認識できない可能性があります。
TR Castのような画面共有や録画アプリを使用する場合、画像トラッキングのようなカメラ映像を必要とする機能は動作しない可能性があります。
ARSessionOrigin
のGameObjectにARTrackedImageManager
を追加すると、Snapdragon Spacesパッケージに含まれるImage Tracking Subsystem
が有効になります。このコンポーネントは以下の項目を設定できます。
Serialized Library
:上記で作成した RuntimeReferenceimageLibraryMax Number Of Moving Images
:トラッキングする最大の画像枚数Tracked Image Prefab
:トラッキングされた画像の検出時にスポーンするプレハブを指定します。例として、プレハブにはトラッキングされた画像の向きを示すギズモの3Dモデルが指定されています。
トラッキング画像の変更を検知するために、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に追加することもできます。このコンポーネントでは、トラッキング画像の追加設定を行えます。
トラッキングモード
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>
を指定します。
ライブラリを交換する際、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;
}