Seguimiento de códigos QRQR code tracking

HoloLens 2 puede detectar códigos QR en el entorno alrededor del caso, estableciendo un sistema de coordenadas en la ubicación real de cada código.HoloLens 2 can detect QR codes in the environment around the headset, establishing a coordinate system at each code's real-world location.

Compatibilidad con dispositivosDevice support

CaracterísticaFeature HoloLens (primera generación)HoloLens (first gen)HoloLens 2HoloLens 2 Cascos envolventesImmersive headsets
Detección del código QRQR code detection ✔️✔️✔️✔️

Nota

El seguimiento del código QR con auriculares con ventanas de gran nivel en equipos de escritorio es compatible con la versión 2004 y posteriores de Windows 10.QR code tracking with immersive Windows Mixed Reality headsets on desktop PCs is supported on Windows 10 Version 2004 and higher. Use la API Microsoft. MixedReality. QRCodeWatcher. IsSupported () para determinar si la característica es compatible con el dispositivo actual.Use the Microsoft.MixedReality.QRCodeWatcher.IsSupported() API to determine whether the feature is supported on the current device.

Obtención del paquete QRGetting the QR package

Puede descargar el paquete NuGet para la detección del código QR aquí.You can download the NuGet package for QR code detection here.

Detección de códigos QRDetecting QR codes

Agregar la funcionalidad de cámara webAdding the webcam capability

Deberá agregar la funcionalidad webcam al manifiesto para detectar códigos QR.You'll need to add the capability webcam to your manifest to detect QR codes. Esta capacidad es necesaria, ya que los datos de los códigos detectados en el entorno del usuario pueden contener información confidencial.This capability is required as the data within detected codes in the user's environment may contain sensitive information.

El permiso se puede solicitar mediante una llamada a QRCodeWatcher.RequestAccessAsync() :Permission can be requested by calling QRCodeWatcher.RequestAccessAsync():

C#C#:

await QRCodeWatcher.RequestAccessAsync();

CC++:

co_await QRCodeWatcher.RequestAccessAsync();

Se debe solicitar permiso antes de construir un objeto QRCodeWatcher.Permission must be requested before you construct a QRCodeWatcher object.

Aunque la detección del código QR requiere la webcam capacidad, la detección se produce mediante las cámaras de seguimiento del dispositivo.While QR code detection requires the webcam capability, the detection occurs using the device's tracking cameras. Esto proporciona un hipergráfico de detección más amplio y una mayor duración de la batería en comparación con la detección con la cámara foto/vídeo (PV) del dispositivo.This provides a wider detection FOV and better battery life compared to detection with the device's photo/video (PV) camera.

Detección de códigos QR en UnityDetecting QR codes in Unity

Puede usar la API de detección de código QR en Unity sin importar MRTK mediante la instalación del paquete de NuGet con Nuget para Unity.You can use the QR code detection API in Unity without importing MRTK by installing the NuGet package using NuGet for Unity. Si quiere saber cómo funciona, descargue la aplicación de ejemplo de Unity.If you want to get a feel for how it works, download the sample Unity app. La aplicación de ejemplo tiene ejemplos para mostrar un cuadrado holográfica sobre códigos QR y datos asociados, como GUID, tamaño físico, marca de tiempo y datos descodificados.The sample app has examples for displaying a holographic square over QR codes and associated data such as GUID, physical size, timestamp, and decoded data.

Detectar códigos QR en C++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
        }
    }
};

Obtención del sistema de coordenadas para un código QRGetting the coordinate system for a QR code

Cada código QR detectado expone un sistema de coordenadas espaciales alineado con el código QR en la esquina superior izquierda del cuadrado de detección rápida en la parte superior izquierda: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:

Sistema de coordenadas del código QR

Cuando se usa directamente el SDK QR, el eje Z apunta al papel (no se muestra) cuando se convierte en coordenadas de Unity, el eje Z apunta fuera del papel y se entrega a la izquierda.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.

El SpatialCoordinateSystem de un código QR se alinea como se muestra.A QR code's SpatialCoordinateSystem aligns as shown. Puede obtener el sistema de coordenadas de la plataforma llamando a SpatialGraphInteropPreview:: CreateCoordinateSystemForNode y pasando el SpatialGraphNodeId del código.You can get the coordinate system from the platform by calling SpatialGraphInteropPreview::CreateCoordinateSystemForNode and passing in the code's SpatialGraphNodeId.

En el código de C++ siguiente se muestra cómo crear un rectángulo y colocarlo mediante el sistema de coordenadas del código QR:The C++ code below 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;
}

Puede usar el tamaño físico para crear el rectángulo QR:You can use the physical size to create the QR rectangle:

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

El sistema de coordenadas se puede usar para dibujar el código QR o adjuntar hologramas a la ubicación: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());

Por completo, su QRCodeAddedHandler puede tener un aspecto similar al siguiente: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);
}

Prácticas recomendadas para la detección del código QRBest practices for QR code detection

Zonas tranquilas alrededor de códigos QRQuiet zones around QR Codes

Para que se puedan leer correctamente, los códigos QR requieren un margen alrededor de todos los lados del código.To be read correctly, QR codes require a margin around all sides of the code. Este margen no debe contener contenido impreso y debe ser de cuatro módulos (un solo cuadrado negro en el código).This margin must not contain any printed content and should be four modules (a single black square in the code) wide.

La especificación QR contiene más información acerca de las zonas tranquilas.The QR spec contains more information about quiet zones.

Iluminación y fondoLighting and backdrop

La calidad de detección del código QR es susceptible a la iluminación y el telón de fondo variables.QR code detection quality is susceptible to varying illumination and backdrop.

En una escena con iluminación brillante, imprima un código negro sobre un fondo gris.In a scene with bright lighting, print a code that is black on a gray background. De lo contrario, imprima un código QR negro sobre un fondo blanco.Otherwise, print a black QR code on a white background.

Si el telón de fondo del código es oscuro, pruebe con un color negro en el código gris si la tasa de detección es baja.If the backdrop to the code is dark, try a black on gray code if your detection rate is low. Si el telón de fondo es relativamente claro, un código normal debería funcionar correctamente.If the backdrop is relatively light, a regular code should work fine.

Tamaño de los códigos QRSize of QR codes

Los dispositivos de Windows Mixed Reality no funcionan con códigos QR con lados inferiores a 5 cm cada uno.Windows Mixed Reality devices don't work with QR codes with sides smaller than 5 cm each.

En el caso de los códigos QR entre 5 cm y 10 cm de longitud, debe estar bastante cerca de detectar el código.For QR codes between 5 cm and 10-cm length sides, you must be fairly close to detect the code. También se tardará más tiempo en detectar códigos en este tamaño.It will also take longer to detect codes at this size.

El tiempo exacto para detectar códigos depende no solo del tamaño de los códigos QR, sino de la distancia del código.The exact time to detect codes depends not only on the size of the QR codes, but how far you're away from the code. Si se desplaza más cerca del código, se le ayudará a desplazar los problemas con el tamaño.Moving closer to the code will help offset issues with size.

Distancia y posición angular del código QRDistance and angular position from the QR code

Las cámaras de seguimiento solo pueden detectar un cierto nivel de detalle.The tracking cameras can only detect a certain level of detail. En el caso de códigos pequeños (< 10 cm a lo largo de los lados) debe estar bastante cerca.For small codes - < 10 cm along the sides - you must be fairly close. En el caso de un código QR de la versión 1 que varía de 10 cm a 25 cm de ancho, la distancia mínima de detección oscila entre 0,15 y 0,5 metros.For a version 1 QR code varying from 10 cm to 25 cm wide, the minimum detection distance ranges from 0.15 meters to 0.5 meters.

La distancia de detección para el tamaño aumenta linealmente.The detection distance for size increases linearly.

La detección de QR funciona con un rango de ángulos + = 45 grados para garantizar que tenemos una solución adecuada para detectar el código.QR detection works with a range of angles += 45 deg to ensure we have proper resolution to detect the code.

Códigos QR con logotiposQR codes with logos

Los códigos QR con logotipos no se han probado y actualmente no se admiten.QR codes with logos haven't been tested and are currently unsupported.

Administración de datos de código QRManaging QR code data

Los dispositivos de Windows Mixed Reality detectan códigos QR en el nivel de sistema del controlador.Windows Mixed Reality devices detect QR codes at the system level in the driver. Cuando se reinicia el dispositivo, los códigos QR detectados desaparecen y se volverán a detectar como nuevos objetos la próxima vez.When the device is rebooted, the detected QR codes are gone and will be redetected as new objects next time.

Se recomienda configurar la aplicación para omitir los códigos QR anteriores a una marca de tiempo específica.We recommend configuring your app to ignore QR codes older than a specific timestamp. Actualmente, la API no permite borrar el historial del código QR.Currently, the API doesn't support clearing QR code history.

Colocación del código QR en un espacioQR code placement in a space

Para obtener recomendaciones sobre dónde y cómo colocar códigos QR, consulte consideraciones de entorno para HoloLens.For recommendations on where and how to place QR codes, refer to Environment considerations for HoloLens.

Referencia de la API QRQR 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,
    }
}

Consulte tambiénSee also