VNRequest はVisionフレームワークの抽象ベースクラスで、画像またはビデオストリームの解析単位を表します。各タイプの解析 — 顔検出、テキスト認識、バーコード検索、分類 — はVNRequestの具体的なサブクラスとして実装されています。Apple Developer Documentation (2024)によると、開発者はリクエストインスタンスを作成し、パラメータを構成し、VNImageRequestHandlerを通じて画像を渡し、VNObservationの配列として結果を取得します。
メインポイント
VNRequest はVisionアーキテクチャの基本要素であり、画像およびビデオ解析のためのリクエスト-レスポンスパターンを実装しています。VNRequestの各サブクラスは、コンピュータビジョンの特定のタスクを担当します: 顔検出、テキスト認識、コンテンツ分類。
VNRequestアーキテクチャは「何を解析するか」(リクエスト)と「どのように処理するか」(ハンドラ)を分離します。開発者はリクエスト(解析タイプ、追加パラメータ)を構成し、画像とともにハンドラに渡します。ハンドラはリクエストを実行し、開発者が内部MLアルゴリズムを理解する必要なく結果を返します。
VNRequestのすべてのサブクラスは、統一された構造に従います: オプションのcompletion handlerでの初期化、プロパティの構成(興味領域、精度レベル)、そしてハンドラへの渡し。これによりAPIが予測可能であり、容易に拡張できます — 新しい解析タイプを追加するには、新しいVNRequestサブクラスを作成するだけです。
import Vision
// 1. リクエストを作成
let request = VNDetectFaceRectanglesRequest { req, _ in
// 3. 結果を処理
guard let faces = req.results as? [VNFaceObservation]
else { return }
print("Found \\(faces.count) faces")
}
// 2. ハンドラを通じて実行
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try handler.perform([request])
VNRequestの主なプロパティ: regionOfInterest(解析を加速するための画像上の興味領域)、preferBackgroundProcessing(バックグラウンドモード)、revision(アルゴリズムバージョン)、cancellationSupport。これらのプロパティを適切に構成することで、特定のタスクに対してパフォーマンスを最適化できます。
Apple WWDC 2024によると、Visionの存在から7年で、利用可能なVNRequestサブクラスの数は8つ(iOS 11)から25個以上(iOS 18)に増え、モバイルデバイス上のすべての主なコンピュータビジョンタスクをカバーしています。
Visionには25個以上のVNRequestサブクラスが含まれており、検出、認識、トラッキング、分類のカテゴリに分かれています。各サブクラスはVNRequestを継承し、タスク固有のプロパティを追加します。
VNDetectFaceRectanglesRequest — 画像での顔検出。バウンディングボックス構造体構構構構構構と確信度とともにVNFaceObservationを返します。VNDetectHumanRectanglesRequest — 人についても同様。VNDetectHumanBodyPoseRequest — 人体の姿勢推定(骨格ポイント)。
VNRecognizeTextRequest — 13言語と2つの精度レベルをサポートするテキスト認識。VNReadCodeRequest — 専門コード用。VNDetectTextRectanglesRequest — 認識なしでテキスト領域を検索(高速だが、矩形のみ)。
VNClassifyImageRequest — 1,000のImageNetカテゴリへの画像分類。VNGenerateImageFeaturePrintRequest — 画像比較のための特徴ベクトル抽出。VNDetectContoursRequest — 物体の輪廓検出。
| カテゴリ | リクエスト例 | 結果 |
|---|---|---|
| 顔検出 | VNDetectFaceRectanglesRequest | VNFaceObservation |
| テキスト認識 | VNRecognizeTextRequest | VNRecognizedTextObservation |
| バーコード | VNDetectBarcodesRequest | VNBarcodeObservation |
| 分類 | VNClassifyImageRequest | VNClassificationObservation |
| トラッキング | VNTrackObjectRequest | VNDetectedObjectObservation |
| 輪廓 | VNDetectContoursRequest | VNContoursObservation |
VNImageRequestHandler — 静止画像用のハンドラ。CGImage、CIImage、Data(JPEG/PNG)を受け付け、一つまたは複数のVNRequestインスタンスを実行します。写真、スクリーンショット、アップロードされた画像にVisionを使用する主な方法です。
VNSequenceRequestHandler — 画像シーケンス(ビデオフレーム)用のハンドラ。同じ画像タイプのセットを受け付けますが、フレーム間で状態を維持しつつフレーム単位での処理のために設計されています(物体トラッキングに必要)。
// 単一画像用VNImageRequestHandler
let imageHandler = VNImageRequestHandler(
cgImage: cgImage,
orientation: orientation,
options: [:])
// ビデオ用VNSequenceRequestHandler
let sequenceHandler = VNSequenceRequestHandler()
try sequenceHandler.perform([trackingRequest],
on: cgImage)
重要な違い: VNSequenceRequestHandlerは複数のリクエストの並列実行をサポートしていません — 各perform()呼出しは1フレームに対する1セットのリクエストを処理します。マルチスレッドのビデオ処理には、スレッドごとに独立したハンドラインスタンスを作成してください。
VNImageRequestHandlerはバックグラウンドキューで実行できます。Appleは、インタラクティブなシナリオ(ユーザーが結果を待つ)にはDispatchQueue.global(qos: .userInitiated)を、バッチ処理(例:全写真ライブラリの解析)には.backgroundを推奨しています。
VNObservation — すべてのVisionリクエスト結果のベースクラス。VNObservationの各サブクラスは、解析タイプ固有のデータを含みます: バウンディングボックス構造体構構構構構構、認識されたテキスト、確信度、固有識別子(uuid)、タイムスタンプ(timeRange)。
VNObservationの主なサブクラス: VNFaceObservation(バウンディングボックスとランドマーク付きの顔検出結果)、VNRecognizedTextObservation(候補付きの認識テキスト)、VNBarcodeObservation(ペイロードとシンボロジー付きのデコードバーコード)、VNClassificationObservation(確信度付きの分類カテゴリ)。
func handleTextResults(request: VNRequest) {
guard let observations = request.results
as? [VNRecognizedTextObservation]
else { return }
for observation in observations {
let bbox = observation.boundingBox
let text = observation.topCandidates(1).first ?? ""
print("\\(text) at \\(bbox)")
}
}
confidenceプロパティ(0.0から1.0)はすべてのVNObservationインスタンスに存在し、結果に対するモデルの確信度を示します。Appleは、大部分 Nのタスクではconfidence < 0.5の観測結果を撇棄することを推奨しています。クリティカルナアプリケーション(医療、セキュリティ)では、この制限を0.8–0.9に上げるべきです。
VNObservationには、timeRange(ビデオリクエスト用)とuuid(フレーム間のマッチング用の固有ID)も含まれています。これにより、ビデオフレームのシーケンスを横断して同じ物体(例:顔)をトラッキングできます。
VNRequestの主なメリットのいとつは、単一のhandler.perform()呼出しで同じ画像に対して複数の異なるリクエストを実行できることです。Visionは内部的に実行順序を最適化し、共通の計算(例:画像プリプロセシング)を再利用します。
これにより、1回の処理で画像についての完全なデータセットを得られます: 顔を同時に検出し、テキストを認識し、バーコードを見つけ、コンテンツを分類します。このアプローチは、各リクエストを順番に呼ぶよりも大幅に効率的です。
import Vision
// 配列での複数リクエスト
let faceRequest = VNDetectFaceRectanglesRequest()
let textRequest = VNRecognizeTextRequest()
let barcodeRequest = VNDetectBarcodesRequest()
let classifyRequest = VNClassifyImageRequest()
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try handler.perform([
faceRequest,
textRequest,
barcodeRequest,
classifyRequest
])
// 各リクエストから結果にアクセス
print("Faces: \\(faceRequest.results?.count ?? 0)")
print("Text blocks: \\(textRequest.results?.count ?? 0)")
制約: すべてのリクエストを他のリクエストと組み合わせられるわけではありません。例えば、VNGenerateImageFeaturePrintRequestは単独で実行する必要があります。Appleは、タイプ(検出、認識、分類)ごとにリクエストをグループ化し、ターゲットデバイスで組み合わせをテストすることを推奨しています。
パフォーマンス: Visionが共有のML計算と画像プリプロセシング(スケーリング、色校正)を再利用するため、1つのperform()で3–4つのリクエストを組み合わせると、順番実行より30–40%高速になります。
VNCoreMLRequestはCore MLとVisionの間のブリッジであり、任意のCore MLモデルをVisionリクエストとして実行できます。モデルはVNCoreMLModelにラップされ、VNCoreMLRequestに渡され、Visionが自動的に画像プリプロセシング(スケーリング、モデル入力サイズへのクロップ)を処理します。
VNCoreMLRequestはVNRequestを継承するため、すべての標準機能をサポートします: regionOfInterest、completion handler、複数リクエスト。これにより、カスタムMLモデルを組み込みのVision検出器と単一のパイプラインで組み合わせられます。
import Vision
import CoreML
// Core MLモデルをラップ
guard let mlModel = try VNCoreMLModel(
for: MyCustomClassifier().model)
else { return }
// VNCoreMLRequestを作成
let coreMLRequest = VNCoreMLRequest(model: mlModel) { request, _ in
guard let results = request.results
as? [VNClassificationObservation]
else { return }
for result in results.prefix(5) {
print("\\(result.identifier): \\(result.confidence)"
}
}
coreMLRequest.imageCropAndScaleOption = .centerCrop
coreMLRequest.regionOfInterest = faceBoundingBox
imageCropAndScaleOptionは、Visionがモデル入力に合わせて画像をどのようにスケーリングするかを決定します: .centerCrop(中央クロッピング)、.scaleFill(伸縮)、.scaleFit(アスペクト比を維持したスケーリング)。選択はモデルのタイプと画像上の物体の位置に依存します。
実践例: VNDetectFaceRectanglesRequestによる顔検出、その後カスタムモデル(例:性別や年齢推定)を使ったVNCoreMLRequestによる各顔の分類。1つのperform()で複数のリクエストを組み合わせることで、1回の処理で完全な顔解析パイプラインを得られます。
よくある質問
はい、各VNRequestにはリクエストの実行をキャンセルするcancel()プロパティがあります。ただし、キャンセルは処理開始前にのみ効果があります — MLモデルがすでに始動している場合、キャンセルで計算を中断できません。信頼性のあるキャンセルには、completion handler内でDispatchWorkItem.cancel()をVNRequest.cancel()と組み合わせて使用します。
VNDetectFaceRectanglesRequestは顔のバウンディング矩形のみを検出します。VNDetectFaceLandmarksRequestはさらに68の顔部関倣ポイント(目、眉毛、鼻、口、輪廓)を特定します。VNDetectFaceLandmarksRequestは速度は遅いが、アニメーション、マスク、AR効果のためにより多くのデータを提供します。簡単な顔のカウントには、VNDetectFaceRectanglesRequestで十分です。
はい、VNDetectBarcodesRequestはすべてのタイプのバーコードとQRコードに対する正しいリクエストです。EAN、UPC、Code 39、Code 128、PDF417、Aztec、QR、その他のフォーマットをサポートしています。結果は、ペイロードとシンボロジー付きのVNBarcodeObservationで返されます。ビデオストリームには、AVCaptureMetadataOutputを使用してください — ライブスキャンにはこちらのほうが高速です。
はい、VNImageRequestHandlerはinit(ciImage:options:)イニシャライザを通じてCIImageを受け付けます。Data(JPEG/PNG)やNSURL(ファイルパス)もサポートしています。CIImageは、画像がすでにCore Imageパイプラインを通じて読み込まれている場合に便利です — メモリ上での不要なデータコピーを避けられます。
個数に制限はありませんが、実際には3–5個のリクエストが最適です。5個を超えると、各リクエストが独自のMLモデルをロードするため、メモリ消費が増加する可能性があります。10個以上の異なる解析を実行する必要がある場合は、2–3のグループに分けて順番実行してください。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。