ハイライト
Vision は Apple のコンピュータビジョンフレームワーク。顔検出、文字認識、人体ポーズ推定、バーコードスキャンなど 31 種類の画像分析リクエストを提供。今年 Apple は Swift ネイティブ API でフレームワークを再設計。async/await、throws、Swift 6 厳密並行性チェックをサポート(01:09)。
主要内容
Vision フレームワークは Apple プラットフォームでのコンピュータビジョンの定番ツール。顔と顔特徴点(目、鼻、口)を検出。18 言語の文字認識(韓国語、スウェーデン語、中国語を含む)。人体ポーズと手の軌跡を追跡(00:24)。
旧 API には明確な問題——Objective-C ベースの completion handler 設計が Swift の現代 async パターンと相容れない。コードはネストコールバックと NSError 処理で溢れ、Swift 6 並行安全性チェック非対応(11:13)。
今年 Apple は Vision の Swift API を完全書き換え。核心ルール 3 つ:VN プレフィックス除去、completion handler 除去、async/await でコールバック置換。結果——コード量 10 行から 6 行へ。型安全、並行安全(12:11)。
API 近代化に加え、2 つの長年の痛点を解決:正規化座標変換(新 toImageCoordinates() API)、複数リクエスト同時実行時のストリーミング結果処理(performAll が AsyncStream を返す)(05:37、08:22)。
さらに 2 つの新機能:画像美学スコアリング(CalculateImageAestheticsScoresRequest、写真品質と memorable 度を評価)、holistic body pose(DetectHumanBodyPoseRequest で detectsHands = true を設定し、身体と手のポーズを同時検出)(14:51、15:21)。
詳細
Vision の核心概念は単純:画像に質問(request)し、答え(observation)を得る。フレームワークは 31 種類のリクエストタイプを提供——画像分類、文字認識、バーコード検出、人体ポーズ推定など(02:59)。
基本用法:バーコードスキャン
新 API の極簡スタイル——3 行:
// ([04:06](https://developer.apple.com/videos/play/wwdc2024/10163/?time=246))
let request = DetectBarcodesRequest()
let barcodeObservations = try await request.perform(on: image)
// barcodeObservations には検出された各バーコードが含まれる
- 1 行目:リクエスト作成。VN プレフィックス不要
- 2 行目:
try awaitで実行。結果直接返却。completion handler 不要 - 3 行目:observation 処理。各 observation が 1 つの検出バーコード
性能向上のためバーコードタイプ指定(EAN-13 のみなど):
// ([06:38](https://developer.apple.com/videos/play/wwdc2024/10163/?time=398))
request.symbologies = [.ean13]
座標変換
Vision の座標系は正規化(0〜1)。原点は左下。SwiftUI の原点は左上。新 API は toImageCoordinates() を提供:
// ([05:42](https://developer.apple.com/videos/play/wwdc2024/10163/?time=342))
let boundingBox = observation.boundingBox
let convertedBox = boundingBox.toImageCoordinates(
imageSize: image.size,
origin: .upperLeft
)
boundingBox:Vision が返す正規化座標ボックスimageSize:元画像サイズorigin:出力座標原点。upperLeftは SwiftUI 等に適合
バッチリクエスト:一括実行
複数リクエスト同時実行(バーコードと文字など)は ImageRequestHandler:
// ([07:36](https://developer.apple.com/videos/play/wwdc2024/10163/?time=456))
let handler = ImageRequestHandler(image: image)
let (barcodeResults, textResults) = try await handler.perform(
DetectBarcodesRequest(),
RecognizeTextRequest()
)
ImageRequestHandler:画像コンテナ。バッチリクエスト実行perform:parameter pack 構文。任意数のリクエストを渡せる- 戻り値:リクエストごとに 1 結果。tuple でアンパック
バッチリクエスト:ストリーミング
上記方法は全リクエスト完了を待つ。各完了時に即処理する場合は performAll:
// ([08:44](https://developer.apple.com/videos/play/wwdc2024/10163/?time=524))
let handler = ImageRequestHandler(image: image)
for await result in try await handler.performAll(
DetectBarcodesRequest(),
RecognizeTextRequest()
) {
switch result {
case .barcode(let observations):
// バーコード検出が完了したらすぐに処理
handleBarcodes(observations)
case .text(let observations):
// テキスト認識が完了したらすぐに処理
handleText(observations)
}
}
performAll:AsyncStream を返す。各リクエスト完了時に結果をプッシュfor await:Swift Concurrency 標準ストリーム処理構文switch:結果タイプで分岐
並行最適化:複数画像処理
大量画像処理時は TaskGroup で並行実行。ただしメモリ制御のため並行数制限:
// ([10:18](https://developer.apple.com/videos/play/wwdc2024/10163/?time=618))
await withTaskGroup(of: Void.self) { group in
var imageIterator = images.makeIterator()
var activeTasks = 0
let maxConcurrency = 5
while activeTasks < maxConcurrency, let nextImage = imageIterator.next() {
group.addTask {
await generateThumbnail(from: nextImage)
activeTasks -= 1
}
activeTasks += 1
}
}
withTaskGroup:Swift Concurrency タスクグループmaxConcurrency:同時実行タスク数制限。Vision は約 5 を推奨——メモリ使用量削減addTask:並行タスク追加。各タスクが 1 画像を処理
旧コード移行
3 ステップ移行法:
// 古い API
// ([12:32](https://developer.apple.com/videos/play/wwdc2024/10163/?time=752))
let handler = VNImageRequestHandler(image: image)
let request = VNDetectBarcodesRequest()
request completionHandler = { request, error in
guard let observations = request.results else { return }
// 結果を処理
}
try handler.perform([request])
// 新しい API
let request = DetectBarcodesRequest()
let observations = try await request.perform(on: image)
// 結果を処理
- ステップ 1:VN プレフィックス除去(
VNDetectBarcodesRequest→DetectBarcodesRequest) - ステップ 2:completion handler 除去。
async/await使用 - ステップ 3:
VNImageRequestHandler除去。request.perform(on:)を直接使用
画像美学スコアリング
新 API で画像品質評価:
// ([14:54](https://developer.apple.com/videos/play/wwdc2024/10163/?time=894))
let request = CalculateImageAestheticsScoresRequest()
let observation = try await request.perform(on: image)
print(observation.overallScore) // -1 から 1、値が高いほど良い
print(observation.isUtility) // true はユーティリティ画像(スクリーンショット、領収書など)を示す
overallScore:総合品質スコア。-1 〜 1isUtility:ユーティリティ画像か(技術的には問題ないが共有価値低い)
Holistic Body Pose
身体と手のポーズを同時検出:
// ([15:38](https://developer.apple.com/videos/play/wwdc2024/10163/?time=938))
let request = DetectHumanBodyPoseRequest()
request.detectsHands = true
let observation = try await request.perform(on: image)
print(observation.leftHandObservation) // 左手のポーズ
print(observation.rightHandObservation) // 右手のポーズ
detectsHands:true で返却 observation に手データを含むleftHandObservation/rightHandObservation:左右手ポーズ情報の新プロパティ
重要ポイント
-
1. 新 API へ移行:新プロジェクトは新 API を直接使用。旧プロジェクトは段階的移行。最も一般的なリクエスト(
DetectBarcodesRequest、RecognizeTextRequest)から。3 ステップ——プレフィックス除去、handler 除去、async/await 追加。コード削減、型安全、Swift 6 厳密並行性チェック対応。 -
2.
toImageCoordinates()で手動計算を置換:Vision の正規化座標系(左下原点)は SwiftUI(左上原点)等と不一致が多い。新座標変換 API で手動計算エラーを排除。origin: .upperLeftで大部分 UI フレームワークに適合。 -
3. 複数リクエストシナリオで
performAll使用:複数 Vision リクエスト同時実行(バーコードと文字など)時はperformAllで AsyncStream。全完了を待たず各結果を即処理。UX 向上——バーコード検出即表示、文字認識完了を待たない。 -
4. 並行数制限でメモリ制御:大量画像処理時は TaskGroup で並行実行。ただし並行数制限(約 5 推奨)。Vision リクエストはメモリ消費大——並行制限でメモリピークによるシステム負荷を防止。
-
5. 画像美学スコアリングでアルバム最適化:
CalculateImageAestheticsScoresRequestでユーザーフォトライブラリを評価——低品質写真(ぼけ、露出問題)自動フィルタ、ユーティリティ画像(スクリーンショット、レシート)識別。「厳選集」機能で memorable な写真のみ表示。
関連セッション
- Bring your machine learning and AI models to Apple silicon — ML モデルを最適化して Apple silicon 算力を活用
- Deploy machine learning and AI models on-device with Core ML — 端末 ML モデルデプロイ時の速度・メモリ最適化の新手法
- Build a great Lock Screen camera capture experience — Lock Screen Camera Capture API でロック画面からカメラキャプチャ
- What’s new in Create ML — Create ML 更新。visionOS オブジェクト追跡モデルテンプレートを含む
コメント
GitHub Issues · utterances