Acompanhamento de código QRQR code tracking

O HoloLens 2 pode detectar códigos QR no ambiente em torno do headset, estabelecendo um sistema de coordenadas na localização do mundo 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.

Suporte a dispositivosDevice support

RecursoFeature HoloLens (primeira gen)HoloLens (first gen)HoloLens 2HoloLens 2 Headsets imersivosImmersive headsets
Detecção de código QRQR code detection ✔️✔️✔️✔️

Observação

O controle de código QR com alto-se com o Windows Mixed Realm headsets em computadores desktop tem suporte no Windows 10 versão 2004 e superior.QR code tracking with immersive Windows Mixed Reality headsets on desktop PCs is supported on Windows 10 Version 2004 and higher. Use a API Microsoft. MixedReality. QRCodeWatcher. IsSupported () para determinar se o recurso tem suporte no dispositivo atual.Use the Microsoft.MixedReality.QRCodeWatcher.IsSupported() API to determine whether the feature is supported on the current device.

Obtendo o pacote QRGetting the QR package

Você pode baixar o pacote NuGet para detecção de código QR aqui.You can download the NuGet package for QR code detection here.

Detectando códigos QRDetecting QR codes

Adicionando o recurso de webcamAdding the webcam capability

Você precisará adicionar a capacidade webcam ao seu manifesto para detectar códigos QR.You'll need to add the capability webcam to your manifest to detect QR codes. Esse recurso é necessário, pois os dados dentro de códigos detectados no ambiente do usuário podem conter informações confidenciais.This capability is required as the data within detected codes in the user's environment may contain sensitive information.

A permissão pode ser solicitada chamando QRCodeWatcher.RequestAccessAsync() :Permission can be requested by calling QRCodeWatcher.RequestAccessAsync():

C#C#:

await QRCodeWatcher.RequestAccessAsync();

CC++:

co_await QRCodeWatcher.RequestAccessAsync();

A permissão deve ser solicitada antes de construir um objeto QRCodeWatcher.Permission must be requested before you construct a QRCodeWatcher object.

Embora a detecção de código QR exija o webcam recurso, a detecção ocorre usando as câmeras de rastreamento do dispositivo.While QR code detection requires the webcam capability, the detection occurs using the device's tracking cameras. Isso fornece uma FOV de detecção mais ampla e uma melhor vida útil da bateria em comparação com a detecção com a câmera de foto/vídeo (PV) do dispositivo.This provides a wider detection FOV and better battery life compared to detection with the device's photo/video (PV) camera.

Detectando códigos QR no UnityDetecting QR codes in Unity

Você pode usar a API de detecção de código QR no Unity sem importar o MRTK instalando o pacote NuGet usando o 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. Se você quiser ter uma ideia de como funciona, baixe o aplicativo do Unity de exemplo.If you want to get a feel for how it works, download the sample Unity app. O aplicativo de exemplo tem exemplos para exibir um Holographic quadrado sobre códigos QR e dados associados, como GUID, tamanho físico, carimbo de data/hora e dados decodificados.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.

Detectando códigos QR em 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
        }
    }
};

Obtendo o sistema de coordenadas para um código QRGetting the coordinate system for a QR code

Cada código QR detectado expõe um sistema de coordenadas espaciais alinhado com o código QR no canto superior esquerdo do quadrado de detecção rápida na parte superior esquerda: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 de código QR

Ao usar o SDK QR diretamente, o eixo Z está apontando para o papel (não mostrado)-quando convertido em coordenadas do Unity, o eixo Z aponta para fora do papel e é canhoto.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.

Um SpatialCoordinateSystem de código QR é alinhado conforme mostrado.A QR code's SpatialCoordinateSystem aligns as shown. Você pode obter o sistema de coordenadas da plataforma chamando SpatialGraphInteropPreview:: CreateCoordinateSystemForNode e passando o SpatialGraphNodeId do código.You can get the coordinate system from the platform by calling SpatialGraphInteropPreview::CreateCoordinateSystemForNode and passing in the code's SpatialGraphNodeId.

O código C++ abaixo mostra como criar um retângulo e colocá-lo usando o sistema de coordenadas do 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;
}

Você pode usar o tamanho físico para criar o retângulo QR:You can use the physical size to create the QR rectangle:

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

O sistema de coordenadas pode ser usado para desenhar o código QR ou anexar hologramas ao local: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());

Totalmente, seu QRCodeAddedHandler pode ser semelhante a este: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áticas recomendadas para detecção de código QRBest practices for QR code detection

Zonas silenciosas em cerca de códigos QRQuiet zones around QR Codes

Para ser lido corretamente, os códigos QR exigem uma margem em volta de todos os lados do código.To be read correctly, QR codes require a margin around all sides of the code. Essa margem não deve conter nenhum conteúdo impresso e deve ter quatro módulos (um único quadrado preto no código) de largura.This margin must not contain any printed content and should be four modules (a single black square in the code) wide.

A especificação QR contém mais informações sobre zonas silenciosas.The QR spec contains more information about quiet zones.

Iluminação e pano de fundoLighting and backdrop

A qualidade de detecção de código QR é suscetível à iluminação e ao pano de fundo variadas.QR code detection quality is susceptible to varying illumination and backdrop.

Em uma cena com iluminação brilhante, imprima um código preto em um plano de fundo cinza.In a scene with bright lighting, print a code that is black on a gray background. Caso contrário, imprima um código QR preto em um plano de fundo branco.Otherwise, print a black QR code on a white background.

Se o pano de fundo para o código for escuro, experimente um preto no código cinza se a taxa de detecção for baixa.If the backdrop to the code is dark, try a black on gray code if your detection rate is low. Se o pano de fundo for relativamente claro, um código regular deverá funcionar bem.If the backdrop is relatively light, a regular code should work fine.

Tamanho dos códigos QRSize of QR codes

Os dispositivos Windows Mixed Reality não funcionam com códigos QR com lados menores que 5 cm cada.Windows Mixed Reality devices don't work with QR codes with sides smaller than 5 cm each.

Para códigos QR entre lados de comprimento de 5 cm e 10 cm, você deve estar bastante perto de detectar o código.For QR codes between 5 cm and 10-cm length sides, you must be fairly close to detect the code. Também levará mais tempo para detectar códigos nesse tamanho.It will also take longer to detect codes at this size.

O tempo exato para detectar códigos depende não apenas do tamanho dos códigos QR, mas o quanto você está longe do 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. Avançar para o código ajudará a deslocar os problemas com o tamanho.Moving closer to the code will help offset issues with size.

Distância e posição angular do código QRDistance and angular position from the QR code

As câmeras de rastreamento só podem detectar um determinado nível de detalhe.The tracking cameras can only detect a certain level of detail. Para códigos pequenos – < 10 cm ao longo dos lados-você deve estar bem próximo.For small codes - < 10 cm along the sides - you must be fairly close. Para um código QR da versão 1 variando de 10 cm a 25 cm de largura, a distância mínima de detecção varia de 0,15 metros a 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.

A distância de detecção para o tamanho aumenta linearmente.The detection distance for size increases linearly.

A detecção QR funciona com um intervalo de ângulos + = 45 graus para garantir que tenhamos a resolução adequada para detectar o 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 com logotiposQR codes with logos

Códigos QR com logotipos não foram testados e não têm suporte no momento.QR codes with logos haven't been tested and are currently unsupported.

Gerenciando dados de código QRManaging QR code data

Dispositivos Windows Mixed Reality detectam códigos QR no nível do sistema no driver.Windows Mixed Reality devices detect QR codes at the system level in the driver. Quando o dispositivo é reinicializado, os códigos QR detectados são desfeitos e serão detectados novamente como novos objetos da próxima vez.When the device is rebooted, the detected QR codes are gone and will be redetected as new objects next time.

É recomendável configurar seu aplicativo para ignorar códigos QR anteriores a um carimbo de data/hora específico.We recommend configuring your app to ignore QR codes older than a specific timestamp. Atualmente, a API não dá suporte à limpeza do histórico de código QR.Currently, the API doesn't support clearing QR code history.

Posicionamento de código QR em um espaçoQR code placement in a space

Para obter recomendações sobre onde e como inserir códigos QR, consulte considerações de ambiente para o HoloLens.For recommendations on where and how to place QR codes, refer to Environment considerations for HoloLens.

Referência de 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,
    }
}

Confira tambémSee also