yotiky Tech Blog

とあるエンジニアの備忘録

HoloLens2 でQRコードのスキャンを実装する

目次

検証環境

  • Unity:2019.4.3f1
  • VisualStudio:2019
  • MRTK 2.5 (設定、UI、操作などに)
  • UniRx

手順

導入

  • NuGetForUnity のパッケージをDLして Import する
  • NuGet > Manage NuGet Packages を開いて、「Microsoft.MixedReality.QR」を検索して Install する

f:id:yotiky:20201022211436p:plain

実装

最低限の実装であれば、 QRCodeWatcher クラスだけで実装できます。 QRCodeWatcher に、Added、Updated、Removed のイベントがあるので、イベントハンドラを登録します。Start メソッドを呼び出すと、スキャンが開始されイベントが発行されるようになります。停止したい時は Stop メソッドで停止します。

一部抜粋した実装例を以下に示します。

    private QRCodeWatcher qRCodeWatcher;
    private readonly ConcurrentQueue<ActionData> pendingActions = new ConcurrentQueue<ActionData>();

    async void Start()
    {
        IsSupported = QRCodeWatcher.IsSupported();
        await QRCodeWatcher.RequestAccessAsync();

        qRCodeWatcher = new QRCodeWatcher();
        qRCodeWatcher.Added += QRCodeWatcher_Added;
        qRCodeWatcher.Updated += QRCodeWatcher_Updated;
        qRCodeWatcher.Removed += QRCodeWatcher_Removed;

        IsReady.Value = true;

        this.UpdateAsObservable()
            .Subscribe(_ =>
            {
                if(pendingActions.TryDequeue(out var action))
                {
                    if (action.Type == ActionData.EventType.Added 
                        || action.Type == ActionData.EventType.Updated)
                    {
                        if (DateTimeOffset.Compare(StartTime, action.QRCode.LastDetectedTime) < 0)
                        {
                            onScanned.OnNext(action.QRCode);
                        }
                    }
                }

            })
            .AddTo(this);
    }

    public void StartScan()
    {
        if (!IsReady.Value) { return; }

        StartTime = DateTimeOffset.Now;
        qRCodeWatcher.Start();
    }

    public void StopScan()
    {
        if (!IsReady.Value) { return; }

        qRCodeWatcher.Stop();
    }
}

イベントハンドラはキューに ActionData を追加するだけなので割愛してます。

StartScan メソッドでは、StartTime を保存していますが、HoloLens は過去に認識したQRのデータを保持しています。スキャンを開始した日時よりも古いデータは無視するような処理が必要になってきます。

ビルドする前に、Capabilities で WebCam を有効にしてください。

f:id:yotiky:20201022231223g:plain

上の録画では後述する自作のQRアプリを使っています。このアプリでは ZXing を使用しており、CharacterSet を設定できますが、デフォルトと言われているISO-8859-1だとHoloLensが認識しません。そのためUTF-8を使用しています。

サンプルプロジェクト

ソースコード一式は以下においてあります。

github.com

参考

公式ページは英語のみ、C++が9割と参考なるのかならないのか。 ただ、QRスキャンに関するベストプラクティスが載っていますのでそこは必読です。(日本語に抄訳されている記事も)

docs.microsoft.com

また、以下のQRラッキングのサンプルを参考にさせて頂きました。 github.com

関連記事

yotiky.hatenablog.com

yotiky.hatenablog.com