iOS
Swift
ARKit

ARKit 2.0の何が凄いのか

ARkit2_Lifestyle-room_06042018.jpg

WWDC2018で発表されたARKit2.0
今回のアップデートはなかなか凄いです。

WWDC2018で公開されている情報やAppleの公式Documentsに乗っている情報を元に僕が解釈したものを書いていきたいと思います。

(beta版のiOS12やxcode10の独自のスクリーンショットをアップするとApple Beta配信のNDA違反になってしまう可能性があるので注意していきましょう :thumbsup: )

新しいARAnchor

AREnvironmentProbeAnchor, ARObjectAnchorはARkit2.0で追加された新しいAnchor。ARAnchorクラスを継承している。

今までARPlaneAnchor(ARKit1.0から), ARFaceAnchor(ARKit1.0からiPhoneXのみ), ARImageAnchor(ARKit1.5から)などがあったが、ARKit2.0で新たな2つが追加された。

Anchorと言えば、最近のARCore1.2におけるCloud Anchorが思い出される。

ARCoreのCloud AnchorsをSwift, iOSで試してみた

CloudAnchorを利用する際は、以下のようにGARAnchorのtransformからARAnchorを生成していた。

    func session(_ session: GARSession, didResolve anchor: GARAnchor) {
        let arAnchor = ARAnchor(transform: anchor.transform)
        sceneView.session.add(anchor: arAnchor)
    }

空間をより一意に認識するために、このAnchorが欠かせない。

今回追加された2つに対する僕の理解は以下。

AREnvironmentProbeAnchor

https://developer.apple.com/documentation/arkit/arenvironmentprobeanchor

An object that provides environmental lighting information for a specific area of space in a world-tracking AR session. は直訳すると、特定環境におけるライティング情報

こちらも今回から追加された、var environmentTexture: MTLTexture? というpropertyがあって、Anchorに対するテキスチャ情報が取れる。

スクリーンショット 2018-06-10 12.35.59.png

WWDC2018のWhat’s New in ARKit 2では、テーブルの上に現実のバナナを置くことで、AR物体のりんごのバケットの環境をより正確にレンダリングできるようになったと説明している。

銀のバケットにバナナの反射が写り込んでいるのがわかるであろうか?
これがARKit1.xではできなかったこと。

engagetの記事の解説が分かりやすかったので以下に引用します。

鏡や銀食器はもちろん、車のボディやスマホの画面、磁器に至るまで、およそ光沢のあるものには、すべて「周囲の風景や色」が反射している。この反射を物体に映し込む技術を「環境マッピング」という。ゲームでいえば、メタルマリオのテカり感や、グランツーリスモの車のボディのなまめかしさだが、ARKit 1までは環境マッピングに対応していなかったので、「現実にあるものをCGの物体に反射させる」ことができなかった。これだとどうしても「合成っぽさ」が残る。

しかしARKit 2ではカメラが捉えた現実の世界の状況から、反射のための「環境マップ」がリアルタイムに生成され、物体に反映される。この写真の場合、リンゴの入った金属の食器はCGであり、バナナは実際に机の上にあるものだ。ARKit 1ではバナナの黄色は反映されないが、ARKit 2では、ぼんやりとバナナが映り込んでいる。
https://japanese.engadget.com/2018/06/08/arkit2/

ARObjectAnchor

https://developer.apple.com/documentation/arkit/arobjectanchor

物体を勝手に認識してくれて、今までのPlaneAnchorなどと同じようにAnchorを付与してくれる。これはかなりデカイ。

ARKitとVisionを使って物体認識してそこに何かを貼り付けるというサンプルを作ったことがあるが、Visionで得られる物体情報は2DのboundingBoxだったので、そこの側面を座標まで得ることはできなかった。ARObjectAnchorのおかげでかなりそれがやりやすいはず。

ARObjectAnchorには、var referenceObject: ARReferenceObject というプロパティがある(これもARKit2.0から)。次に続く。

スゴイ物体認識

ARReferenceObject

https://developer.apple.com/documentation/arkit/arreferenceobject

これがスゴイ。

center, extent, scaleというpropertyがあるので、物体を検出し、その位置や大きさなどを検出することができる。これで、実際にある物体を加工したりすることができると思う。

SnowやSnapChat, FacebookMessangerでFaceFilterができると思うが、これが物体に対してできるイメージ。

また、

init(archiveURL: URL)

というイニシャライザに注目したい。

ARReferenceObjectは .arobject という拡張子のファイルとしてアウトプットすることができ、そしてそれはアプリで使うことができる。さらに、一度アウトプットすれば、そのファイルは他のアプリでもimportして使えて物体認識に利用することができる。

スクリーンショット 2018-06-10 13.15.08.png

WWDC2018のWhat’s New in ARKit 2では、ネフェルティティの物体を認識して情報を保存し、後から再びみたときもネフェルティティが認識できた様子がデモされていた。

自分もデモアプリを使ってみたが、複数ある別の見た目のタンブラーの中から、正しいタンブラーをboundingBoxごと認識できた。

世界ごと保存!?

ARWorldMap

https://developer.apple.com/documentation/arkit/arworldmap

一度作った拡張現実情報を保存して、次にカメラを開いた時に、同じAnchorを探して、前回と同じような位置に仮想物体が出てくるように再現することができる。

ARSessionに用意された getCurrentWorldMap(completionHandler:) メソッドを使って、その時のARWorldMap が得られる。

これを以下のような感じでアーカイブできて、

func writeWorldMap(_ worldMap: ARWorldMap, to url: URL) throws {
    let data = try NSKeyedArchiver.archivedData(withRootObject: worldMap, requiringSecureCoding: true)
    try data.write(to: url)
}

以下のように、再現できる。

func loadWorldMap(from url: URL) -> ARWorldMap throws {
    let mapData = try Data(contentsOf: mapURL)
    guard let worldMap = try NSKeyedUnarchiver.unarchivedObject(of: ARWorldMap.classForKeyedUnarchiver(), from: mapData) as? ARWorldMap
        else { throw ARError.invalidWorldMap }
    return worldMap
}

ドキュメントでは,

  • Multiuser AR experiences. (複数人でのAR体験)
  • Persistent AR experiences (永続的なAR体験)

という2点のAR体験の拡張に貢献すると紹介されていて、
前者はリアルタイムに同じ場所でAR体験をするようなゲームを想起させるし、
後者は例えば公園の特定の場所に何かを保存して、後から来た人が同じ場所に来た時にそれを発見できるといった体験を想起させる。

パフォーマンス向上

ImageTracking

https://developer.apple.com/documentation/arkit/arimagetrackingconfiguration
https://developer.apple.com/documentation/arkit/arimageanchor

スクリーンショット 2018-06-10 12.49.10.png

今までは1枚ずつしか画像を検出できなかったが、今回から複数が可能になる。
そして、その認識の精度が向上し、画像が動いていても正確に追跡することができる。

スクリーンショット 2018-06-10 12.50.24.png

configurationに画像を登録してから、ARSessionをRunすることで、該当の画像を認識することができるようになる。ARIMageAnchorは自動的にSceneKitが発見してくれて、ARSessionDelegateやARSCNViewDelegateでanchorの発見をトラックできる。(これはARKit1.5からできる)

WWDC2018のWhat’s New in ARKit 2では、猫の静止画を認識し、その画像の上で動画を再生するというデモを行なっていた。

Face Detection

視線
スクリーンショット 2018-06-10 13.27.58.png スクリーンショット 2018-06-10 13.28.19.png

Gaze DetectionとTongue Detectrionが追加された。
視線と舌の認識である。

より顔の動きを正確に認識することができるようになった。

こちらは現状iPhoneXだけで使える機能。今後とも対応デバイスが増えて行くであろう。

Faster Plane Detection

平面認識なども早くなったと言われている。

いつも2、3秒はARSessionの起動にかかるので、これが短くなるのは嬉しい。

スクリーンショット 2018-06-10 13.42.14.png

まとめ

  • 実世界にある物体の検出とその保存
  • 実世界のマップ情報の保存、再現

これらは使いようによって、かなり面白いことができそうです。

仕事上、ARKit2.0は調べていくので、コードベースでも最新情報はどんどん追記していきます。

何か認識が間違っているものがあればお気軽に教えてください :bow:

公開されているサンプルコード

ARKit 2.0 参考資料

https://developer.apple.com/videos/play/wwdc2018/602
https://developer.apple.com/documentation/arkit

GRAFFITY - AR Video Chat -

スクリーンショット 2018-06-06 18.19.08.png

お仕事で、GRAFFITY - AR Video Chat -作ってます :thumbsup: