iOS
Swift
ARKit

ARKit 2.0の何が凄いのか

ARkit2_Lifestyle-room_06042018.jpg

WWDC2018で発表されたARKit2.0

WWDCでのビデオからの情報やAppleの公式Documentsに載っている情報を元に書いていきます。

追記
iOS12がリリースされたので、サンプルコードを作りました! 👇👇👇
サンプルコードを作ってわかったことを元に本記事も加筆訂正を加えています。

kboy-silvergym/ARKit-Emperor

新しい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から)。次に続く。

スゴイ物体認識

物体をスキャン それを認識
GIF image-8C238A00CA21-1.gif GIF image-A27D4DEE9665-1.gif

ARReferenceObject

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

これがスゴイ。

center, extent, scaleというpropertyがあるので、物体を検出し、その位置や大きさなどを検出することができる。(現状事前にその物体のcenter, extent, scaleは作成時に手動で定義しておく必要がある)

これで、実際にある物体を加工したりすることができると思う。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) {
    let mapData = try Data(contentsOf: mapURL)
    guard let worldMap = try? NSKeyedUnarchiver.unarchivedObject(of: ARWorldMap.classForKeyedUnarchiver(), from: mapData) as? ARWorldMap
        else { throw ARError.invalidWorldMap }

    let configuration = ARWorldTrackingConfiguration()
    configuration.planeDetection = .horizontal
    configuration.initialWorldMap = worldMap
    sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
}

ARWorldTrackingConfigurationのinitialWorldMapにセットしてsessionを起動すると、共有元の座標系と同じになるので、複数のデバイスで繋いでゲームするようなときに実装しやすそう。

例えばARCoreのCloud AnchorでもAnchorを共有することができて同じ場所に物を置く実装を容易に実現できるが、それだけでは座標系は一致していないので何らかの方法で座標系を合わせる必要がある。その証拠にGoogleが出しているJust A Lineのアプリでは、「2つのデバイスの位置を合わせてください」というメッセージが出てきている。同じ座標系にするのを簡単にするためだ。

just a line

ちなみにJust a lineのiOSのコードはgithubに公開されているのだが、ここではsetWorldOrigin(relativeTransform:)というメソッドを使って2つのデバイスの座標系を一致させている。

AppleのドキュメントではこのARWorldMapについて、

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

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

筆者の印象としては、iOS12のデバイスどうしで空間共有体験を実現するためにはARWorldMapを使うのがベストだ。もちろん世界の点群情報が集まったARCloudが提供される未来がくればそちらの方が良いかもしれない。

パフォーマンス向上

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からARImageAnchorは使うことができるが、ARImageTrackingConfiguration がARKit2.0から。今まではARWorldTrackingConfigurationを使って同様なことができていたが、新しいconfigulationは画像が動いていても追跡できるという点でパフォーマンスが向上している。その代わりこのconfigulationだと平面認識などができない。

堤さんのブログのARKit 2.0の画像トラッキングとARKit 1.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:

こちらもチェック