ARKitのまとめ(概要)
Jul 16, 2017 · iosarkit
概要
WWDC2017で発表されたARKit
についてのまとめ
ARKit
はiOS上でARを実現するためのフレームワークである
スマホでのよくあるARでは、GPSの位置情報を元にしたローケーション型や画像認識を元にしたマーカー型やマーカーレス型が多いが、ARKit
では画像認識とモーションセンサーを組み合わせた自己位置認識(visual-inertial odometry
)を元にしている
一般的な使い方の手順としては、
- 実空間の状態(位置など)を検出する
- 検出した情報を元に、仮想オブジェクトを配置する
- カメラでキャプチャした画像に重ね合わせて仮想オブジェクトを描画
となる。 この仮想オブジェクトとは、例えば家具を配置するアプリなら家具に該当するもので、ARとして現実世界に登場させたい「もの」のことである
このオブジェクトを描画する際に、リアリティをいかに持たせるか(仮想のオブジェクトと現実の景色を融合させるか)がARのポイントとなる。 例えば、家具を配置させるアプリの場合は、実際に床の上に実物大で家具が置かれていたり、カメラ(デバイス)の位置や向きが変わるとそれに追従して家具の位置や向きも変わる必要がある
ARKit
の場合は、デバイスや仮想オブジェクトの位置や向き、大きさを簡単に取得でき、SceneKit
やSpriteKit
を使えば描画も簡単である(アプリ側での座標計算は基本不要)。
また、他のフレームワークと違って、照明状況(明るさ)も取得できるのが特徴。
ただし、検知できる物体が平面(床)だけなので、マーカー型の様にこちらからピンポイントの位置を指定して出すのは難しい。
一方で、ヒットテストがあるので、ユーザが画面をタップして位置を指定というのは簡単である
動作環境
- iOS11
- iPhone6S以降
機種が対応していれば、デプスセンサーの様な追加のセンサーであったり、空間スキャンなどの事前設定が不要なのも特徴 (ただし、その分環境によっては認識精度が落ちる)
なお、Unity
やUE4
でもフルサポートされる予定
他のフレームワークとの関係性
以下の2つのフレームワークの上に構成されている
AVFoundation
: カメラ画像のキャプチャ用CoreMotion
: センサー用
AR空間に配置したオブジェクトのレンダリング用に、以下のフレームワークには専用のクラスが用意されている
SceneKit
: 3Dの場合SpriteKit
: 2Dの場合
カスタムレンダリングをしたい場合は、Metal
を使うことが推奨されている
機能
デバイスのトラッキング
実空間におけるデバイスの相対的な位置や向きを追跡(トラッキング)し続ける機能
「相対的な」というのがポイントで、ARKit
の実行開始時を原点(0, 0, 0)
として、どれだけデバイスが動いたかを追跡し続けることにより、現時点での位置や向きを取得できるようにしている
デバイスの位置が特定できるので、それを元にAR空間に追加した仮想オブジェクトの位置も特定できる
また、実際の物体のスケール(大きさ)もm
(メートル)単位で取得できる
仕組みと動作
カメラの画像やデバイスの位置や向きや回転から、セッションの開始位置からの相対的な位置(物理的な距離と向き)を求めている。 画像からは3次元の特徴点を複数検出し、それを元に三角測量の原理で特定しているらしい
よって、画像やセンサーのデータが止まってしまうと、トラッキングもできなくなる。 また、特徴点の検出がしにくい画像(背景)の場合もトラッキングが制限される。 例えば、白い壁の様に特徴となるものが無い場合や十分な明るさがない場合は、精度が落ちたりトラッキングができなくなる
トラッキング時は、動きの少ない画像(デバイスや背景があまり動かない)が効果的である。 あまりに動きが大きいとモーションデータ(センサー情報)と画像情報が一致せずにドリフトが発生してしまう
場面把握
デバイスがある空間(シーン)の状況を把握する機能
以下の3つから成る
- 平面検出: 床やテーブルといった平面(水平面)を検出する機能
- ヒットテスト: 指定したポイントからレイキャストを行い、平面や特徴点との交差判定を行うする機能
- 照明の明るさを推測する機能
この機能により、指定したテーブルの上にオブジェクトをリアルに配置するといったことが行える
仕組みと動作
シーンの状況は画像を複数のフレームにわたり集計することで検出している。 それで、カメラを動かすならより多くの情報を取得できる(ただし、速く動かすとトラッキング精度が落ちる)。 逆に言うと、カメラで捉えていない部分の状況の把握はできない(当然だけど・・・)
この状況の把握はリアルタイムで行われ、例えばデバイスを動かすことで新たな平面が検出されたりすると、即座にアプリ側に通知される
平面検出
検出できるのは水平面だけであり、壁のような垂直面は検出できない。 平面は一つだけでなく、ある程度の大きさのある平面なら複数検出できる
実際に検出された平面は、その平面が収まる矩形に調整されて通知される。 一度検出された平面も、デバイスが動くことで情報が追加されると範囲が更新されていく
もし複数の平面が検出され、それらが物理的に同一の面であるなら、ARKitはそれを一つの面にマージする。 マージされた場合、新しい方の面が削除され、元からある方の面の範囲が大きくなる
ヒットテスト
指定したポイントとぶつかる平面または特徴点があるかを検索する。 検索対象はオプションとして指定でき、結果は距離が近い順にソートされた配列で取得できる。 (配列の最初にデバイスと一番近い交点が入る)
始点となるポイントは、正規化されたカメラ画像の座標空間で指定できる。
座標系は左上が(0, 0)
, 右下が(1, 1)
となる。
この指定された座標とデバイスの位置から実空間での始点となる位置を求め、
そこからデバイスのカメラの向きに向かってレイを照射し交差判定を行う
SceneKit
やSpriteKit
では、ビュー座標で指定ができるメソッドが準備されているので、
画面のタップした位置を渡して結果を取得するのが簡単にできる
照明の状況
シーンの環境光の強度を推定する機能。 デフォルト(ニュートラル)を1000ルーメン。 明るい場所では数値は大きく、暗い場所では数値は小さくなる
これによりリアルなライティングを行え、仮想のオブジェクトを現実空間により溶け込ませることができる。
なお、SceneKit
のARSCNView
は自動でこの値を使ってライトを調整することができる
確認環境
- Xcode9.0 beta3