Table of Contents

外部フレームデータソースの入力フレームデータ要件

外部フレームデータソースを正常に動作させるためには、データの正確性を保証することが最も重要であり、同時に最も困難な作業です。この文書では外部フレームデータソースの入力フレームデータ要件について説明します。

開始する前に

入力フレームデータの種類

Unityでは、外部フレームデータソースは通常、異なる2つのタイミングで異なるデータを受信する必要があります。外部データ入力のタイミングとデータ特性に基づき、これら2つのデータセットを以下のように呼びます:

  1. カメラフレームデータ(camera frame data)
  2. レンダリングフレームデータ(rendering frame data)

異なるタイプの外部フレームデータソースは、これらのデータセットに対して異なる要件を持ちます:

  • 画像とデバイスモーションデータ入力拡張:カメラフレームデータとレンダリングフレームデータの両方が必要
  • 画像入力拡張:カメラフレームデータのみが必要

カメラフレームデータ

データ要件:

  1. タイムスタンプ(timestamp)
  2. 生の物理カメラ画像データ(raw camera image data)
  3. 内部パラメータ(intrinsics、画像サイズ、焦点距離、主点を含む。歪みがある場合は歪みモデルと歪みパラメータも必要)
  4. 外部パラメータ(extrinsics、TcwまたはTwc、校正された行列、物理カメラのデバイス/ヘッドのpose原点に対する物理的オフセットを表す)
  5. トラッキング状態(tracking status)
  6. デバイスポーズ(device pose)

データタイミング:

  • 物理カメラの露出中点

データ使用:

  • API呼び出しタイミング:外部コードの設計に応じて変更可能。多くのデバイスで使用される一般的な方法は、3Dエンジンのレンダリング更新中にクエリを行い、デバイスデータのタイムスタンプに基づいてデータ処理を進めるかどうかを判断する
  • API呼び出しスレッド:3Dエンジンのgame thread、または使用するすべての外部APIがスレッドセーフである場合はその他のスレッド

UnityにおけるAPI呼び出しの例:

void TryInputCameraFrameData()
{
    double timestamp;

    if (timestamp == curTimestamp) { return; }
    curTimestamp = timestamp;

    PixelFormat format;
    Vector2Int size;
    Vector2Int pixelSize;
    int bufferSize;

    var bufferO = TryAcquireBuffer(bufferSize);
    if (bufferO.OnNone) { return; }
    var buffer = bufferO.Value;

    IntPtr imageData;
    buffer.tryCopyFrom(imageData, 0, 0, bufferSize);

    var historicalHeadPose = new Pose();
    MotionTrackingStatus trackingStatus = (MotionTrackingStatus)(-1);

    using (buffer)
    using (var image = Image.create(buffer, format, size.x, size.y, pixelSize.x, pixelSize.y))
    {
        HandleCameraFrameData(deviceCamera, timestamp, image, cameraParameters, historicalHeadPose, trackingStatus);
    }
}

Rendering frame data

データ要件:

  1. タイムスタンプ(timestamp)
  2. トラッキングステータス(tracking status)
  3. デバイスポーズ(device pose)

データタイミング:

  • ディスプレイ出力時点。TimeWarpは含まれない。同じ時刻のdevice poseデータは、現在のフレームをレンダリングするために仮想カメラのtransformを設定するために外部(デバイスSDKなど)によって使用される。
注記

TimeWarp(ReprojectionやATW/PTWとも呼ばれる)は、VR/ARヘッドセットでレイテンシを低減するためによく使用される技術です。レンダリング完了後、最新のヘッドポーズに基づいて画像を再変換し、レンダリング中のヘッド運動を補償します。EasyARが必要とするのは、レンダリング開始時に仮想カメラを設定するために使用されるポーズに対応する時点であり、TimeWarp後の実際のディスプレイ出力時点ではありません。

データ使用:

  • API呼び出しタイミング:3Dエンジンの各レンダリングフレーム
  • API呼び出しスレッド:3Dエンジンのgame thread

Unity での API 呼び出し例を以下に示します:

private void InputRenderFrameMotionData()
{
    double timestamp = 0e-9;
    var headPose = new Pose();
    MotionTrackingStatus trackingStatus = (MotionTrackingStatus)(-1);
    HandleRenderFrameData(timestamp, headPose, trackingStatus);
}

データ要件の詳細

物理カメラ画像データ:

  • 画像座標系:センサーが水平時に取得したデータも水平である必要がある。データは左上隅を原点として行優先で保存されること。画像が反転または逆さまになってはいけない。
  • 画像FPS:通常の30または60fpsのデータが可能。高fpsが特別な影響を与える場合、合理的なアルゴリズム効果を得るために最小許容フレームレートは2。2を超えるfpsの使用を推奨し、通常は元のデータフレームレートを使用する。
  • 画像サイズ:より良い計算結果を得るために、最大辺は960以上であることが望ましい。データパイプラインでの時間のかかる画像スケーリングは推奨されず、完全なサイズのデータコピー時間が受け入れられないほど長くなければ、生データを直接使用することが推奨される。画像解像度は640*480未満であってはならない。
  • ピクセルフォーマット:トラッキング性能を優先し総合的に考慮した場合、通常のフォーマット優先順位はYUV > RGB > RGBA > Gray(YUVのY成分)。YUVデータを使用する場合、データカプセル化とパディングの詳細を含む完全なデータ定義が必要。単一チャネル画像と比較して、カラー画像を使用するとMegaの効果が向上するが、他の機能への影響は小さい。
  • データアクセス:データポインタまたは同等の実装。データパイプラインからすべての不要なコピーを排除することが望ましい。HandleRenderFrameDataではEasyARがデータをコピーし、その後非同期で使用するため、この同期呼び出しが完了すると画像データは使用されなくなる。データ所有権に注意。

タイムスタンプ:

  • すべてのタイムスタンプはクロック同期されている必要があり、可能であればハードウェア同期が望ましい。データの単位は秒だが、ナノ秒レベルまたは可能な限り高い精度が求められる。

トラッキング状態:

  • トラッキング状態はデバイスによって定義され、トラッキングロスト(VIOが利用不可)の状態を含める必要がある。より多くのレベルがあればなお良い。

デバイスの姿勢:

  • すべてのpose(3Dエンジン内の仮想カメラのtransformを含む)は同じ原点を使用すべきである。
  • すべてのposeおよび外部パラメータは同じ座標軸システムを使用すべきである。
  • Unityでは、poseデータの座標軸システムタイプはUnity座標系またはEasyAR座標系であるべき。もし入力拡張がEasyARによって実装され、他の座標軸システム定義が使用されている場合、明確な座標軸システムの定義を提供するか、Unity座標系またはEasyAR座標系への変換方法を提示すべきである。
  • Unityでは、Unity XRフレームワークを使用する場合、XROrigin.TrackingOriginMode.Deviceモードとの互換性のみを確保すれば良い。

内部パラメータ:

  • すべての値は画像データと一致すべきである。必要に応じて、EasyARに入力する前に内部パラメータをスケーリングすべき。
  • もし入力拡張がEasyARによって実装される場合、内部パラメータがフレームごとに変化するかどうかを明記すべき(対応するAPIを一度呼び出すべきか、フレームごとに呼び出すべきかの違い)。

外部パラメータ:

  • ヘッドマウントディスプレイ上では、実際のデータを提供しなければならない。
  • これは、物理カメラのデバイス/頭部のpose原点に対する物理的なオフセットを表すキャリブレーションマトリックスである。デバイスのposeと物理カメラのposeが等しい場合、それは単位行列であるべき。
  • Apple Vision Proの対応インターフェースは:CameraFrame.Sample.Parameters.extrinsics。そのデータ定義とインターフェースが要求するデータには違いがあることに注意が必要であり、EasyAR内部では変換を行った後に使用している。
  • Unityでは、外部パラメータの座標軸システムタイプはUnity座標系またはEasyAR座標系であるべき。もし入力拡張がEasyARによって実装され、他の座標軸システム定義が使用されている場合、明確な座標軸システムの定義を提供するか、Unity座標系またはEasyAR座標系への変換方法を提示すべき。
  • ヘッドマウントデバイスでは、通常、異なる定義を持つ複数の座標系が存在する。この違いには、座標軸の原点、向き、左右手系の表現などが含まれる可能性がある。外部パラメータは同一の座標系で計算されるべきであり、このインターフェースデータは同一座標系内での座標変換を必要とし、異なる定義を持つ2つの座標系間の変換行列ではない。

パフォーマンス:

  • データは最適な効率で提供されるべきである。ほとんどの実装では、API呼び出しはレンダリングプロセス中に発生するため、基盤層で時間のかかる操作が必要な場合でも、API呼び出しをブロックしないこと、またはこれらのAPIを合理的な方法で使用することが推奨される。
  • もし入力拡張がEasyARによって実装される場合、すべての時間のかかるAPI呼び出しについて説明が必要である。

マルチカメラ:

  • 少なくとも1つのカメラのデータが必要である。このカメラは、RGBカメラ、VSTカメラ、トラッキングカメラなどのいずれでもよい。ヘッドマウントディスプレイ上で1つのカメラのデータのみを入力する場合、通常は中央または目の近くにあるRGBカメラまたはVSTカメラの使用が推奨される。
  • マルチカメラを使用するとEasyARアルゴリズムの効果が向上する。利用可能なすべてのカメラのある時点のカメラフレームデータは、同じ時間点で同時に入力されるべきである。

マルチカメラは現在完全にはサポートされていない。詳細はEasyARにお問い合わせください。

次のステップ

関連トピック

  • EasyAR座標系
  • 画像入力拡張サンプル Workflow_FrameSource_ExternalImageStream