動かして学ぶDockKit入門

2.3K Views

August 27, 24

スライド概要

iOSDC2024のトーク資料になります。

profile-image

iOS・wacthOS アプリエンジニアです。 App : apps.apple.com/jp/app/mycam-pro/id1540711931

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

動かして学ぶDockKit入門 iOSDC Japan 2024 day0 - Track C 19:20 ~ Naoya Maeda

2.

DockKitについて話します

3.

自己紹介 • 前田 直哉 • 株式会社タイミー / iOS エンジニア • タイミーを使っていただいているワーカー様の「働く前」・「働 いた後」の体験が向上する機能の開発

4.

• 技術発信 • Zenn、noteでiOS / watchOSに関する技術記事を発信 • 個人開発アプリ • カメラアプリを3つリリース中

5.

アジェンダ • DockKitについて • 実装 • まとめ

6.

本トークで話さないこと • AVFoundationのAVCapture APIについて • Core ML, Visionについて

7.

DockKitについて

8.

DockKit • DockKit対応デバイスをコン トロール • 2023年の9月にリリース • iOS 17から使用可能 引用元:[Belkin公式サイト]Auto-Tracking Stand Pro with DockKit https://www.belkin.com/jp/p/auto-tracking-stand-pro-with-dockkit/MMA008qc05BK.html

9.

DockKit対応デバイスについて

10.

Auto-Tracking Stand Pro with DockKit (Belkin) • 2024年3月に発売 • 世界で初めてDockKitに対応 したデバイス • 人の顔と体を自動でトラッキ ング • iOS 18で追加された一部の APIは非対応 引用元:[Belkin公式サイト]Auto-Tracking Stand Pro with DockKit https://www.belkin.com/jp/p/auto-tracking-stand-pro-with-dockkit/MMA008qc05BK.html

11.

Insta360 Flow Pro (Insta360) • 2024年7月に発売 • 人の顔と体を自動でトラッ キング • DockKit全てのAPIに対応 • ホイール / ボタン 引用元:[Insta360公式サイト]insta360- ow-pro fl fl https://www.insta360.com/jp/product/insta360- ow-pro

12.

似たようなデバイスってたくさん あるんじゃないの?

13.

DockKit対応デバイスの強み

14.

DockKit対応デバイスの強み • 専用アプリは不要 • ビデオ撮影機能を搭載しているアプリはDockKitアクセサリに対 応

15.

DockKit対応デバイスの強み • 専用アプリは不要 • ビデオ撮影機能を搭載しているアプリはDockKitアクセサリに対 応 • 他のフレームワークとの相性が良好 • Vision, Core ML, AVFoundation…

16.

実装

17.

顔・体のトラッキング

18.

実装は不要!

19.

AVCapture APIとDockKitが連携している • AVCapture APIを使用してビデオ撮影機能を実装すればOK

20.

AVCapture APIとDockKitが連携している • AVCapture APIを使用してビデオ撮影機能を実装すればOK

21.

AVCapture APIとDockKitが連携している • AVCapture APIを使用してビデオ撮影機能を実装すればOK

22.

デモ

23.

カスタムコントロール

24.

DockAccessory iOS 17 • DockKit対応デバイスを表すクラス • 主要な役割 • ハードウェア情報を提供 • 動きをカスタマイズするためのメソッドやプロパティを提供

25.

被写体の表示位置変更 • デフォルトは中央寄せで表示 • 組み込みモードは4種類 • 左寄せ / 右寄せ / 中央寄せ / 自動 • 座標とサイズを指定して表示領域を指定することも可能 iOS 17

26.

• func setFramingMode(̲ mode: DockAccessory.FramingMode) • enum FramingMode (automatic, center, left, right) switch framingType { case .auto: try await dockAccessory.setFramingMode(.automatic) case .left: try await dockAccessory.setFramingMode(.left) case .center: try await dockAccessory.setFramingMode(.center) case .right: try await dockAccessory.setFramingMode(.right) }

27.

• func setRegionOfInterest(̲ region: CGRect) let roi = CGRect(x: 0.0, y: 50.0, width: 1.0, height: 0.46) do { if let dockAccessory { try await dockAccessory.setRegionOfInterest(roi) } } catch { print(error.localizedDescription) }

28.

デモ

29.

カスタムトラッキング • 顔・体以外をトラッキング • Vision、Core MLとの連携 • Observationを利用 iOS 17

30.

Observation • 検出した物体の情報 • DockKitに渡すことでトラッ キング対象を決定

31.

Observation • 検出した物体の情報 • DockKitに渡すことでトラッ キング対象を決定

32.

Observation • 独自に生成したObservation をDockKitに渡すことでトラ ッキング対象をカスタマイズ • Vision, Core ML

33.

• VNImageRequestHandler • 画像解析リクエストを処理 let handler = VNImageRequestHandler(cmSampleBuffer: sampleBuffer, orientation: .up, options: [:]) try handler.perform([handPoseRequest]) guard let observation = handPoseRequest.results?.first as? VNHumanHandPoseObservation else { return } let indexFingerTip = try observation.recognizedPoints(.indexFinger)[.indexMCP] if let indexFingerTip { let rect = CGRect(x: indexFingerTip.x, y: indexFingerTip.y, width: 0.4, height: 0.4) let dockAccessoryObservation = DockAccessory.Observation(identifier: 1, type: .object, rect: rect) do { let cameraInfo = DockAccessory.CameraInformation(captureDevice: .builtInWideAngleCamera, cameraPosition: .front, orientation: .corrected, cameraIntrinsics: nil, referenceDimensions: nil) try await dockAccessory.track([dockAccessoryObservation], cameraInformation: cameraInfo) } catch { print(error.localizedDescription) } }

34.

• DockAccessory.Observation • 被写体の情報 let handler = VNImageRequestHandler(cmSampleBuffer: sampleBuffer, orientation: .up, options: [:]) try handler.perform([handPoseRequest]) guard let observation = handPoseRequest.results?.first as? VNHumanHandPoseObservation else { return } let indexFingerTip = try observation.recognizedPoints(.indexFinger)[.indexMCP] if let indexFingerTip { let rect = CGRect(x: indexFingerTip.x, y: indexFingerTip.y, width: 0.4, height: 0.4) let dockAccessoryObservation = DockAccessory.Observation(identifier: 1, type: .object, rect: rect) do { let cameraInfo = DockAccessory.CameraInformation(captureDevice: .builtInWideAngleCamera, cameraPosition: .front, orientation: .corrected, cameraIntrinsics: nil, referenceDimensions: nil) try await dockAccessory.track([dockAccessoryObservation], cameraInformation: cameraInfo) } catch { print(error.localizedDescription) } }

35.

• DockAccessory.CameraInformation • 使用しているカメラデバイスの情報 let handler = VNImageRequestHandler(cmSampleBuffer: sampleBuffer, orientation: .up, options: [:]) try handler.perform([handPoseRequest]) guard let observation = handPoseRequest.results?.first as? VNHumanHandPoseObservation else { return } let indexFingerTip = try observation.recognizedPoints(.indexFinger)[.indexMCP] if let indexFingerTip { let rect = CGRect(x: indexFingerTip.x, y: indexFingerTip.y, width: 0.4, height: 0.4) let dockAccessoryObservation = DockAccessory.Observation(identifier: 1, type: .object, rect: rect) do { let cameraInfo = DockAccessory.CameraInformation(captureDevice: .builtInWideAngleCamera, cameraPosition: .front, orientation: .corrected, cameraIntrinsics: nil, referenceDimensions: nil) try await dockAccessory.track([dockAccessoryObservation], cameraInformation: cameraInfo) } catch { print(error.localizedDescription) } }

36.

• func track(̲ data: [DockAccessory.Observation], cameraInformation: DockAccessory.CameraInformation • 被写体の追跡処理 let handler = VNImageRequestHandler(cmSampleBuffer: sampleBuffer, orientation: .up, options: [:]) try handler.perform([handPoseRequest]) guard let observation = handPoseRequest.results?.first as? VNHumanHandPoseObservation else { return } let indexFingerTip = try observation.recognizedPoints(.indexFinger)[.indexMCP] if let indexFingerTip { let rect = CGRect(x: indexFingerTip.x, y: indexFingerTip.y, width: 0.4, height: 0.4) let dockAccessoryObservation = DockAccessory.Observation(identifier: 1, type: .object, rect: rect) do { let cameraInfo = DockAccessory.CameraInformation(captureDevice: .builtInWideAngleCamera, cameraPosition: .front, orientation: .corrected, cameraIntrinsics: nil, referenceDimensions: nil) try await dockAccessory.track([dockAccessoryObservation], cameraInformation: cameraInfo) } catch { print(error.localizedDescription) } }

37.

デモ

38.

iOS 18 ボタンコントロール • ジンバルに搭載されているボ タン、ホイールの回転イベン トを取得可能 • 2024/8/22時点では Insta360 Flow Proのみ対応 引用元:[Insta360公式サイト]insta360- ow-pro fl fl https://www.insta360.com/jp/product/insta360- ow-pro

39.

デモ

40.

被写体の識別 • ビデオフレーム内の被写体を識別 • 被写体の特徴を取得 • 顕著性ランク • カメラ目線スコア • 発話確信スコア iOS 18

41.

デモ

42.

まとめ • ビデオキャプチャ機能を実装すれば自動トラッキングを使用可能 • 豊富なカスタムコントロール • 他のフレームワークとの相性も良い • iOS 18からはよりインテリジェンスな被写体識別が可能

43.

ご静聴ありがとうございました