VNRequest — co to jest, architektura żądań Vision w iOS

Autor: IT Sectr Opublikowano: 2026-07-20 Czas czytania: 8 min

VNRequest — to abstrakcyjna klasa bazowa frameworku Vision, która reprezentuje jednostkę analizy obrazu lub strumienia wideo. Każdy typ analizy — wykrywanie twarzy, rozpoznawanie tekstu, wyszukiwanie kodów kreskowych, klasyfikacja — jest zaimplementowany jako konkretna podklasa VNRequest. Według Apple Developer Documentation (2024), programista tworzy instancję żądania, konfiguruje jego parametry, przekazuje obraz przez VNImageRequestHandler i otrzymuje wyniki w postaci tablicy VNObservation.

Najważniejsze

  • VNRequest — klasa bazowa dla wszystkich żądań Vision: analizy obrazów, wideo i modeli ML.
  • Żądanie jest wykonywane przez VNImageRequestHandler (obraz) lub VNSequenceRequestHandler (wideo).
  • Wyniki są zwracane w postaci tablicy VNObservation — każda podklasa zawiera specyficzne dane.
  • Completion handler umożliwia asynchroniczne przetwarzanie wyników po zakończeniu analizy.
  • Kilka żądań można wykonać jednym wywołaniem handler.perform() dla jednego obrazu.

Czym jest VNRequest w Vision?

VNRequest — to fundamentalny element architektury Vision, implementujący wzorzec Request-Response do analizy obrazów i wideo. Każda podklasa VNRequest odpowiada za konkretne zadanie wizji komputerowej: wyszukiwanie twarzy, rozpoznawanie tekstu, klasyfikację treści.

Architektura VNRequest oddziela „co analizować” (żądanie) od „jak przetwarzać” (handler). Programista konfiguruje żądanie (typ analizy, dodatkowe parametry) i przekazuje je do handlera wraz z obrazem. Handler wykonuje żądanie i zwraca wyniki, nie wymagając od programisty znajomości wewnętrznych algorytmów ML.

Wszystkie podklasy VNRequest mają jednolitą strukturę: inicjalizacja z opcjonalnym completion handler, konfiguracja właściwości (region analizy, poziom dokładności) i przekazanie do handlera. To sprawia, że API jest przewidywalne i łatwo rozszerzalne — dodanie nowego typu analizy oznacza utworzenie nowej podklasy VNRequest.

swift
import Vision

// 1. Utwórz żądanie
let request = VNDetectFaceRectanglesRequest { req, _ in
    // 3. Przetwarzaj wyniki
    guard let faces = req.results as? [VNFaceObservation]
    else { return }
    print("Found \\(faces.count) faces")
}

// 2. Wykonaj przez handler
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try handler.perform([request])

Kluczowe właściwości VNRequest: regionOfInterest (obszar zainteresowania na obrazie w celu przyspieszenia analizy), preferBackgroundProcessing (tryb tła), revision (wersja algorytmu) i cancellationSupport. Prawidłowa konfiguracja tych właściwości pozwala zoptymalizować wydajność pod konkretne zadanie.

Według Apple WWDC 2024, przez 7 lat istnienia Vision liczba dostępnych podklas VNRequest wzrosła z 8 (iOS 11) do ponad 25 (iOS 18), pokrywając wszystkie główne zadania wizji komputerowej na urządzeniach mobilnych.

Główne typy VNRequest do analizy

Vision zawiera ponad 25 podklas VNRequest, podzielonych na kategorie: detekcja, rozpoznawanie, śledzenie i klasyfikacja. Każda podklasa dziedziczy VNRequest i dodaje właściwości specyficzne dla zadania.

Detekcja i rozpoznawanie

VNDetectFaceRectanglesRequest — wyszukiwanie twarzy na obrazie. Zwraca VNFaceObservation z współrzędnymi bounding box i confidence. VNDetectHumanRectanglesRequest — analogicznie dla ludzi. VNDetectHumanBodyPoseRequest — określanie pozy człowieka (punkty szkieletowe).

Analiza tekstu

VNRecognizeTextRequest — rozpoznawanie tekstu z obsługą 13 języków i dwoma poziomami dokładności. VNReadCodeRequest — dla wyspecjalizowanych kodów. VNDetectTextRectanglesRequest — wyszukiwanie obszarów tekstu bez rozpoznawania (szybsze, ale tylko prostokąty).

Klasyfikacja i analiza

VNClassifyImageRequest — klasyfikacja obrazu według 1000 kategorii ImageNet. VNGenerateImageFeaturePrintRequest — ekstrakcja wektora cech do porównywania obrazów. VNDetectContoursRequest — wykrywanie konturów obiektów.

KategoriaPrzykład żądaniaWynik
Detekcja twarzyVNDetectFaceRectanglesRequestVNFaceObservation
Rozpoznawanie tekstuVNRecognizeTextRequestVNRecognizedTextObservation
Kody kreskoweVNDetectBarcodesRequestVNBarcodeObservation
KlasyfikacjaVNClassifyImageRequestVNClassificationObservation
ŚledzenieVNTrackObjectRequestVNDetectedObjectObservation
KonturyVNDetectContoursRequestVNContoursObservation

VNImageRequestHandler i VNSequenceRequestHandler

VNImageRequestHandler — handler dla statycznych obrazów. Przyjmuje CGImage, CIImage lub Data (JPEG/PNG) i wykonuje jeden lub wiele VNRequest. Jest to podstawowy sposób korzystania z Vision dla zdjęć, zrzutów ekranu i przesłanych obrazów.

VNSequenceRequestHandler — handler dla sekwencji obrazów (klatek wideo). Przyjmuje ten sam zestaw typów obrazów, ale jest przeznaczony do przetwarzania klatka po klatce z zachowaniem stanu między klatkami (niezbędne do śledzenia obiektów).

swift
// VNImageRequestHandler dla pojedynczego obrazu
let imageHandler = VNImageRequestHandler(
    cgImage: cgImage,
    orientation: orientation,
    options: [:])

// VNSequenceRequestHandler dla wideo
let sequenceHandler = VNSequenceRequestHandler()
try sequenceHandler.perform([trackingRequest],
    on: cgImage)

Ważna różnica: VNSequenceRequestHandler nie obsługuje równoległego wykonywania wielu żądań — każde wywołanie perform() przetwarza jeden zestaw żądań dla jednej klatki. Do wielowątkowego przetwarzania wideo twórz osobne instancje handlera dla różnych wątków.

VNImageRequestHandler może być wykonywany w kolejce tła. Apple zaleca DispatchQueue.global(qos: .userInitiated) dla scenariuszy interaktywnych (użytkownik czeka na wynik) i .background dla przetwarzania wsadowego (np. analiza całej biblioteki zdjęć).

VNObservation: struktura wyników

VNObservation — klasa bazowa dla wszystkich wyników zapytań Vision. Każda podklasa VNObservation zawiera dane specyficzne dla typu analizy: współrzędne bounding box, rozpoznany tekst, pewność (confidence), unikalny identyfikator (uuid) i znacznik czasu (timeRange).

Kluczowe podklasy VNObservation: VNFaceObservation (wynik detekcji twarzy z bounding box i landmarks), VNRecognizedTextObservation (rozpoznany tekst z candidates), VNBarcodeObservation (zdekodowany kod kreskowy z payload i symbology), VNClassificationObservation (kategoria klasyfikacji z confidence).

swift
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)")
    }
}

Właściwość confidence (od 0.0 do 1.0) występuje we wszystkich VNObservation i pokazuje pewność modelu co do wyniku. Apple zaleca odrzucanie obserwacji z confidence < 0.5 dla większości zadań. Dla krytycznych aplikacji (medycyna, bezpieczeństwo) próg należy podnieść do 0.8–0.9.

VNObservation zawiera również timeRange (dla żądań wideo) i uuid (unikalny ID do dopasowywania między klatkami). Pozwala to śledzić ten sam obiekt (np. twarz) przez sekwencję klatek wideo.

Wykonywanie wielu żądań jednocześnie

Jedna z kluczowych zalet VNRequest — możliwość wykonywania kilku różnych żądań do jednego obrazu w jednym wywołaniu handler.perform(). Vision wewnętrznie optymalizuje kolejność wykonywania i współdzieli wspólne obliczenia (np. wstępne przetwarzanie obrazu).

Pozwala to uzyskać pełny zestaw danych o obrazie w jednym przebiegu: jednocześnie wykryć twarze, rozpoznać tekst, znaleźć kody kreskowe i sklasyfikować treść. Takie podejście jest znacznie wydajniejsze niż sekwencyjne wywoływanie każdego żądania osobno.

swift
import Vision

// Wiele żądań w jednej tablicy
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
])

// Dostęp do wyników z każdego żądania
print("Faces: \\(faceRequest.results?.count ?? 0)")
print("Text blocks: \\(textRequest.results?.count ?? 0)")

Ograniczenia: nie wszystkie żądania można łączyć z innymi. Na przykład VNGenerateImageFeaturePrintRequest musi być wykonywany osobno. Apple zaleca grupowanie żądań według typu (detekcja, rozpoznawanie, klasyfikacja) i testowanie kombinacji na docelowych urządzeniach.

Wydajność: łączenie 3–4 żądań w jednym perform() jest o 30–40% szybsze niż sekwencyjne wykonanie, ponieważ Vision współdzieli wspólne obliczenia ML i wstępne przetwarzanie obrazu (skalowanie, korekcję kolorów).

Niestandardowe żądania z VNCoreMLRequest

VNCoreMLRequest — to most między Core ML a Vision, umożliwiający uruchamianie dowolnego modelu Core ML jako żądania Vision. Model jest opakowywany w VNCoreMLModel, przekazywany do VNCoreMLRequest, a Vision automatycznie przetwarza wstępnie obraz (skalowanie, crop do rozmiaru wejścia modelu).

VNCoreMLRequest dziedziczy VNRequest, więc obsługuje wszystkie standardowe funkcje: regionOfInterest, completion handler, wiele żądań. Pozwala to łączyć niestandardowy model ML z wbudowanymi detektorami Vision w jednym pipeline.

swift
import Vision
import CoreML

// Opakuj model Core ML
guard let mlModel = try VNCoreMLModel(
    for: MyCustomClassifier().model)
else { return }

// Utwórz 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 określa, jak Vision skaluje obraz do wejścia modelu: .centerCrop (przycięcie od środka), .scaleFill (rozciągnięcie) lub .scaleFit (skalowanie z zachowaniem proporcji). Wybór zależy od typu modelu i położenia obiektu na obrazie.

Praktyczny przykład: wykrywanie twarzy przez VNDetectFaceRectanglesRequest, następnie klasyfikacja każdej twarzy przez VNCoreMLRequest z niestandardowym modelem (np. określanie płci lub wieku). Łącząc dwa żądania w jednym perform(), otrzymujesz pełny pipeline analizy twarzy w jednym przebiegu.

Często zadawane pytania

Czy można anulować wykonywane VNRequest?

Tak, każde VNRequest ma właściwość cancel(), która anuluje wykonanie żądania. Jednak anulowanie działa tylko do momentu rozpoczęcia przetwarzania — jeśli model ML został już uruchomiony, anulowanie nie przerwie obliczeń. Do niezawodnego anulowania używaj DispatchWorkItem.cancel() razem z VNRequest.cancel() w completion handler.

VNDetectFaceRectanglesRequest i VNDetectFaceLandmarksRequest — jaka jest różnica?

VNDetectFaceRectanglesRequest znajduje tylko prostokąty twarzy. VNDetectFaceLandmarksRequest dodatkowo określa 68 kluczowych punktów twarzy (oczy, brwi, nos, usta, kontur). VNDetectFaceLandmarksRequest jest wolniejszy, ale dostarcza więcej danych do animacji, masek i efektów AR. Do prostego liczenia twarzy wystarczy VNDetectFaceRectanglesRequest.

Krórego requesta użyć do wyszukiwania kodów kreskowych — VNDetectBarcodesRequest?

Tak, VNDetectBarcodesRequest — to właściwe żądanie dla wszystkich typów kodów kreskowych i QR. Obsługuje EAN, UPC, Code 39, Code 128, PDF417, Aztec, QR i inne formaty. Wynik jest zwracany w VNBarcodeObservation z payload i symbology. Dla strumienia wideo używaj AVCaptureMetadataOutput — jest szybszy do skanowania na żywo.

Czy można wykonać VNRequest na CIImage zamiast na CGImage?

Tak, VNImageRequestHandler przyjmuje CIImage przez inicjalizator init(ciImage:options:). Obsługiwane są również Data (JPEG/PNG) i NSURL (ścieżka do pliku). CIImage jest wygodny, gdy obraz został już załadowany przez Core Image pipeline — pozwala to uniknąć niepotrzebnego kopiowania danych w pamięci.

Ile VNRequest można wykonać w jednym perform()?

Nie ma ograniczenia co do liczby, ale w praktyce 3–5 żądań to optymalna ilość. Więcej niż 5 żądań może spowodować wzrost zużycia pamięci, ponieważ każde żądanie ładuje swój model ML. Jeśli potrzebujesz wykonać 10+ różnych analiz, podziel je na 2–3 grupy i wykonuj sekwencyjnie.

Podsumowanie

  • VNRequest — klasa bazowa Vision dla wszystkich typów analizy obrazów i wideo z jednolitą architekturą Request-Response.
  • Vision zawiera ponad 25 podklas VNRequest do wykrywania twarzy, OCR, kodów kreskowych, klasyfikacji, konturów, śledzenia i modeli ML.
  • VNImageRequestHandler wykonuje żądania na statycznych obrazach; VNSequenceRequestHandler — na sekwencjach klatek do śledzenia.
  • Wyniki są zwracane w postaci VNObservation z bounding box, confidence, uuid i danymi specyficznymi dla typu.
  • Wiele żądań w jednym perform() działa 30–40% szybciej niż sekwencyjne wywołania dzięki współdzieleniu obliczeń ML.
  • VNCoreMLRequest integruje niestandardowe modele Core ML z pipeline Vision z automatycznym wstępnym przetwarzaniem obrazów.
  • Wszystkie żądania są wykonywane na urządzeniu bez wysyłania danych na serwer, zapewniając prywatność i pracę offline.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również