ARやMRで使われる、SLAMという技術の裏側を知りたい。

f:id:tnychor06:20190304180105j:plain 画像認識の応用先の1つとしてARやMRが挙げられると思いますが、正直あまり詳しくないので色々調べてます。 中でも面白そうな英語のブログを見つけたので、英語の練習もかねて翻訳してまとめたいと思います。

そのブログはこれ→ARCore and Arkit, What is under the hood: SLAM (Part 2)。 英語に自信あっても日本語の記事があると便利ですよね!

この記事のPart1では画像中の特徴点(キーポイント)の検出するアルゴリズムについて説明しています。 画像中から特徴点の検出を行うのは、周辺環境を認識する基本となります。

しかし、Mixed Realityにおいてはこれだけでは不十分です。 この2次元の画像から3次元上での位置を計算する必要があり、検出された数多くの特徴点間の空間的な距離を計算しないといけません。

この技術をSLAM(Simultaneous Localization and Mapping)と呼びます。 *1

この記事を読んでわかること:

  • どのようにARCoreとARKitがSLAM/Visual Inertial Odometryを行うのか。
  • SLAMの処理をより理解するために合理的な精度のSLAMを自作できるのか。

コンピュータ目線での空間センシング

まず始めにARアプリを起動したとき、行われることは「平面の検出」。 MRアプリをARKitやARCoreで起動した時には、システム自体は周辺環境についてまだ何も知りません。したがってカメラから画像を取得し、そのほかのセンサーとも接続を行います。

一度これらのデータが取得できると、

  1. 周辺の空間マップをポイントクラウドメッシュで構築する
  2. 認識した環境から相対的な位置を求める

処理を行います。ビーコンを設置して空間マップの構築を行う手法もあるが、ARのシステムにおいては不可能な状況が多い。

物体の位置関係

空間マップ、つまり物体間の関係から見ていきます。(参考文献: A stochastic map for uncertain spatial relationships - Semantic Scholar by Smith et al.)

実世界では、人間からするとそれぞれの物体の位置関係を正しく認識し情報を得ることは容易にできます。 しかしながらARの世界ではそれが難しくなります。

その難しさを理解するために空っぽの何もない部屋にいることを考えてみましょう。 ARアプリで、ある物体が確かに存在していることをAで検出し撮影者がBにいるとします。

f:id:tnychor06:20190304181238j:plain

実世界では、AとBの距離がわかっています。 もしBをCに動かしたいときにはどれくらい動かせば良いか推定できます。

f:id:tnychor06:20190304181858j:plain

残念ながらARやSLAM内の世界では、AとCの位置において完全に正確とは限らない情報しかありません。 その結果、不確かな物体の位置を正す必要があります。

f:id:tnychor06:20190304182310j:plain

それぞれの物体は相対的な位置関係を持つため、物体の存在確率で表すことができます。 その存在確率と位置の誤差を修正する手法はいくつかあります。 カルマンフィルター(Kalman Filter)、最大事後確率推定(Maximum Posteriori Estimation)、バンドル調整(Bundle Adjustment)です。

これらの推定手法は完全ではないので、新しいセンサーが出る度にその手法が更新されています。

認識した空間を整える

ARアプリで周辺の空間を確実に空間マップに構築するためには測定データを継続して更新する必要があります。 これは、どのセンサーから取得したデータにも誤差が含まれているだろう、という仮説のもと行われています。

この問題を理解するために、 Globally Consistent Range Scan Alignment for Environment Mapping | SpringerLink by Milios et al. を参考にします。

f:id:tnychor06:20190304183921j:plain

画像(a)の中でカメラが位置P1からPnまで動いてるのがわかります。このとき測定の誤差によって部屋の形がずれています。

しかし、画像(b)では精度が良くなっています。これは撮影時のフレームデータと位置関係を同時に追跡するアルゴリズムによるものです。

ここでの問題は、精度を保つためにどれほどのデータを保持し続けないといけないか、になります。計算量を減らすために保持するフレームを減らすという手法が使われています。

SLAMで空間マップを構築する

ARアプリを使いやすくするために、SLAMは以下の3つの課題に取り組む必要があります。

  1. 単眼カメラからの入力
  2. リアルタイムでの処理
  3. 時間経過による予測精度の低下

SLAMの骨組み

どのようにこれらの課題をARの中で扱えば良いのか? まずはCadena et al. が提案する(Past, Present, and Future of Simultaneous Localization and Mapping: Toward the Robust-Perception Age - IEEE Journals & Magazine)原理から考えていきましょう。 論文の中ではこのようなSLAMの基本構造について説明されています。

f:id:tnychor06:20190304223051j:plain

この図を分解していくと4つのモジュールに分けられます。

  1. センサー: モバイル端末では基本的にカメラがあり、加速度センサーやジャイロスコープ、デバイスによっては光センサーを利用しデータを取得する。
  2. フロントエンド: 特徴点の抽出と同じアンカーの特定を行う。
  3. バックエンド: 時間経過による精度の低下を補填するための誤差修正、カメラ位置や角度など姿勢の位置付けと幾何学的な空間全体の再構成を行う。
  4. SLAM推定: 検出した特徴と位置の最終的な結果を表す。

さらに理解するためにSLAMのオープンソースの実装を見てみましょう。

ORB-SLAMを覗き見してみよう

SLAMがどのように動くのかを理解するために、Montiel et al. によって最近実装されたアルゴリズムORB-SLAMを見てみましょう。

コードはORB-SLAM2を使っています。 アルゴリズムはGeneral Public Lisenceの元Githubで使用可能です。使い方の詳細はこちらのブログORB-Slam2: Implementation on my Ubuntu 16.04 with ROS Kinectに載っています。

彼のデモがこちらの動画になります。

youtu.be

ORB-SLAMはカメラからのデータのみを使っており、そのほかのジャイロスコープなどのセンサーは使っておりません。それでも精度が高いことがわかります。

  1. 特徴点の検出: ORB-SLAMは名前の通りORB(Oriented FAST and Rotated BRIEF: 詳しくはこちら)を使い特徴となるポイントを探し出し、バイナリ記述子(特徴量として記述された情報)を生成する。 ORB内部での処理はBRISKと同じ手法を元にしている。 ORB-SLAMは各フレームからキーフレームを取り出し保持しておき、後に空間マップの構築を行うときに過去データとして参照し精度を高めるのに使用する。
  2. 特徴点→3次元の目印: このアルゴリズムは新たなフレームを探し出すと特徴点の検出を行う。現フレーム内で検出された特徴点と前のフレームを比較し一致する点から空間的な距離を算出する。この手法は新しいフレームの中で同じ特徴点を再び見つけ出すという良いアイデアである。この手法では最初に推定されたカメラ姿勢が用意されている。
  3. カメラの姿勢を改良: このアルゴリズムは最初に推定されたカメラの姿勢を次のフレームでの特徴点の探索に使用する。この特徴点は前のフレームで検出された特徴点と同じ特徴点になる。これらの処理をStep2では繰り返す。もし確かに特徴点を見つけ出すことができれば、そのデータを使いカメラの姿勢を改良し空間的な測定誤差を修正する。
    f:id:tnychor06:20190304234652j:plain
    緑の枠が追跡されている特徴点。青の箱がキーフレーム。赤の箱がカメラの視点。赤の点が局所空間マップの点

ホーム位置に戻る、Loop Closing

ARアプリの1つのゴールとして、歩いて初期のホーム位置に戻ってきたときに「ホーム位置に戻ってきた」と認識することです。 カメラ固有の誤差や誘導誤差によってこの予測が難しいとされている。 これはSLAMにおいてはLoop Closingと呼ばれている。

ORB-SLAMはしきい値を決めることで対応している。あるフレームと次のフレームででの特徴点が一致し、さらに以前検出したフレーム中にそのフレームと一定のパーセンテージを超えて特徴点が一致するフレームが存在する場合に、ホーム位置に帰ってきたとする。 f:id:tnychor06:20190305000755j:plain

誤差を考慮するために、アルゴリズムでは更新されたループが閉じたという知識を全体のフレームに伝搬させて座標の修正を行います。 f:id:tnychor06:20190305001138j:plain

最後に

以上がブログの和訳になります。 SLAMに関してほとんど知識なかったため単語の意味がわからなくて意訳に近い部分があるかと思いますが、どんどんご指摘ください。

このブログを読んでSLAMのことが少しはわかったような気がしています。 リアルタイムで前のフレームと比較して特徴点のマッチングを行うとかできるんだ、と感心していました。 というのも研究ではバドミントンの選手の行動認識をしていましたが、リアルタイムでの処理とは程遠い手法だったからです。

視点が固定されていなくても特徴点のマッチングで空間を認識できるけど人物の行動を分類したりしようと思うと時系列の情報が必要となる。だからこそ、リアルタイムでの人物の行動認識は難しいのか、と改めた思った次第であります。

今後も興味のある分野を調べてはブログに書いていきたいと思いますー。

*1:ARKitはVisual Inertial Odometryという技術を使っており厳密にはSLAMとは異なるらしい。