夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

Apple CreateMLとは? ObjectTrackingの実装を

本日はAI、Apple枠です。

先日はCreateMLを使用していきました。

 CreateMLはAppleが提供する機械学習モデル(ML)を作成可能なツールです。

 MacOS上、正確にはXCodeに付随するDeveloperToolsに含まれる機能として提供されており、WindowsOS環境下では動かすことができません。

 特徴としてプログラミングの知識が無くてもGUIを通してデータをトレーニング、モデルの作成が可能です。

 CreateMLを通してテキスト、画像、音声、オブジェクト検出など様々なモデルの作成をサポートしています。

 また前述の通り、XCodeのパッケージの一部として提供されていることから、アプリケーション開発にシームレスに統合することができます。

 実はCreateMLはMicrosoftAzureのように従量課金制のサービスだと筆者は思い込んでいました。

 ローカル環境で動作します。

〇環境

Mac mini (M2)

 ・MacOS(15)

 ・XCode(16.0)

〇ObjectTrackingのサンプルコード

先日はCreateMLで.referenceobjectファイルの作成までを見ていきました。

redhologerbera.hatenablog.com

 今回はXCode上でこのファイルをどのように使用していくのかを見ていきます。

ObjectTrackingのサンプルコードはWWDC24のビデオページに記載されています。

https://developer.apple.com/videos/play/wwdc2024/10101/

 このコードではSwiftUIとRealityKitを使用してUSDZファイルを表示します。

// Display object USDZ
struct ImmersiveView: View {
   @State var globeAnchor: Entity? = nil
    var body: some View {
        RealityView { content in
            // Load the reference object with ARKit API
            let refObjURL = 
            Bundle.main.url(forResource: "globe", withExtension: ".referenceobject")
            let refObject = try? await ReferenceObject(from: refObjURL!)

            // Load the model entity with USDZ path extracted from reference object
            let globePreviewEntity = 
            try? await Entity.init(contentsOf: (refObject?.usdzFile)!)

            // Set opacity to 0.5 and add to scene
            globePreviewEntity!.components.set(OpacityComponent(opacity: 0.5))
            content.add(globePreviewEntity!)
        }
    }
}

ImmersiveViewはVisionOSのSwiftで没入型体験を実装する構造体です。

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

次のブロックがステータスです。

 ここではObjectTrackingのアンカーのステータスを確認しています。

// Check anchor state
struct ImmersiveView: View {
   @State var globeAnchor: Entity? = nil
    var body: some View {
        RealityView { content in
            if let scene = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
                globeAnchor = scene.findEntity(named: "GlobeAnchor")
                content.add(scene)
            }
            let updateSub = content.subscribe(to: SceneEvents.AnchoredStateChanged.self) { event in
                if let anchor = globeAnchor, event.anchor == anchor {
                    if event.isAnchored {
                        // Object anchor found, trigger transition animation
                    } else {
                        // Object anchor not found, display coaching UI
                    }
                }
            }
        }
    }
}

ここではSceneEvents.AnchoredStateChanged:でアンカーの状態が変わったときにイベントを受け取ります。

                    if event.isAnchored {
                        // Object anchor found, trigger transition animation
                    }

で、アンカーを発見した際のイベントを定義します。

最後のコードはトラッキングセッションを処理するビューを定義しています。

struct ImmersiveView: View {
   @State var globeAnchor: Entity? = nil
    var body: some View {
        RealityView { content in
            // Setup anchor transform space for object and world anchor
            let trackingSession = SpatialTrackingSession()
            let config = SpatialTrackingSession.Configuration(tracking: [.object, .world])
            if let result = await trackingSession.run(config) {
                if result.anchor.contains(.object) {
                    // Tracking not authorized, adjust experience accordingly
                }
            }
           // Get tracked object's world transform, identity if tracking not authorized
            let objectTransform = globeAnchor?.transformMatrix(relativeTo: nil)
            // Implement animation
            ...
        }
    }
}

〇サンプルプロジェクト

筆者はSwiftはそこまで詳しくないのですが、いかにVisionOSでのサンプルプロジェクトを公開している方がいたので次回はこちらを使用していきます。

https://github.com/dilmerv/VisionOSObjectTrackingDemo