VNRequest — е абстрактен базов клас на рамката Vision, който представлява единица за анализ на изображение или видео поток. Всеки тип анализ — откриване на лица, разпознаване на текст, търсене на баркодове, класификация — е имплементиран като конкретен подклас на VNRequest. Според Apple Developer Documentation (2024), разработчикът създава инстанция на заявка, конфигурира нейните параметри, предава изображението чрез VNImageRequestHandler и получава резултатите като масив от VNObservation.
Основно
VNRequest — е основен елемент на архитектурата на Vision, който имплементира модела Request-Response за анализ на изображения и видео. Всеки подклас на VNRequest е отговорен за конкретна задача на компютърното зрение: търсене на лица, разпознаване на текст, класификация на съдържание.
Архитектурата на VNRequest разделя „какво да анализираме” (заявка) от „как да обработваме” (handler). Разработчикът конфигурира заявката (тип анализ, допълнителни параметри) и я предава на handler-а заедно с изображението. Handler-ът изпълнява заявката и връща резултатите, без да изисква от разработчика да разбира вътрешните ML алгоритми.
Всички подкласове на VNRequest следват единна структура: инициализация с опционален completion handler, конфигуриране на свойства (регион за анализ, ниво на точност) и предаване на 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. Изпълнение чрез 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 — откриване на контури на обекти.
VNImageRequestHandler — handler за статични изображения. Приема CGImage, CIImage или Data (JPEG/PNG) и изпълнява една или повече VNRequest. Това е основният начин за използване на Vision за снимки, екранни прегледи и качени изображения.
VNSequenceRequestHandler — handler за последователности от изображения (кадъри на видео). Приема същия набор от видове изображения, но е предназначен за покадрова обработка с запазване на състоянието между кадърите (необходимо за проследяне на обекти).
// VNImageRequestHandler за единично изображение
let imageHandler = VNImageRequestHandler(
cgImage: cgImage,
orientation: orientation,
options: [:])
// VNSequenceRequestHandler за видео
let sequenceHandler = VNSequenceRequestHandler()
try sequenceHandler.perform([trackingRequest],
on: cgImage)
Важна разлика: VNSequenceRequestHandler не подкрепа паралелно изпълняване на няколко заявки — всяко обаждане на perform() обработва един набор заявки за един кадър. За многонишкова обработка на видео създавайте отделни инстанции на handler-а за различни нишки.
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
// Множествени заявки в един масив
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 в един pipeline.
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(), получавате пълен pipeline за анализ на лице в един преминаване.
Често задавани въпроси
Да, всяко 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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също