QR コードの追跡QR code tracking

HoloLens 2 では、ヘッドセット周辺の環境内の QR コードを検出し、各コードの実際の場所で座標系を確立します。HoloLens 2 can detect QR codes in the environment around the headset, establishing a coordinate system at each code's real-world location.

デバイス サポートDevice support

機能Feature HoloLens (第 1 世代)HoloLens (1st gen)HoloLens 2HoloLens 2 イマーシブ ヘッドセットImmersive headsets
QR コードの検出QR code detection ✔️✔️✔️✔️

注意

デスクトップ Pc でのイマーシブ Windows Mixed Reality ヘッドセットを使用した QR コードの追跡は、Windows 10 バージョン2004以降でサポートされています。QR code tracking with immersive Windows Mixed Reality headsets on desktop PCs is supported on Windows 10 Version 2004 and higher. MixedReality () API を使用して、機能が現在のデバイスでサポートされているかどうかを判断します。Use the Microsoft.MixedReality.QRCodeWatcher.IsSupported() API to determine whether the feature is supported on the current device.

QR パッケージの取得Getting the QR package

QR コード検出用の NuGet パッケージは こちらからダウンロードできます。You can download the NuGet package for QR code detection here.

QR コードの検出Detecting QR codes

Web カメラ機能の追加Adding the webcam capability

QR コードを検出するには、マニフェストに機能を追加する必要があり webcam ます。You will need to add the capability webcam to your manifest to detect QR codes. この機能は、ユーザーの環境で検出されたコード内のデータに機密情報が含まれている場合に必要です。This capability is required as the data within detected codes in the user's environment may contain sensitive information.

アクセス許可を要求するには、次のように呼び出し QRCodeWatcher.RequestAccessAsync() ます。Permission can be requested by calling QRCodeWatcher.RequestAccessAsync():

VisualC#:

await QRCodeWatcher.RequestAccessAsync();

C++C++:

co_await QRCodeWatcher.RequestAccessAsync();

QRCodeWatcher オブジェクトを構築する前に、アクセス許可を要求する必要があります。Permission must be requested before you construct a QRCodeWatcher object.

QR コードの検出には機能が必要ですが、 webcam 検出はデバイスの追跡カメラを使用して行われます。While QR code detection requires the webcam capability, the detection occurs using the device's tracking cameras. これにより、デバイスの写真/ビデオ (PV) カメラとの検出と比較して、より広範な検出とバッテリ寿命が提供されます。This provides a wider detection FOV and better battery life compared to detection with the device's photo/video (PV) camera.

Unity での QR コードの検出Detecting QR codes in Unity

Unity の QR コード検出 API は、MRTK に依存せずに使用できます。You can use the QR code detection API in Unity without taking a dependency on MRTK. これを行うには、nuget For Unityを使用して nuget パッケージをインストールする必要があります。To do so, you must install the NuGet package using NuGet for Unity.

サンプル Unity アプリには、QR コードに holographic 二乗と、関連するデータ (GUID、物理サイズ、タイムスタンプ、デコードされたデータなど) が表示されます。There is a sample Unity app that displays a holographic square over QR codes, along with the associated data such as GUID, physical size, timestamp, and decoded data. このアプリは、にあり https://github.com/chgatla-microsoft/QRTracking/tree/master/SampleQRCodes ます。This app can be located at https://github.com/chgatla-microsoft/QRTracking/tree/master/SampleQRCodes.

C++ での QR コードの検出Detecting QR codes in C++

using namespace winrt::Windows::Foundation;
using namespace winrt::Microsoft::MixedReality::QR;

class QRListHelper
{
public:
    QRListHelper(MyApplication& app) :
        m_app(app)
    {}

    IAsyncAction SetUpQRCodes()
    {
        if (QRCodeWatcher::IsSupported())
        {
            QRCodeWatcherAccessStatus status = co_await QRCodeWatcher::RequestAccessAsync();
            InitializeQR(status);
        }
    }

private:
    void OnAddedQRCode(const IInspectable&, const QRCodeAddedEventArgs& args)
    {
        m_app.OnAddedQRCode(args);
    }

    void OnUpdatedQRCode(const IInspectable&, const QRCodeUpdatedEventArgs& args)
    {
        m_app.OnUpdatedQRCode(args);
    }

    void OnEnumerationComplete(const IInspectable&, const IInspectable&)
    {
        m_app.OnEnumerationComplete();
    }

    MyApplication& m_app;
    QRCodeWatcher m_qrWatcher{ nullptr };

    void InitializeQR(QRCodeWatcherAccessStatus status)
    {
        if (status == QRCodeWatcherAccessStatus::Allowed)
        {
            m_qrWatcher = QRCodeWatcher();
            m_qrWatcher.Added({ this, &QRListHelper::OnAddedQRCode });
            m_qrWatcher.Updated({ this, &QRListHelper::OnUpdatedQRCode });
            m_qrWatcher.EnumerationCompleted({ this, &QRListHelper::OnEnumerationComplete });
            m_qrWatcher.Start();
        }
        else
        {
            // Permission denied by system or user
            // Handle the failures
        }
    }
};

QR コードの座標系を取得するGetting the coordinate system for a QR code

検出された各 QR コードは、次に示すように、左上の高速検出四角形の左上隅にある QR コードに一致する 空間座標システム を公開します。Each detected QR code exposes a spatial coordinate system aligned with the QR code at the top left corner of the fast detection square in the top left as seen below. QR SDK を直接使用している場合、Z 軸は用紙を指しています (図には示されていません)。 Unity 座標に変換されると、Z 軸は用紙から外れ、左手で示されます。When directly using the QR SDK, the Z-axis is pointing into the paper (not shown) - when converted into Unity coordinates, the Z-axis points out of the paper and is left-handed.

QR コードの SpatialCoordinateSystem は、示されているように配置されます。A QR code's SpatialCoordinateSystem aligns as shown. この座標系は、 SpatialGraphInteropPreview:: CreateCoordinateSystemForNode を呼び出し、コードの SpatialGraphNodeId を渡すことによって、プラットフォームから取得できます。This coordinate system can be obtained from the platform by calling SpatialGraphInteropPreview::CreateCoordinateSystemForNode and passing in the code's SpatialGraphNodeId.

QR コードの座標系

QRCode オブジェクトの場合、次の C++ コードは、QR コードの座標系を使用して、四角形を作成して配置する方法を示しています。For a QRCode object, the following C++ code shows how to create a rectangle and place it using the QR code's coordinate system:

// Creates a 2D rectangle in the x-y plane, with the specified properties.
std::vector<float3> MyApplication::CreateRectangle(float width, float height)
{
    std::vector<float3> vertices(4);

    vertices[0] = { 0, 0, 0 };
    vertices[1] = { width, 0, 0 };
    vertices[2] = { width, height, 0 };
    vertices[3] = { 0, height, 0 };

    return vertices;
}

次のように、物理的なサイズを使用して QR 四角形を作成できます。You can use the physical size to create the QR rectangle:

std::vector<float3> qrVertices = CreateRectangle(code.PhysicalSideLength(), code.PhysicalSideLength()); 

座標系は、QR コードを描画したり、場所にホログラムをアタッチしたりするために使用できます。The coordinate system can be used to draw the QR code or attach holograms to the location:

using namespace winrt::Windows::Perception::Spatial;
using namespace winrt::Windows::Perception::Spatial::Preview;
SpatialCoordinateSystem qrCoordinateSystem = SpatialGraphInteropPreview::CreateCoordinateSystemForNode(code.SpatialGraphNodeId());

QRCodeAddedHandler は、次のようになります。Altogether, your QRCodeAddedHandler may look something like this:

void MyApplication::OnAddedQRCode(const QRCodeAddedEventArgs& args)
{
    QRCode code = args.Code();
    std::vector<float3> qrVertices = CreateRectangle(code.PhysicalSideLength(), code.PhysicalSideLength());
    std::vector<unsigned short> qrCodeIndices = TriangulatePoints(qrVertices);
    XMFLOAT3 qrAreaColor = XMFLOAT3(DirectX::Colors::Aqua);

    SpatialCoordinateSystem qrCoordinateSystem = SpatialGraphInteropPreview::CreateCoordinateSystemForNode(code.SpatialGraphNodeId());
    std::shared_ptr<SceneObject> m_qrShape =
        std::make_shared<SceneObject>(
            m_deviceResources,
            qrVertices,
            qrCodeIndices,
            qrAreaColor,
            qrCoordinateSystem);

    m_sceneController->AddSceneObject(m_qrShape);
}

QR コードの検出のベストプラクティスBest practices for QR code detection

QR コードに関する非表示のゾーンQuiet zones around QR Codes

QR コードを正しく読み取るには、コードのすべての辺の周りに余白が必要です。To be read correctly, QR codes require a margin around all sides of the code. この余白には、印刷されたコンテンツを含めることはできません。また、4つのモジュール (コード内の1つの黒い四角形) にする必要があります。This margin must not contain any printed content and should be four modules (a single black square in the code) wide.

QR 仕様には、非表示ゾーンに関する詳細情報が含まれています。The QR spec contains more information about quiet zones.

照明と背景Lighting and backdrop

QR コード検出の品質は、さまざまな照明と背景に影響します。QR code detection quality is susceptible to varying illumination and backdrop.

特に明るい照明を持つシーンでは、グレーの背景に黒のコードを印刷します。In a scene with particularly bright lighting, print a code that is black on a gray background. それ以外の場合は、黒の QR コードを白い背景に印刷します。Otherwise, print a black QR code on a white background.

コードの背景が特に暗い場合は、検出率が低い場合はグレーのコードで黒を試してみてください。If the backdrop to the code is particularly dark, try a black on gray code if your detection rate is low. 背景が比較的薄い場合は、通常のコードが正常に動作します。If the backdrop is relatively light, a regular code should work fine.

QR コードのサイズSize of QR codes

Windows Mixed Reality デバイスは、それぞれ 5 cm 未満の QR コードでは機能しません。Windows Mixed Reality devices do not work with QR codes with sides smaller than 5 cm each.

5から 10 cm の長さの辺までの QR コードの場合、コードを検出するには非常に近い必要があります。For QR codes between 5 and 10 cm length sides, you must be fairly close to detect the code. また、このサイズでコードを検出するのにも時間がかかります。It will also take longer to detect codes at this size.

コードを正確に検出するための正確な時間は、QR コードのサイズだけでなく、コードから離れた場所までの距離に依存します。The exact time to detect codes depends not only on the size of the QR codes, but how far you are away from the code. コードに近づけると、サイズの問題を相殺するのに役立ちます。Moving closer to the code will help offset issues with size.

QR コードからの距離と角度の位置Distance and angular position from the QR code

追跡カメラは、特定のレベルの詳細のみを検出できます。The tracking cameras can only detect a certain level of detail. 実際に小さいコードの場合は、< 10cm を横に配置する必要があります。For really small codes - < 10cm along the sides - you must be fairly close. バージョン1の QR コードが 10 ~ 25 cm 幅を超える場合、最小検出距離は0.15 メートルから0.5 メートルの範囲内です。For a version 1 QR code varying from 10 to 25 cm wide, the minimum detection distance ranges from 0.15 meters to 0.5 meters.

サイズの検出距離は直線的に増加します。The detection distance for size increases linearly.

QR 検出は、角度の範囲 (+ = 45deg) で動作します。QR detection works with a range of angles += 45deg. これは、コードを検出するための適切な解決策があることを確認するためのものです。This is to ensure we have proper resolution to detect the code.

ロゴ付き QR コードQR codes with logos

ロゴ付きの QR コードはテストされていないため、現在サポートされていません。QR codes with logos have not been tested and are currently unsupported.

QR コードデータの管理Managing QR code data

Windows Mixed Reality デバイスは、ドライバーのシステムレベルで QR コードを検出します。Windows Mixed Reality devices detect QR codes at the system level in the driver. デバイスが再起動されると、検出された QR コードは失われ、次に新しいオブジェクトとして再検出されます。When the device is rebooted, the detected QR codes are gone and will be re-detected as new objects next time.

特定のタイムスタンプよりも古い QR コードを無視するようにアプリを構成することをお勧めします。It is recommended to configure your app to ignore QR codes older than a specific timestamp. 現時点では、API は QR コード履歴のクリアをサポートしていません。Currently, the API does not support clearing QR code history.

スペースでの QR コードの配置QR code placement in a space

QR コードを配置する場所と方法に関する推奨事項については、「 HoloLens の環境に関する考慮事項」を参照してください。For recommendations on where and how to place QR codes, please refer to Environment considerations for HoloLens.

QR API リファレンスQR API reference

namespace Microsoft.MixedReality.QR
{
    /// <summary>
    /// Represents a detected QR code.
    /// </remarks>
    public class QRCode
    {
        /// <summary>
        /// Unique id that identifies this QR code for this session.
        /// </summary>
        public Guid Id { get; }

        /// <summary>
        /// Spatial graph node id for this QR code to create a coordinate system.
        /// </summary>
        public Guid SpatialGraphNodeId { get; }

        /// <summary>
        /// Version of this QR code. Version 1-40 are regular QR codes and M1 to M4 are Micro QR code formats 1-4.
        /// </summary>
        public QRVersion Version { get; }

        /// <summary>
        /// Physical width and height of this QR code in meters.
        /// </summary>
        public float PhysicalSideLength { get; }

        /// <summary>
        /// Decoded QR code data.
        /// </summary>
        public String Data { get; }

        /// <summary>
        /// Size of the RawData of this QR code.
        /// </summary>
        public UInt32 RawDataSize { get; }

        /// <summary>
        /// Gets the error-corrected raw data bytes.
        /// Used when the platform is unable to decode the code's format,
        /// allowing your app to decode as needed.
        /// </summary>
        public void GetRawData(byte[] buffer);

        /// <summary>
        /// The last detected time in 100ns QPC ticks.
        /// </summary>
        public System.TimeSpan SystemRelativeLastDetectedTime { get; }

        /// <summary>
        /// The last detected time.
        /// </summary>
        public System.DateTimeOffset LastDetectedTime { get; }
    }

    /// <summary>
    /// Event arguments for a QRCodeWatcher's Added event.
    /// </summary>
    public class QRCodeAddedEventArgs
    {
        /// <summary>
        /// Gets the QR Code that was added
        /// </summary>
        public QRCode Code { get; }
    }

    /// <summary>
    /// Event arguments for a QRCodeWatcher's Removed event.
    /// </summary>
    public class QRCodeRemovedEventArgs
    {
        /// <summary>
        /// Gets the QR Code that was removed.
        /// </summary>
        public QRCode Code { get; }
    }

    /// <summary>
    /// Event arguments for a QRCodeWatcher's Updated event.
    /// </summary>
    public class QRCodeUpdatedEventArgs
    {
        /// <summary>
        /// Gets the QR Code that was updated.
        /// </summary>
        public QRCode Code { get; }
    }

    /// <summary>
    /// Represents the status of an access request for QR code detection.
    /// </summary>
    public enum QRCodeWatcherAccessStatus
    {
        /// <summary>
        /// The system has denied permission for the app to detect QR codes.
        /// </summary>
        DeniedBySystem = 0,
        /// <summary>
        /// The app has not declared the webcam capability in its manifest.
        /// </summary>
        NotDeclaredByApp = 1,
        /// <summary>
        /// The user has denied permission for the app to detect QR codes.
        /// </summary>
        DeniedByUser = 2,
        /// <summary>
        /// A user prompt is required to get permission to detect QR codes.
        /// </summary>
        UserPromptRequired = 3,
        /// <summary>
        /// The user has given permission to detect QR codes.
        /// </summary>
        Allowed = 4,
    }

    /// <summary>
    /// Detects QR codes in the user's environment.
    /// </summary>
    public class QRCodeWatcher
    {
        /// <summary>
        /// Gets whether QR code detection is supported on the current device.
        /// </summary>
        public static bool IsSupported();

        /// <summary>
        /// Request user consent before using QR code detection.
        /// </summary>
        public static IAsyncOperation<QRCodeWatcherAccessStatus> RequestAccessAsync();

        /// <summary>
        /// Constructs a new QRCodeWatcher.
        /// </summary>
        public QRCodeWatcher();

        /// <summary>
        /// Starts detecting QR codes.
        /// </summary>
        /// <remarks>
        /// Start should only be called once RequestAccessAsync has succeeded.
        /// Start should not be called if QR code detection is not supported.
        /// Check that IsSupported returns true before calling Start.
        /// </remarks>
        public void Start();

        /// <summary>
        /// Stops detecting QR codes.
        /// </summary>
        public void Stop();

        /// <summary>
        /// Get the list of QR codes detected.
        /// </summary>
        /// <remarks>
        /// </remarks>
        public IList<QRCode> GetList();

        /// <summary>
        /// Event representing the addition of a QR Code.
        /// </summary>
        public event EventHandler<QRCodeAddedEventArgs> Added;

        /// <summary>
        /// Event representing the removal of a QR Code.
        /// </summary>
        public event EventHandler<QRCodeRemovedEventArgs> Removed;

        /// <summary>
        /// Event representing the update of a QR Code.
        /// </summary>
        public event EventHandler<QRCodeUpdatedEventArgs> Updated;

        /// <summary>
        /// Event representing the enumeration of QR Codes completing after a Start call.
        /// </summary>
        public event EventHandler<Object> EnumerationCompleted;
    }

    /// <summary>
    /// Version info for QR codes, including Micro QR codes.
    /// </summary>
    public enum QRVersion
    {
        QR1 = 1,
        QR2 = 2,
        QR3 = 3,
        QR4 = 4,
        QR5 = 5,
        QR6 = 6,
        QR7 = 7,
        QR8 = 8,
        QR9 = 9,
        QR10 = 10,
        QR11 = 11,
        QR12 = 12,
        QR13 = 13,
        QR14 = 14,
        QR15 = 15,
        QR16 = 16,
        QR17 = 17,
        QR18 = 18,
        QR19 = 19,
        QR20 = 20,
        QR21 = 21,
        QR22 = 22,
        QR23 = 23,
        QR24 = 24,
        QR25 = 25,
        QR26 = 26,
        QR27 = 27,
        QR28 = 28,
        QR29 = 29,
        QR30 = 30,
        QR31 = 31,
        QR32 = 32,
        QR33 = 33,
        QR34 = 34,
        QR35 = 35,
        QR36 = 36,
        QR37 = 37,
        QR38 = 38,
        QR39 = 39,
        QR40 = 40,
        MicroQRM1 = 41,
        MicroQRM2 = 42,
        MicroQRM3 = 43,
        MicroQRM4 = 44,
    }
}

関連項目See also