VNRequest — это абстрактный базовый класс фреймворка Vision, который представляет собой единицу анализа изображения или видеопотока. Каждый тип анализа — детекция лиц, распознавание текста, поиск штрихкодов, классификация — реализован как конкретный подкласс VNRequest. По данным Apple Developer Documentation (2024), разработчик создаёт экземпляр запроса, настраивает его параметры, передаёт изображение через VNImageRequestHandler и получает результаты в виде массива VNObservation.
Главное
VNRequest — это фундаментальный элемент архитектуры Vision, реализующий паттерн Request-Response для анализа изображений и видео. Каждый подкласс VNRequest отвечает за конкретную задачу компьютерного зрения: поиск лиц, распознавание текста, классификацию контента.
Архитектура VNRequest отделяет «что анализировать» (запрос) от «как обрабатывать» (обработчик). Разработчик конфигурирует запрос (тип анализа, дополнительные параметры), и передаёт его обработчику вместе с изображением. Обработчик выполняет запрос и возвращает результаты, не требуя от разработчика понимания внутренних алгоритмов ML.
Все подклассы VNRequest следуют единой структуре: инициализация с опциональным completion handler, настройка свойств (регион анализа, уровень точности) и передача в обработчик. Это делает API предсказуемым и легко расширяемым — добавить новый тип анализа значит создать новый подкласс VNRequest.
import Vision
// 1. Create request
let request = VNDetectFaceRectanglesRequest { req, _ in
// 3. Process results
guard let faces = req.results as? [VNFaceObservation]
else { return }
print("Found \\(faces.count) faces")
}
// 2. Execute via handler
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try handler.perform([request])
Ключевые свойства VNRequest: regionOfInterest (область интереса на изображении для ускорения анализа), preferBackgroundProcessing (фоновый режим), revision (версия алгоритма) и cancellationSupport. Правильная настройка этих свойств позволяет оптимизировать производительность под конкретную задачу.
По данным Apple WWDC 2024, за 7 лет существования Vision количество доступных подклассов VNRequest выросло с 8 (iOS 11) до 25+ (iOS 18), покрывая все основные задачи компьютерного зрения на мобильных устройствах.
Vision включает более 25 подклассов VNRequest, разделённых на категории: детекция, распознавание, трекинг и классификация. Каждый подкласс наследует VNRequest и добавляет специфичные для задачи свойства.
VNDetectFaceRectanglesRequest — поиск лиц на изображении. Возвращает VNFaceObservation с координатами bounding box и confidence. VNDetectHumanRectanglesRequest — аналогично для людей. VNDetectHumanBodyPoseRequest — определение позы человека (скелетные точки).
VNRecognizeTextRequest — распознавание текста с поддержкой 13 языков и двумя уровнями точности. VNReadCodeRequest — для специализированных кодов. VNDetectTextRectanglesRequest — поиск областей текста без распознавания (быстрее, но только прямоугольники).
VNClassifyImageRequest — классификация изображения по 1000 категориям ImageNet. VNGenerateImageFeaturePrintRequest — извлечение feature vector для сравнения изображений. VNDetectContoursRequest — выделение контуров объектов.
| Категория | Пример запроса | Результат |
|---|---|---|
| Детекция лиц | VNDetectFaceRectanglesRequest | VNFaceObservation |
| Распознавание текста | VNRecognizeTextRequest | VNRecognizedTextObservation |
| Штрихкоды | VNDetectBarcodesRequest | VNBarcodeObservation |
| Классификация | VNClassifyImageRequest | VNClassificationObservation |
| Отслеживание | VNTrackObjectRequest | VNDetectedObjectObservation |
| Контуры | VNDetectContoursRequest | VNContoursObservation |
VNImageRequestHandler — обработчик для статических изображений. Принимает CGImage, CIImage или Data (JPEG/PNG) и выполняет один или несколько VNRequest. Это основной способ использования Vision для фотографий, скриншотов и загруженных изображений.
VNSequenceRequestHandler — обработчик для последовательностей изображений (кадров видео). Принимает тот же набор типов изображений, но предназначен для покадровой обработки с сохранением состояния между кадрами (необходимо для трекинга объектов).
// VNImageRequestHandler for single image
let imageHandler = VNImageRequestHandler(
cgImage: cgImage,
orientation: orientation,
options: [:])
// VNSequenceRequestHandler for video
let sequenceHandler = VNSequenceRequestHandler()
try sequenceHandler.perform([trackingRequest],
on: cgImage)
Важное различие: VNSequenceRequestHandler не поддерживает параллельное выполнение нескольких запросов — каждый вызов perform() обрабатывает один набор запросов для одного кадра. Для многопоточной обработки видео создавайте отдельные экземпляры обработчика для разных потоков.
VNImageRequestHandler может выполняться на фоновой очереди. Apple рекомендует DispatchQueue.global(qos: .userInitiated) для интерактивных сценариев (пользователь ждёт результат) и .background для пакетной обработки (например, анализ всей фотобиблиотеки).
VNObservation — базовый класс для всех результатов запросов Vision. Каждый подкласс VNObservation содержит данные, специфичные для типа анализа: координаты bounding box, распознанный текст, уверенность (confidence), уникальный идентификатор (uuid) и временную метку (timeRange).
Ключевые подклассы VNObservation: VNFaceObservation (результат детекции лиц с bounding box и landmarks), VNRecognizedTextObservation (распознанный текст с candidates), VNBarcodeObservation (декодированный штрихкод с payload и symbology), VNClassificationObservation (категория классификации с confidence).
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 рекомендует отбрасывать наблюдения с confidence < 0.5 для большинства задач. Для критичных приложений (медицина, безопасность) порог стоит повысить до 0.8–0.9.
VNObservation также содержит timeRange (для видеозапросов) и uuid (уникальный ID для сопоставления между кадрами). Это позволяет отслеживать один и тот же объект (например, лицо) через последовательность кадров видео.
Одно из ключевых преимуществ VNRequest — возможность выполнять несколько разных запросов к одному изображению в одном вызове handler.perform(). Vision внутренне оптимизирует порядок выполнения и переиспользует общие вычисления (например, предобработку изображения).
Это позволяет получить полный набор данных об изображении за один проход: одновременно определить лица, распознать текст, найти штрихкоды и классифицировать контент. Такой подход значительно эффективнее последовательного вызова каждого запроса по отдельности.
import Vision
// Multiple requests in a single array
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
])
// Access results from each request
print("Faces: \\(faceRequest.results?.count ?? 0)")
print("Text blocks: \\(textRequest.results?.count ?? 0)")
Ограничения: не все запросы можно комбинировать с другими. Например, VNGenerateImageFeaturePrintRequest должен выполняться отдельно. Apple рекомендует группировать запросы по типу (детекция, распознавание, классификация) и тестировать комбинации на целевых устройствах.
Производительность: комбинирование 3–4 запросов в одном perform() на 30–40% быстрее последовательного выполнения, так как Vision переиспользует общие ML-вычисления и предобработку изображения (масштабирование, цветокоррекцию).
VNCoreMLRequest — это мост между Core ML и Vision, позволяющий запускать любую Core ML модель как запрос Vision. Модель оборачивается в VNCoreMLModel, передаётся в VNCoreMLRequest, и Vision автоматически обрабатывает предобработку изображения (масштабирование, crop под размер входа модели).
VNCoreMLRequest наследует VNRequest, поэтому поддерживает все стандартные возможности: regionOfInterest, completion handler, множественные запросы. Это позволяет комбинировать кастомную ML-модель со встроенными детекторами Vision в одном пайплайне.
import Vision
import CoreML
// Wrap Core ML model
guard let mlModel = try VNCoreMLModel(
for: MyCustomClassifier().model)
else { return }
// Create 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 с кастомной моделью (например, определение пола или возраста). Комбинируя два запроса в одном perform(), вы получаете полный пайплайн анализа лиц за один проход.
Часто задаваемые вопросы
Да, каждый VNRequest имеет свойство cancel(), которое отменяет выполнение запроса. Однако отмена работает только до начала обработки — если ML-модель уже запущена, отмена не прервёт вычисление. Для надёжной отмены используйте DispatchWorkItem.cancel() совместно с VNRequest.cancel() в completion handler.
VNDetectFaceRectanglesRequest находит только прямоугольники лиц. VNDetectFaceLandmarksRequest дополнительно определяет 68 ключевых точек лица (глаза, брови, нос, рот, контур). VNDetectFaceLandmarksRequest медленнее, но даёт больше данных для анимации, масок и AR-эффектов. Для простого подсчёта лиц достаточно VNDetectFaceRectanglesRequest.
Да, VNDetectBarcodesRequest — правильный запрос для любых типов штрихкодов и QR-кодов. Он поддерживает EAN, UPC, Code 39, Code 128, PDF417, Aztec, QR и другие форматы. Результат возвращается в VNBarcodeObservation с payload и symbology. Для видеопотока используйте AVCaptureMetadataOutput — он быстрее для живого сканирования.
Да, VNImageRequestHandler принимает CIImage через инициализатор init(ciImage:options:). Также поддерживаются Data (JPEG/PNG) и NSURL (путь к файлу). CIImage удобен, когда изображение уже загружено через Core Image pipeline — это избегает лишнего копирования данных в памяти.
Ограничения по количеству нет, но на практике 3–5 запросов — оптимальное количество. Больше 5 запросов могут вызвать рост потребления памяти, так как каждый запрос загружает свою ML-модель. Если нужно выполнить 10+ разных анализов, разбейте их на 2–3 группы и выполняйте последовательно.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также