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, за 7 років існування Vision кількість доступних підкласів VNRequest зросла з 8 (iOS 11) до 25+ (iOS 18), охоплюючи всі основні завдання комп’ютерного зору на мобільних пристроях.
Vision включає понад 25 підкласів VNRequest, розділених на категорії: виявлення, розпізнавання, відстеження та класифікація. Кожен підклас успадковує VNRequest та додає властивості, специфічні для завдання.
VNDetectFaceRectanglesRequest — пошук облич на зображенні. Повертає VNFaceObservation з координатами bounding box та конфіденційністю. VNDetectHumanRectanglesRequest — аналогічно для людей. VNDetectHumanBodyPoseRequest — визначення пози людини (скелетні точки).
VNRecognizeTextRequest — розпізнавання тексту з підтримкою 13 мов та двома рівнями точності. VNReadCodeRequest — для спеціалізованих кодів. VNDetectTextRectanglesRequest — пошук областей тексту без розпізнавання (швидше, але лише прямокутники).
VNClassifyImageRequest — класифікація зображення за 1000 категоріями 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() обробляє один набір запитів для одного кадра. Для багатопотокової обробки відео створюйте окремі екземпляри обробника для різних потоків.
VNImageRequestHandler може виконуватися в фоновій черзі. Apple рекомендує DispatchQueue.global(qos: .userInitiated) для інтерактивних сценаріїв (користувач чекає на результат) та .background для пакетної обробки (наприклад, аналіз всієї фототеки).
VNObservation — базовий клас для всіх результатів запитів Vision. Кожен підклас VNObservation містить дані, специфічні для типу аналізу: координати bounding box, розпізнаний текст, конфіденційність, унікальний ідентифікатор (uuid) та часова мітка (timeRange).
Ключові підкласи VNObservation: VNFaceObservation (результат виявлення обличчя з bounding box та ландмарками), VNRecognizedTextObservation (розпізнаний текст з кандидатами), VNBarcodeObservation (декодований штрихкод з payload та symbology), 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 рекомендує відкидати спостереження з confidence < 0.5 для більшості завдань. Для критичних застосунків (медицина, безпека) поріг варто підвищити до 0.8–0.9.
VNObservation також містить timeRange (для відеозапитів) та uuid (унікальний ID для зіставлення між кадрами). Це дозволяє відстежувати одного й того ж об’єкта (наприклад, обличчя) через послідовність кадрів відео.
Одна з ключових переваг VNRequest — можливість виконувати кілька різних запитів до одного зображення одним викликом handler.perform(). Vision внутрішньо оптимізує порядок виконання та перевикористовує спільні обчислення (наприклад, попередню обробку зображення).
Це дозволяє отримати повний набір даних про зображення за один прохід: одночасно виявити обличчя, розпізнати текст, знайти штрихкоди та класифікувати вміст. Такий підхід значно ефективніший за послідовний виклик кожного запиту окремо.
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 рекомендує групувати запити за типом (виявлення, розпізнавання, класифікація) та тестувати комбінації на цільових пристроях.
Продуктивність: комбінування 3–4 запитів в одному perform() на 30–40% швидше за послідовне виконання, оскільки Vision перевикористовує спільні ML-обчислення та попередню обробку зображення (масштабування, кольорова корекція).
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 з кастомною моделлю (наприклад, визначення статі або віку). Комбінуючи два запити в одному 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 — це уникає зайвого копіювання даних в пам’яті.
Обмежень за кількістю немає, але на практиці 3–5 запитів — оптимальна кількість. Більше 5 запитів можуть викликати зростання споживання пам’яті, оскільки кожен запит завантажує свою ML-модель. Якщо потрібно виконати 10+ різних аналізів, розбийте їх на 2–3 групи та виконуйте послідовно.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також