iPhone12ProのLiDARスキャナを試してみる

# はじめに
これは[NTTテクノクロス Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ntt-tx)の19日目の記事です．

こんにちは．NTTテクノクロスの大貫です．

私は普段，業務でiOS/iPadOS関連の仕事をしているのですが，私生活でもApple信者で家の中はApple製品で溢れています．
今年は10月からAppleの新製品ラッシュでAppleWatch, HomePod mini, iPhone12シリーズにm1搭載MacBook, 12/18に発売されたばかりのAirPods Maxと情報を追うのが忙しい日々でした．
それにしてもAirPods Maxは強気な値段設定ですね．この記事を書いている時点では発売されておらず，試聴できていませんが音質が気になるところです．

そんな新製品ラッシュでしたが，私はiPhone12 Proを購入しました．
無印12と12 Proの主な違いはカメラが２つか３つかになりますが，それに加えてLiDARスキャナの有無があります．

本記事ではiPhone12 ProのLiDARスキャナが何に使えるのか，サンプルプログラムを動かしながら確認してみます．
私もこの記事の執筆に当たって初めて触ってみたため，技術的に深い部分はありませんが，概要だけでもお伝えできればと思います．

# 想定する読者
* Xcodeの基本的な操作を理解されている方
* ARアプリを作成したことがない方

# LiDARスキャナとは
そもそもLiDARスキャナとは2020年3月に発売されたiPad Proで初めて搭載された深度(距離)センサーになります．
iPhoneでは12 Pro/12 Pro Maxで初めて搭載されました．

技術的な詳細は専門の記事にお任せするとして，簡単に言えば赤外線のドットを照射し，その反射波から３次元的な空間データを取得するセンサーになっています．
つまりその空間に存在する物体を３次元的に取得できるセンサーになります．

３次元的な空間データは主にARアプリなどで利用されており，これまでは複数のカメラによる差分やAIによる推定によって取得されていました．
それがこのLiDARスキャナ搭載によって，より高精度なデータを取得できるようになったということになります．
これによってiOSでは夜間のカメラ撮影時のオートフォーカスの精度向上などが図られているようです．

# まずは簡単なARアプリを作ってみる
センサーの概要が分かったところで，まずは手始めに簡単なARアプリを作ってみます．
といっても，作り方は簡単でXcodeでスケルトンアプリを作成するだけです．

### 1.プロジェクトの作成
Xcodeで新規プロジェクトを作成し，テンプレートの選択で「Augmented Reality App」を選択します．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/d2ce72ae-9cf1-10d0-0f5d-c78f3b817ad8.png" width=800px>
あとはいつも通りそのままプロジェクトを作成すればARアプリの完成です．

### 2.アプリの起動
早速動かしてみましょう．

そのまま何も変更せずにアプリを実行し，起動してみます．
※プロビジョニングプロファイルなどの設定は別途実施してください．
最初はアプリを起動するとカメラの使用許可が出ますので許可してあげます．

起動するとカメラの画像が表示されますので，机や床などの平面が映るようにします．
すると認識した平面に黒色のキューブが表示されます．その状態で端末を動かしても，しっかりと位置を認識してその場に存在しているように表示されます．
簡単ですね．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/16c563d6-1fba-8894-2d4e-1811d90c0574.png" width=400px>

### 3.ちょっとだけ修正してみる
先ほど画面に表示された黒色のキューブは「Experience.rcproject」で定義されており，右上の「Open in Reality Composer」から編集も可能です．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/d8d70b9b-b5c9-ae73-0bb7-febbc55e076e.png" width=800px>
試しに素材をゴールドにしてサイズも変更してみました．
配置したいオブジェクトのデータさえ用意してあげれば,このままでもそこそこ使えそうですね．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/769106cd-20ff-5dc7-53d4-013846064789.png" width=800px>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/e42547f3-cb9d-2d6c-48c8-53eb37fd18ca.png" width=400px>
（なんだかお金持ちになれそうです）

もう少し設定を追加してみます．
初期状態だとキューブは平面上に固定されますが，単純に画像に重ね合わせただけでキューブの手前に現実世界の物体があってもキューブが手前に描画されてしまいます．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/a639f685-18ad-6454-c098-5f3681974ea9.png" width=400px>
これでは３次元感がないので，手前の物体にキューブが隠れるようにします．（オクルージョンの有効化）
設定は簡単で以下の１行をViewControllerのviewDidLoadに追記してオプションを設定してあげます．

```
arView.environment.sceneUnderstanding.options.insert(.occlusion)
```

先ほどと同じように手前に物体を配置してみると，それに隠れるように表示されます．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/21c5d6f0-fa6d-a7b2-352b-2fe3bb64bcf3.png" width=400px>　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/97c7a28b-e136-6779-44e1-04535bc4b055.png" width=400px>
2枚目のように曲線や複雑な形状の場合，境界の判定は完璧とは言えませんが，それっぽくなっているのではないでしょうか．

ついでに認識している物体のメッシュ表示を設定してみます．
先ほどと同じようにViewControllerのviewDidLoadに１行デバッグオプション追加します．

```
arView.debugOptions.insert(.showSceneUnderstanding)
```

実行してみるとiPhoneがどのように物体を認識しているのか画面上で確認することができます．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/859c362d-8661-f285-dfc1-bc44cc11cc75.png" width=400px>
このサンプルを元に配置する物体のデータを入れ替えることができるようにすれば，仮想的に家具を家に配置するアプリなどが作成できそうです．
その他にも物理演算の有効化などいろいろな[オプション](https://developer.apple.com/jp/documentation/arkit/world_tracking/visualizing_and_interacting_with_a_reconstructed_scene/)が設定できるようなので，試してみると面白そうです．

<details><summary>最終的なViewControllerの全文はこちら</summary><div>

```swift
import UIKit
import RealityKit

class ViewController: UIViewController {
    
    @IBOutlet var arView: ARView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // オクルージョンを有効化する
        arView.environment.sceneUnderstanding.options.insert(.occlusion)

        // メッシュを表示する
        arView.debugOptions.insert(.showSceneUnderstanding)
        
        // Load the "Box" scene from the "Experience" Reality File
        let boxAnchor = try! Experience.loadBox()
        
        // Add the box anchor to the scene
        arView.scene.anchors.append(boxAnchor)
    }
}
```
</div></details>


# そのほかのサンプルも動かしてみる
上記アプリはいわゆるARアプリでしたが，もう少し応用的なアプリを見てみましょう．
といっても私もまだ勉強中のため，Apple公式のサンプルアプリを動かしてみます．

## ３次元データの取得
まずは３次元データを取得するサンプルになります．
サンプルは[こちら](https://developer.apple.com/documentation/arkit/visualizing_a_point_cloud_using_scene_depth)からダウンロードして実行してみます．

このサンプルプログラムは周囲の物体の距離と色を認識し，ドットとして仮想空間上にプロットする物になります．
同じような画角で撮影してみましたが，なんとなく物体を捉えているのがわかるかと思います．
ちなみに物体の最大認識距離は3〜5mといったところでした．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/bbf4e345-3c87-c6f1-6cf3-20d25e83f16e.jpeg" width=800px>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/b1664ee5-bce2-c47f-262c-db470c8f543b.png" width=800px>
処理の中身については全然把握できていないのですが，LiDARスキャナからの深度データは画面内で捉えているカメラ画像に対して深度(距離)のマップとその信頼度のマップで返却されるようです．
こちらのサンプルではそのデータを元に仮想空間上にドットとして認識結果を表示しています．
中央のLow-Medium-Highはプロットするドットの信頼度の変更になります．MediumやHighに設定するとそれよりも信頼度の低いデータはプロットしなくなります．
また，スライダーではカメラ画像を透過表示することができます．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/3aeb0e2b-f7ce-c158-35aa-31002707b7bc.png" width=800px>

## カメラ画像に霧をかける
次に応用的なアプリとして，距離に応じて霧をかけるサンプルを動かしてみます．
こちらも同じくApple公式の[こちら](https://developer.apple.com/documentation/arkit/creating_a_fog_effect_using_scene_depth)からダウンロードすることができます．

実行すると距離の遠い場所は霧（灰色のもや）が濃くなり，近い場所は薄くなります．
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905850/147d0226-2d37-d8b9-f818-40dbc49d9cf8.png" width=800px>
こちらもセンサーから取得した深度データを元にカメラ画像に対してもやをかける画像処理を行っています．

# 終わりに
今回はLiDARスキャナを利用したアプリ開発の初歩の初歩を勉強してみました．
キューブを配置するARアプリなどは簡単に作成でき，物体のデータさえ用意できれば割と実用的なアプリが作成できそうでした．
LiDARスキャナからのデータを取得し利用するアプリについてはサンプルを動かしてみましたが，処理内容についてはまだまだ理解できていないところが多いので，今後も勉強していこうと思います．

本記事が少しでもお役に立てれば幸いです．

明日は@uehajさんになります．
引き続き[NTTテクノクロス Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ntt-tx)をお楽しみください！