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)
}
以上で、登録をしている画像をカメラで認識させると、宇宙船が表示されました!!
この記事が気に入ったらサポートをしてみませんか?