tks_yoshinagaの日記

KinectやLeap motion, VRやARなどの技術を使ってやったことのメモとか

Google TangoでMarker Detectionを使おう

1.はじめに

 GoogleのTangoという技術を搭載した端末が発売されたおかげで、HoloLensのようなマーカーの事前準備が不要なARを手軽に実現できるようになりました。ところがそれに慣れてくると、「CGの配置を自由に行いたい」「毎回同じ位置にCGを表示させたい」という欲も出てきます。前者についてはDepthデータと画面のタップの組み合わせを、後者についてはAreaLearningの機能を用いれば実現できますが、開発・利用ともに手間や工夫を必要とします。そこで今回はこれらをもっと手軽に実現しようということでTangoSDKで提供されているMarker Detection機能をご紹介します。
 この機能では正方形マーカーとCGの位置が対応づけられているため、例えば以下の動画のようにマーカーを実際に手で動かしてCGを移動できます。また、マーカーを置きっぱなしにすれば毎回同じ位置にCGを出現させることも可能です。さらに、マーカーが検出に失敗したときはTangoのトラッキング機能が使えるため、ARコンテンツの体験を継続することができます。

 

2.準備

2.1 プロジェクトの作成とTangoSDKの導入

(1) Unityのプロジェクトを新規作成
(2) TangoSDK for Unityをダウンロード
(3) SDKをダブルクリックしてUnityのプロジェクトに追加

2.2 マーカーの印刷

f:id:tks_yoshinaga:20170708120408p:plain

Marker Detectionで使用されるマーカーは上記のように正方形の枠と、IDを表すドットパターンを組み合わせたものです。ちなみにマーカーの画像はUnityプロジェクト内の下記のディレクトリにPDF形式(ar_markers.pdf)で提供されていますので、事前に印刷しておきましょう。
[Assets] → [TangoSDK] → [Examples] → [MarkerDetection]

余談:
TangoSDKで対応しているマーカーはALVARのAR Tagのようです。ただし、本来であれば0~65535までのIDが使えるはずですがTangoで使う際には上限があり0~16までみたいです。(2017年7月現在)

3.開発

3.1 Uniyt Editor上での操作

Tangoの機能を使用するための設定や表示するCGの設定を行います。

(1) HierarchyからMain Cameraを削除
(2) Projectタブ内のフォルダをAssets→TangoPrefabsの順に開く
(3) Tango CameraTango ManagerをHierarchyにドラッグ&ドロップ
(4) Hierarchy内のTango Managerを選択 (下図)
(5) Inspactor内のEnable Video Overlayのチェックをオンにする
(6) MethodをTexture and Raw Bytesに変更

f:id:tks_yoshinaga:20170708123715j:plain

 
(7) Hierarchy内のTango Cameraを選択 (下図)
(8) Clear FlagsをSolid Colorに変更
(9) Tango AR Screenのチェックをオンにする

f:id:tks_yoshinaga:20170708153557j:plain


(10) Hierarchyをクリックして何も選択していない状態にする
(11) 続けてHierarchyをクリックして3D Object内のCubeを選択
(12) Hierarchy内に追加されたCubeを選択
(13) CubeのInspector内のScaleの項目を全て0.1に変更(0.1m相当)


次に、マーカー認識用のスクリプトを書く準備をします。

(14) Hierarchyをクリックして何も選択していない状態にする
(15) HierarchyをクリックしてCreateEmptyを選択
(16) 新たに追加されたGameObjectを選択
(17) GameObjectのInspector内、Add Componentをクリック
(18) New ScriptをクリックしMarkerTrackingと入力
(19) Create And Addをクリック
 

3.2 マーカー認識とCGの位置・角度への反映

Tango端末のカメラ画像からマーカー検出と位置・角度の推定を行い、その結果をCG(Cube)の位置・角度に反映させることでマーカーに追従させます。

(1) Assetsフォルダ内のMarkerTrackingファイル(C#)をダブルクリックして開く
(2) 下記のコードをコピー&ペースト
(3) マーカーの実寸サイズをmarkerSizeに代入
※この値が間違っているとマーカーを見失ってTangoの機能でのトラッキングに切り替わった際に不整合が生じます。

using System;
using System.Collections;
using System.Collections.Generic;
using Tango;
using UnityEngine;

public class MarkerTracking : MonoBehaviour, ITangoVideoOverlay
{
    //画像処理で発見されたマーカーを格納
    List<TangoSupport.Marker> markers;
    //Tangoの各種情報を扱う
    TangoApplication tango;
    //立方体(Cube)を扱う
    GameObject cube;
    //Cubeの高さ(単位はm)
    float cubeHeight;
    //マーカーの実寸(単位はm)
    double markerSize = 0.13;

    void Start()
    {
        //Tangoで起きたイベントを受け取れるように登録
        tango = FindObjectOfType<TangoApplication>();
        tango.Register(this);
        
        markers = new List<TangoSupport.Marker>();

        //Hierarchy内のCubeをこのスクリプト内で扱えるようにする
        cube = GameObject.Find("Cube");
        //Cubeの高さを取得(OnTangoImageAvailable...で使用)
        cubeHeight = cube.transform.lossyScale.y;
    }

    public void OnTangoImageAvailableEventHandler
(TangoEnums.TangoCameraId cameraId, TangoUnityImageData imageBuffer) { //画像処理によるマーカー検出と位置・角度計算。結果はmarkersに格納される TangoSupport.DetectMarkers(imageBuffer, cameraId,
TangoSupport.MarkerType.ARTAG, markerSize, markers); //検出されたマーカーの個数だけ処理を繰り返す for (int i = 0; i < markers.Count; ++i) { //マーカーのIDが1の時のみ処理を行う TangoSupport.Marker marker = markers[i]; if (marker.m_content == "1") { //マーカーの位置・角度をCubeに反映 cube.transform.position = marker.m_translation; cube.transform.rotation = marker.m_orientation; //Cubeの原点はCubeの中心なので高さの半分(0.5倍)だけ上に //ずらし、マーカーの上にCubeが乗っているように見せる。 cube.transform.Translate(0, cubeHeight * 0.5f, 0, Space.Self); } } } }

 

なおコピペではなく、自分でコードを記述する際には以下をお忘れなく。

  • TangoApplicationにこのスクリプトを必ず登録 (Start関数を参照)
  • ITangoVideoOverlayインターフェースを実装し、カメラからの画像をOnTangoImageAvailableEventHandlerで受け取れるようにする
  • DetectMarkersでマーカーの検出および位置・角度推定することはもちろん、その結果をCGの位置・角度に代入する。(OnTangoImageAvailableEventHandlerを参照)

4.動作確認

 ここまで出来たら、公式リファレンスに記載されている内容に従ってビルドの設定を行い実機にインストールしてください。うまくいけばID:1のマーカーの上に立方体が表示されます。

f:id:tks_yoshinaga:20170708141937j:plain 

5.おわりに

 マーカーを利用するARはどうしても隠れやロストに弱いという欠点がありますが、一方でマーカーレスARの場合は原点やCGの表示位置を一意に決定するのが難しいという欠点があります。どちらかだけが優れているではなく各方式にそれぞれメリット・デメリットがあるので、これらを組み合わせてARシステムを構築することでさらに利用の幅が広がるのではないかと考えています。


 今回は 以上です。なおUnityを使った開発についてはそれほど詳しくないのでお気づきの点があればご指摘いただけると嬉しいです。