スクリーンショット_2018-08-27_22

ARKit1.5との戯れ

2018年の1月頃、どうやらARKitが画像認識なども含めバージョンアップがされていたみたいです。^ - ^
ちょっと今回はARKitとの戯れ日記をつけていこうと思います!

ARkit1.5の追加機能内容

・壁など垂直面の検出ができ、さらにトラッキングにも対応
・画像認識
・イレギュラーな平面形状の認識改善
・映像の解像度が50%以上向上、オートフォーカスにも対応
といった機能追加や強化が含まれています。

以前でも画像認識をすることができたみたいですが、遠回りしてios11から入ってきた、Visonっていうフレームワークも使用して、実装をしていたみたいですが、今回のバージョンアップで簡単にすることができたので、そのコードを備忘録がわりに書いていこうと思います。

画像認識対象画像の登録方法

Assets.xcassetsファイルを開け、プラスボタンをクリックすると上記のメニューが開きます。その中から「New AR Resource Group」を選択します。

そうすると、「AR Resources」というフォルダができますので、それをクリックして選択をすると、ドラッグアンドドロップで画像を入れることができます!

ただしここでの注意点

画像をただ、入れただけでは黄色の注意みたいなのが出てしまい、そのままRunをすると、アプリがエラーを出して、止まってしまいます。
ですので、その画像の実際の大きさも登録する必要があります。

実際の画像の大きさ登録

先ほど、登録をした画像を選択してあげ、下記の図のように実物の大きさを登録してください!

そうすると、注意が消えます^ ^

初期化

デフォルトで、宇宙船が表示されると思います。ですので、「viewWillAppear」の中身を下記の通り消してあげてください!

let scene = SCNScene()

そうすると、宇宙船は表示されなくなります。

画像認識をする処理の準備を行います!

let configuration = ARWorldTrackingConfiguration()
// ARリソースをよびだす
        guard let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else {
            fatalError("Missing expected asset catalog resources.")
        }
// ARリソースを認識用画像として設定する
        configuration.detectionImages = referenceImages

上記のコードを補足説明をしておきます。
ARReferenceImage.referenceImagesで認識する画像を取得して、その画像をreferenceImages変数に入れてあげています。
もし、取得できなかった場合は、その中「fatalError」メソッドが実行され、アプリがクラッシュします。これはデバッグ用のメソッドですので、特に気にしないでいただけたらと思います。

その下で、取得した画像をセットしてあげます!
一様、viewWillAppearの全体コードです。

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // Create a session configuration
        let configuration = ARWorldTrackingConfiguration()
        // ARリソースをよびだす
        guard let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else {
            fatalError("Missing expected asset catalog resources.")
        }
        
        
        // ARリソースを認識用画像として設定する
        configuration.detectionImages = referenceImages

        // Run the view's session
        sceneView.session.run(configuration)
    }

画像を認識してから呼び出されるメソッド

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {}
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {}

上記のメソッドはとてもよく似ているんですが、最初に画像を認識て呼び出されるメソッドは「didAdd」です。そして、認識してカメラなどを動かすと、状況が異なるので、そのときに「didUpdate」メソッドが走ります。

ですので、画像を認識して何かキャラクターなどを表示させるのはdidAddということですね!

それではまずは全体コードから。

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
        // 宇宙船の素材を取得
let chara = SCNScene(named: "art.scnassets/ship.scn")!

                  // charaのノードを取得、これで宇宙船のノードを取得できる
                let charaNode = chara.rootNode.childNodes[0]
                // 宇宙船が表示される位置情報
                let position = SCNVector3(x: 0, y: 0, z: -0.5) // 偏差のベクトルを生成する
                if let camera = self.sceneView.pointOfView { // カメラを取得
                    charaNode.position = camera.convertPosition(position, to: nil) // カメラ位置からの偏差で求めた位置をノードの位置とする
                // nodeをシーンに追加する
                self.sceneView.scene.rootNode.addChildNode(charaNode)
    }

以上で、登録をしている画像をカメラで認識させると、宇宙船が表示されました!!

この記事が気に入ったらサポートをしてみませんか?