はじめに
この投稿はAR Advent Calendar 2018 21日目の記事です!
21日目は社内でARギルドというARアプリを開発する活動をしている(弊社のギルド制度についてはコチラ)iOSエンジニアのcokaholicが担当します。
今回はARKitにおける画像検出と画像トラッキングについてざっくりと解説し、画像検出から画像トラッキングへ書き換える方法ってこんなにも簡単なんだなって思った話について話します。
ARKitの機能の変遷
まずは「画像検出」と「画像トラッキング」の両者がARKitに追加されるまでの流れについて話します。
Apple WWDC2017 - Introducing ARKit: Augmented Reality for iOSより
ARKit 1.0
ARKitは2018年12月現在、version 2.0までありますので、WWDC 2017時点で発表されたARKitのことをここではARKit 1.0と呼称することにします。
2017年に初めて発表されたARKit 1.0では、以下のような特徴があることが発表されました。
- 早く、安定したモーショントラッキング
- 基本的な境界での平面推定
- 環境光推定
- スケール推定
- UnityやUnreal Engine、Appleの3DフレームワークであるSceneKitをサポート
- Xcodeのテンプレートを用意
- 端末内のカメラ、CPU/GPU、モーションセンサーでAR表現を実現
ARKit 1.5
その後、2018年3月29日にリリースされた「iOS 11.3」へのアップデートでARKitはversion 1.5を迎えます。
ARKit 1.5では、以下のような新機能の追加とパフォーマンスの向上が行われました。
- 壁などの垂直面の検出機能を追加
- 既知の2次元画像の検出機能を追加
- 円形テーブルのようなイレギュラーな形をした平面へのマッピング精度の向上
- カメラで映し出される現実世界の解像度を50%向上し、オートフォーカス機能を追加
この時点で「画像検出」機能がARKitに追加されました。
ARKit 2.0
そして、2018年9月18日。2018年6月にWWDC 2018で発表され、新型のiPhone XS, iPhone XS Max, iPhone XRの発表後に満を持してリリースされた「iOS 12」でARKitはversion 2.0を迎えます。
ARKit 2.0では、以下のような大幅な新機能の追加が行われました。
- 現実世界で検出した特徴点の永続化とその復元機能を追加
- オブジェクトの周りの環境をテクスチャとして写し込ませることができる機能を追加
- 既知の2次元画像のトラッキング機能を追加
- 3次元の物体をスキャンし、スキャンした3次元オブジェクトを検出できる機能を追加
- フェイストラッキングに目線と舌をトラッキングできる機能を追加
ここでついに、「画像トラッキング」機能がARKitに追加されました。
ARKit 1.5の「画像検出」とARKit 2.0の「画像トラッキング」の違い
この両者の違いについてですが、ARKit 1.5までの「画像検出」では、画像を検出することはできても、検出された画像側を動かした場合に、検出位置が固定されたままになり、動かされた画像に検出位置が追随していくことはできませんでした。
しかし、ARKit 2.0で追加された「画像トラッキング」では、検出された画像側を動かされた場合でも、検出位置が動かされた画像に追随していくことができるようになりました。
これが両者の大きな違いです。
また、このテーマについては、@shu223さんの以下の記事がとても参考になりますので、おすすめです。
ARKit 2.0の画像トラッキングとARKit 1.5の画像検出の違い - Qiita
ARKitにおける画像検出
次はARKit 1.5の「画像検出」を行うまでの流れをざっくりと説明していきます。
(Xcodeで「Augmented Reality App」テンプレートとかでARKitのベース部分は用意している前提)
1. 検出するための画像を追加するグループを作成する
まずは、Assets.xcassetsを開き、+メニューからNew AR Resource Groupを選択し、AR Resourcesグループを作成しましょう。
2. 検出するための画像をグループに追加する
次に、検知させるための画像を「AR Resources」グループ内に
ドラッグ&ドロップで追加します。
サンプルとして、私が最近ハマっているバーチャルユーチューバーの田中ヒメちゃんの画像と(株)アクトゼロさんが提供している商用フリーの昔の少女マンガ風イラスト画像を追加してみました。
そして、追加した画像にはそれぞれインスペクターから、検出する画像の現実世界でのサイズを入力してください。
検出する画像の現実世界でのサイズを入力してもエラーが消えない場合は、
その画像が画像検出に向いていない理由が表示されます。
こうなった場合は、エラー内容に準拠した別の画像を用意しましょう。
Tips: 画像検出に適した画像について
実際に入れてみたらわかるのですが、結構判定はシビアでした。
背景が白っぽい画像とかはほぼうまくいかなさそうです。
画像検出に適した画像と適さない画像の違いは主に以下の画像の通りです。
3. 検出画像を ARWorldTrackingConfiguration の detectionImages に追加する
検出させるための画像を「AR Resources」グループ内に追加したら、グループ名である「AR Resources」から referenceImages: Set<ARReferenceImage>
のインスタンスを生成します。
そして、configuration: ARWorldTrackingConfiguration
の detectionImages
に生成した referenceImages
をセットすると、画像を検出できるようになります。
画像の検出は ARSCNViewDelegate
の func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)
メソッド内にて行います。
検出した画像の名前によって、どの画像が検出されたかがわかるため、画像ごとに反応を変えることもできます。
ARKitにおける画像トラッキング
さて、次は先ほどの画像検出のコードからARKit 2.0で追加された画像トラッキングに書き換える方法について説明していきます。
1. configuration の変更
以下の画像のように、先ほどのARKitにおける画像検出の章の第3節で解説したdetectionImages
をセットしたconfiguration
をARWorldTrackingConfiguration
からARImageTrackingConfiguration
へ変更し、configuration
へreferenceImages
をセットするプロパティをdetectionImages
からtrackingImages
へ変更するだけで、なんと、画像トラッキングに変わります。超簡単ですね。半端ないって。
画像の検出は先ほどと同じく、 ARSCNViewDelegate
の func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)
メソッド内にて行います。
そして、検出した画像に追随するためのアンカーの更新はアンカーが変化するたびに呼び出される ARSCNViewDelegate
の func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor)
メソッド内で行うことができます。
このとき、お互いのメソッドで検出した画像それぞれを識別するためには、引数で受け取っている anchor: ARAnchor
の anchor.identifier
を使用するとそれぞれで識別することができます。
最後に
今回の記事はここまでとなります。
今年はARKit 2.0の大幅な機能追加によって、ARKitは大いに盛り上がった一年だったなと思います。
来年はARKit 3.0が来て、オクルージョン処理機能の追加とか画像検出のための画像を動的に追加できる機能とか追加されると嬉しいなぁと思いながら、日々ARKitをいじいじして楽しんでおります。
あ、まだ間に合うので、クリスマスプレゼントとしてARKit 3.0を公開してくれてもいいんですよ、Appleさん?
あれ?返事がない。そうか、23日~27日まではお休みでしたね。
無茶言ってすみませんでした〜
以上です!
最後まで読んでいただき、ありがとうございました!