AR Tracked Image Manager コンポーネント
Tracked Image Manager は トラッカブルマネージャー の一種で、2D 画像トラッキングを実行します。
AR Tracked Image Manager コンポーネント
Tracked Image Manager は、環境内で検出された各画像の ゲームオブジェクト を作成します。画像を検出できるようにするためには、マネージャーに対して、参照画像ライブラリにコンパイルされた参照画像のセットを検索するよう指示する必要があります。マネージャーは、このライブラリの画像のみを検出します。
用語集
用語 | 説明 |
---|---|
Reference image (参照画像) | 参照画像は、XRImageTrackingSubsystem による検索対象となる実世界の画像です。サブシステムは、検出した画像と、検出に使用した参照画像を関連付けます。検出された各画像はワールド内でポーズを持ちます。 |
Reference image library (参照画像ライブラリ) | 参照画像のセット。画像トラッキングサブシステムを開始する際は、まず検索対象を認識させるため、参照画像ライブラリを提供する必要があります。 |
参照画像ライブラリの作成
参照画像ライブラリは Unity エディターで作成します。Unity のメインメニューから、Assets > Create > XR > Reference Image Library に移動します。
これにより、プロジェクト内に新しい参照画像ライブラリアセットが作成されます。画像を追加するには、このアセットを選択してから、Add Image をクリックし、表示されたフィールドに情報を入力します。
以下の情報を指定できます。
フィールド | 説明 |
---|---|
Name | ランタイムで使用できる文字列名。この名前は、サブシステムが使用することはありませんが、検出された参照画像を特定する際に便利です。名前の重複による競合はチェックされません。 |
Specify Size | 有効にすると、実世界での画像の物理的なサイズを指定できます。このフィールドが必須かどうかは、プロバイダーによって異なります。詳細はプロバイダーのドキュメントを参照してください。このフィールドを指定する場合、寸法は 0 より大きくする必要があります。1 つの寸法 (幅など) を変更すると、画像のアスペクト比に応じて他方の寸法 (高さ) も自動的に変更されます。 |
Keep Texture at Runtime | 有効にすると、XRReferenceImage.texture にソーステクスチャへの参照が含まれます。ランタイムにソーステクスチャにアクセスする必要がある場合に便利です。デフォルトでは、構築されるプレイヤーのサイズを低減するために、オフになっています。オフの場合、XRReferenceImage.texture は null です。 |
Tip
XRReferenceImageLibrary
をアセットバンドルに加えると、その参照画像ライブラリを使用して構築されていないアプリケーションでも使用できるようになります。
参照画像ライブラリ
参照画像ライブラリはランタイムに設定できますが、Tracked Image Manager コンポーネントが有効になっている場合は、参照画像ライブラリを null 以外にする必要があります。以下のようなスクリプトを使用して設定できます。
ARTrackedImageManager manager = ...;
manager.referenceLibrary = myReferenceImageLibrary;
参照画像ライブラリは XRReferenceImageLibrary または RuntimeReferenceImageLibrary に設定できます。エディターでは XRReferenceImageLibrary
のみ作成できますが、ランタイムに修正することはできません。RuntimeReferenceImageLibrary
は、XRReferenceImageLibrary
のランタイム表現です。ライブラリを XRReferenceImageLibrary
に設定した場合は、画像トラッキングサブシステムによって、自動的に RuntimeReferenceImageLibrary
に変換されて使用されます。
実際の画像ライブラリのデータはプロバイダーごとに異なります。詳しくはプロバイダーのドキュメントを参照してください。
ARTrackedImageManager.CreateRuntimeLibrary
メソッドを使用して、XRReferenceImageLibrary
から RuntimeReferenceImageLibrary
を作成できます。
XRReferenceImageLibrary serializedLibrary = ...
RuntimeReferenceImageLibrary runtimeLibrary = trackedImageManager.CreateRuntimeLibrary(serializedLibrary);
Note
RuntimeReferenceImageLibrary
での XRReferenceImage の順序は定義されていないため、ソースの XRReferenceImageLibrary
での画像の表示順と異なる場合があります。各参照画像にはお客様が割り当てた文字列名と、ランダムに割り当てられる Guid が含まれます。Guid
は、ソースの XRReferenceImageLibrary
とそれに対応する RuntimeReferenceImageLibrary
で同一です。
アセットバンドルを含む参照画像ライブラリの使用
AR Foundation 4.2 より前のバージョンでは、参照画像ライブラリはプレイヤーに組み込む必要があったため、XRReferenceImageLibrary
は、アプリケーションにパッケージされる見込みのデータをルックアップする手段として使用されるだけでした。そのため、例えばリリース済みのアプリケーションに新しい参照画像ライブラリをダウンロードすることはできませんでした。AR Foundation 4.2 から、プレイヤーまたは アセットバンドル を構築する際に、プラットフォーム固有のデータが XRReferenceImageLibrary
アセットにアタッチされます。そのため、アセットバンドルに XRReferenceImageLibrary
を加えると、その参照画像ライブラリを使用して構築されていないアプリケーションでも使用できるようになります。
検出された画像への対応
ARTrackedImageManager の trackedImagesChanged イベントにサブスクライブし、画像の追加時 (最初の検出時)、更新時、削除時に通知が届くようにします。
[SerializeField]
ARTrackedImageManager m_TrackedImageManager;
void OnEnable() => m_TrackedImageManager.trackedImagesChanged += OnChanged;
void OnDisable() => m_TrackedImageManager.trackedImagesChanged -= OnChanged;
void OnChanged(ARTrackedImagesChangedEventArgs eventArgs)
{
foreach (var newImage in eventArgs.added)
{
// Handle added event
}
foreach (var updatedImage in eventArgs.updated)
{
// Handle updated event
}
foreach (var removedImage in eventArgs.removed)
{
// Handle removed event
}
}
画像には、追跡の質に関する追加情報となる トラッキングステート も含まれます。例えば、視界から外れた画像は、"削除" されない場合がありますが、そのトラッキングステートは変わる可能性があります。
ARTrackedImageManager の trackables プロパティを使用して、追跡されている画像をすべて取得することもできます。IEnumerable コレクションと同様に動作するため、foreach
ステートメントで使用できます。
void ListAllImages()
{
Debug.Log(
$"There are {m_TrackedImageManager.trackables.count} images being tracked.");
foreach (var trackedImage in m_TrackedImageManager.trackables)
{
Debug.Log($"Image: {trackedImage.referenceImage.name} is at " +
$"{trackedImage.transform.position}");
}
}
または、TrackableId を使用して画像にアクセスできます。
ARTrackedImage GetImageAt(TrackableId trackableId)
{
return m_TrackedImageManager.trackables[trackableId];
}
Tracked Image Prefab
ARTrackedImageManager には、"Tracked Image Prefab" フィールドがありますが、これはコンテンツのためのフィールドではありません。画像が検出されると、AR Foundation はその画像を表す新しい ゲームオブジェクト を作成します。
"Tracked Image Prefab" が null
の場合、AR Foundation は ARTrackedImage コンポーネントを備えたゲームオブジェクトを作成します。ただし、すべての追跡画像に他のコンポーネントも追加する場合は、AR Foundation が検出された各画像用にインスタンス化するためのプレハブを提供できます。つまり、Prefab フィールドを使用する目的は、追跡画像のデフォルトの動作を拡張することですが、コンテンツをワールドに配置するための方法としてはお勧めしません。
検出画像のポーズでコンテンツを インスタンス化 し、そのポーズを自動更新する場合は、コンテンツを ARTrackedImage
の親にする必要があります。
ランタイムにおける新しい参照画像の追加
ランタイムに変更可能な画像ライブラリに対応しているサブシステムもあります。このケースでは、サブシステムによって、MutableRuntimeReferenceImageLibrary
となる RuntimeReferenceImageLibrary
が作成されます。これを使用するには、RuntimeReferenceImageLibrary
を MutableRuntimeReferenceImageLibrary
にキャストする必要があります。
[SerializeField]
ARTrackedImageManager m_TrackedImageManager;
void AddImage(Texture2D imageToAdd)
{
if (m_TrackedImageManager.referenceLibrary is MutableRuntimeReferenceImageLibrary mutableLibrary)
{
mutableLibrary.ScheduleAddImageWithValidationJob(
imageToAdd,
"my new image",
0.5f /* 50 cm */);
}
}
後で画像を追加できる空のライブラリを作成する場合は、引数なしで CreateRuntimeLibrary
を呼び出します。
void AddImage(Texture2D imageToAdd)
{
var library = m_TrackedImageManager.CreateRuntimeLibrary();
if (library is MutableRuntimeReferenceImageLibrary mutableLibrary)
{
mutableLibrary.ScheduleAddImageWithValidationJob(
imageToAdd,
"my new image",
0.5f /* 50 cm */);
}
}
特定の Tracked Image Manager が可変ライブラリに対応しているかどうかは、記述子からチェックできます。
bool DoesSupportMutableImageLibraries()
{
return m_TrackedImageManager.descriptor.supportsMutableLibrary;
}
可変ライブラリに画像を追加でき、いつでも画像は使用可能です。画像を追加すると、演算のリソース負荷が大きくなり、完了までに数フレームかかる場合があります。Unity Job System を使用すると、非同期的に画像が処理されます。
画像を MutableRuntimeReferenceImageLibrary に追加するには、ScheduleAddImageJob メソッドを使用します。これにより、ジョブの完了時間を特定できる JobHandle が返されます。不要であれば、このハンドルは安全に破棄できます。
Texture2D を受け入れる 拡張メソッド を使用する場合は、メモリを管理する必要はありません。
NativeSlice またはポインターを受け入れる ScheduleAddImageJob のバージョンを使用する場合は、メモリを管理する、つまりジョブの完了時にメモリを解放する必要があります。これは、メモリを解放する依存ジョブのスケジュール設定を行うことで可能です。
struct DeallocateJob : IJob
{
[DeallocateOnJobCompletion]
public NativeArray<byte> data;
public void Execute() { }
}
void AddImage(NativeArray<byte> grayscaleImageBytes,
int widthInPixels, int heightInPixels,
float widthInMeters)
{
if (m_TrackedImageManager.referenceLibrary is MutableRuntimeReferenceImageLibrary mutableLibrary)
{
var aspectRatio = (float)widthInPixels / (float)heightInPixels;
var sizeInMeters = new Vector2(widthInMeters, widthInMeters * aspectRatio);
var referenceImage = new XRReferenceImage(
// Guid is assigned after image is added
SerializableGuid.empty,
// No texture associated with this reference image
SerializableGuid.empty,
sizeInMeters, "My Image", null);
var jobState = mutableLibrary.ScheduleAddImageWithValidationJob(
grayscaleImageBytes,
new Vector2Int(widthInPixels, heightInPixels),
TextureFormat.R8,
referenceImage);
// Schedule a job that deallocates the image bytes after the image
// is added to the reference image library.
new DeallocateJob { data = grayscaleImageBytes }.Schedule(jobState.jobHandle);
}
else
{
// Cannot add the image, so dispose its memory.
grayscaleImageBytes.Dispose();
}
}
複数の画像追加ジョブを同時並行で処理できます。画像トラッキングで MutableRuntimeReferenceImageLibrary
が使用されているかどうかは影響しません。
参照画像とテクスチャのインポート設定
画像検出アルゴリズムは、参照画像のアスペクト比の正確な知識に依存しますが、Unity のデフォルトのテクスチャのインポート設定は、テクスチャの解像度が最近接の 2 の累乗 (PoT) に調整されます。この設定では、2 の累乗ではない (NPoT) 画像を追跡する際に、追跡機能に悪影響が生じることがあります。
NPoT 画像がデフォルト設定でインポートされ、ランタイムに MutableRuntimeReferenceImageLibrary
に追加されると、押しつぶしや引き伸ばし、スケーリングアーティファクトが生じる場合があります。
インポート時に画像のアスペクト比を維持するためには、プロジェクトアセットの画像を選択し、テクスチャのインポート設定の Non-Power of 2 を None に変更します。
Note
アスペクト比が 2 の累乗のテクスチャの場合は、調整が不要なため、Non-Power of 2 設定は選択できません。
ランタイムにおけるマネージャーの作成
Unity では、ランタイムにコンポーネントをアクティブな GameObject
に追加すると、OnEnable
メソッドが即座に呼び出されます。ただし、ARTrackedImageManager
には、null 以外の参照画像ライブラリが必要です。参照画像ライブラリが null の場合は、ARTrackedImageManager
を有効にしても自動的に無効になります。
ランタイムに ARTrackedImageManager
を追加するには、参照画像ライブラリを設定してから再度有効にします。
var manager = gameObject.AddComponent<ARTrackedImageManager>();
manager.referenceLibrary = myLibrary;
manager.enabled = true;
動く画像の最大数
一部のプロバイダーは動く画像を追跡できます。通常、その場合は CPU の負荷が大きくなるため、同時に追跡する動く画像の数を指定できます。この機能に対応しているかどうかは、SubsystemDescriptor
(ARTrackedImageManager.descriptor
) をチェックすることで確認できます。
Tracked Image Prefab
このプレハブは、参照画像ライブラリの画像が検出されるたびにインスタンス化されます。マネージャーによって、インスタンス化された GameObject
に ARTrackedImage
コンポーネントが確実に含まれます。ARTrackedImage.referenceImage
プロパティを使用して、ARTrackedImage
の検出に使用された参照画像を取得できます。
トラッキングステート
ARTrackedImages
には以下の 3 つのトラッキングステートがあります。
トラッキングステート | 説明 |
---|---|
None | 画像が追跡されていません。画像が最初に検出されたときの初期状態がこれになる場合があります。 |
Limited | 画像は追跡されていますが、効果的には追跡されていません。画像が Tracking ではなく Limited と判定される状況は、基盤となる AR (拡張現実) フレームワークによって異なります。例えば、次のようなケースでトラッキングステートが Limited と判定されます。
|
Tracking | 基盤となる AR SDK で、画像の追跡が有効であることが確認されています。 |
画像が視認可能かどうかの判定
画像の可視性を判定する API はありません。一般的には、トラッキングステートが Tracking の場合に、画像が視認不可能になると Limited
に移行する傾向があります。ただし、それ以外の状況でも、トラッキングステートが Tracked
以外になることがあります。
アプリケーションで、可視性に関する情報の重要性が高い場合は、ARTrackedImage
のトランスフォームとカメラの視錐台を比較することをお勧めします。