VNRequest là một lớp cơ sở trừu tượng của framework Vision, đại diện cho một đơn vị phân tích hình ảnh hoặc luồng video. Mỗi loại phân tích — phát hiện khuôn mặt, nhận dạng văn bản, tìm kiếm mã vạch, phân loại — được triển khai dưới dạng một lớp con cụ thể của VNRequest. Theo Tài liệu Nhà phát triển Apple (2024), nhà phát triển tạo một thể hiện yêu cầu, cấu hình các tham số của nó, truyền hình ảnh qua VNImageRequestHandler và nhận kết quả dưới dạng mảng VNObservation.
Điểm Chính
VNRequest là một phần tử cơ bản của kiến trúc Vision, triển khai mô hình Yêu cầu-Phản hồi cho phân tích hình ảnh và video. Mỗi lớp con của VNRequest chịu trách nhiệm cho một tác vụ thị giác máy tính cụ thể: phát hiện khuôn mặt, nhận dạng văn bản, phân loại nội dung.
Kiến trúc VNRequest tách biệt “phân tích gì” (yêu cầu) khỏi “cách xử lý” (trình xử lý). Nhà phát triển cấu hình yêu cầu (loại phân tích, tham số bổ sung) và truyền nó cho trình xử lý cùng với hình ảnh. Trình xử lý thực hiện yêu cầu và trả về kết quả mà không yêu cầu nhà phát triển hiểu các thuật toán ML bên trong.
Tất cả các lớp con của VNRequest tuân theo một cấu trúc thống nhất: khởi tạo với completion handler tùy chọn, cấu hình thuộc tính (vùng quan tâm, mức độ chính xác) và truyền cho trình xử lý. Điều này làm cho API có thể dự đoán được và dễ dàng mở rộng — thêm một loại phân tích mới có nghĩa là tạo một lớp con VNRequest mới.
import Vision
// 1. Tạo yêu cầu
let request = VNDetectFaceRectanglesRequest { req, _ in
// 3. Xử lý kết quả
guard let faces = req.results as? [VNFaceObservation]
else { return }
print("Found \\(faces.count) faces")
}
// 2. Thực hiện qua trình xử lý
let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try handler.perform([request])
Các thuộc tính chính của VNRequest: regionOfInterest (vùng quan tâm trên hình ảnh để tăng tốc phân tích), preferBackgroundProcessing (chế độ nền), revision (phiên bản thuật toán) và cancellationSupport. Việc cấu hình phù hợp các thuộc tính này cho phép tối ưu hiệu suất cho một tác vụ cụ thể.
Theo Apple WWDC 2024, sau 7 năm tồn tại của Vision, số lượng lớp con VNRequest có sẵn đã tăng từ 8 (iOS 11) lên hơn 25 (iOS 18), bao phủ tất cả các tác vụ thị giác máy tính chính trên thiết bị di động.
Vision bao gồm hơn 25 lớp con VNRequest được chia thành các danh mục: phát hiện, nhận dạng, theo dõi và phân loại. Mỗi lớp con kế thừa VNRequest và thêm các thuộc tính cụ thể cho tác vụ.
VNDetectFaceRectanglesRequest — phát hiện khuôn mặt trong hình ảnh. Trả về VNFaceObservation với tọa độ bounding box và độ tin cậy. VNDetectHumanRectanglesRequest — tương tự cho người. VNDetectHumanBodyPoseRequest — ước tính tư thế cơ thể người (các điểm xương).
VNRecognizeTextRequest — nhận dạng văn bản hỗ trợ 13 ngôn ngữ và hai mức độ chính xác. VNReadCodeRequest — cho các mã chuyên dụng. VNDetectTextRectanglesRequest — tìm kiếm vùng văn bản mà không nhận dạng (nhanh hơn, nhưng chỉ hình chữ nhật).
VNClassifyImageRequest — phân loại hình ảnh theo 1.000 danh mục ImageNet. VNGenerateImageFeaturePrintRequest — trích xuất vector đặc trưng để so sánh hình ảnh. VNDetectContoursRequest — phát hiện đường viền đối tượng.
| Danh mục | Ví dụ Yêu cầu | Kết quả |
|---|---|---|
| Phát hiện Khuôn mặt | VNDetectFaceRectanglesRequest | VNFaceObservation |
| Nhận dạng Văn bản | VNRecognizeTextRequest | VNRecognizedTextObservation |
| Mã vạch | VNDetectBarcodesRequest | VNBarcodeObservation |
| Phân loại | VNClassifyImageRequest | VNClassificationObservation |
| Theo dõi | VNTrackObjectRequest | VNDetectedObjectObservation |
| Đường viền | VNDetectContoursRequest | VNContoursObservation |
VNImageRequestHandler — trình xử lý cho hình ảnh tĩnh. Nó chấp nhận CGImage, CIImage hoặc Data (JPEG/PNG) và thực hiện một hoặc nhiều thể hiện VNRequest. Đây là cách chính để sử dụng Vision cho ảnh, ảnh chụp màn hình và hình ảnh được tải lên.
VNSequenceRequestHandler — trình xử lý cho chuỗi hình ảnh (khung hình video). Nó chấp nhận cùng tập hợp các loại hình ảnh nhưng được thiết kế để xử lý từng khung hình trong khi duy trì trạng thái giữa các khung hình (cần thiết cho việc theo dõi đối tượng).
// VNImageRequestHandler cho hình ảnh đơn
let imageHandler = VNImageRequestHandler(
cgImage: cgImage,
orientation: orientation,
options: [:])
// VNSequenceRequestHandler cho video
let sequenceHandler = VNSequenceRequestHandler()
try sequenceHandler.perform([trackingRequest],
on: cgImage)
Sự khác biệt quan trọng: VNSequenceRequestHandler không hỗ trợ thực hiện song song nhiều yêu cầu — mỗi lần gọi perform() xử lý một tập hợp yêu cầu cho một khung hình. Để xử lý video đa luồng, hãy tạo các thể hiện trình xử lý riêng biệt cho các luồng khác nhau.
VNImageRequestHandler có thể chạy trên hàng đợi nền. Apple khuyến nghị sử dụng DispatchQueue.global(qos: .userInitiated) cho các tình huống tương tác (người dùng chờ kết quả) và .background cho xử lý hàng loạt (ví dụ: phân tích toàn bộ thư viện ảnh).
VNObservation — lớp cơ sở cho tất cả kết quả yêu cầu Vision. Mỗi lớp con của VNObservation chứa dữ liệu cụ thể cho loại phân tích: tọa độ bounding box, văn bản được nhận dạng, độ tin cậy, định danh duy nhất (uuid) và dấu thời gian (timeRange).
Các lớp con chính của VNObservation: VNFaceObservation (kết quả phát hiện khuôn mặt với bounding box và điểm mốc), VNRecognizedTextObservation (văn bản được nhận dạng với các ứng cử viên), VNBarcodeObservation (mã vạch được giải mã với payload và symbology), VNClassificationObservation (danh mục phân loại với độ tin cậy).
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)")
}
}
Thuộc tính confidence (từ 0.0 đến 1.0) hiện diện trong tất cả các thể hiện VNObservation và cho biết độ tin cậy của mô hình về kết quả. Apple khuyến nghị loại bỏ các quan sát có confidence < 0.5 đối với hầu hết các tác vụ. Đối với các ứng dụng quan trọng (y tế, bảo mật), ngưỡng nên được nâng lên 0.8–0.9.
VNObservation cũng chứa timeRange (cho yêu cầu video) và uuid (ID duy nhất để khớp giữa các khung hình). Điều này cho phép theo dõi cùng một đối tượng (ví dụ: khuôn mặt) qua một chuỗi các khung hình video.
Một trong những lợi thế chính của VNRequest là khả năng thực hiện nhiều yêu cầu khác nhau trên cùng một hình ảnh trong một lần gọi handler.perform(). Vision tối ưu hóa thứ tự thực hiện nội bộ và tái sử dụng các tính toán chung (ví dụ: tiền xử lý hình ảnh).
Điều này cho phép thu được một tập hợp dữ liệu đầy đủ về một hình ảnh trong một lần: phát hiện khuôn mặt đồng thời, nhận dạng văn bản, tìm mã vạch và phân loại nội dung. Cách tiếp cận này hiệu quả hơn đáng kể so với việc gọi từng yêu cầu một tuần tự.
import Vision
// Nhiều yêu cầu trong một mảng
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
])
// Truy cập kết quả từ mỗi yêu cầu
print("Faces: \\(faceRequest.results?.count ?? 0)")
print("Text blocks: \\(textRequest.results?.count ?? 0)")
Giới hạn: không phải tất cả các yêu cầu đều có thể kết hợp với các yêu cầu khác. Ví dụ, VNGenerateImageFeaturePrintRequest phải được thực hiện riêng. Apple khuyến nghị nhóm các yêu cầu theo loại (phát hiện, nhận dạng, phân loại) và kiểm tra các kết hợp trên các thiết bị mục tiêu.
Hiệu suất: kết hợp 3–4 yêu cầu trong một perform() nhanh hơn 30–40% so với thực hiện tuần tự vì Vision tái sử dụng các tính toán ML dùng chung và tiền xử lý hình ảnh (thay đổi kích thước, hiệu chỉnh màu sắc).
VNCoreMLRequest là cầu nối giữa Core ML và Vision, cho phép chạy bất kỳ mô hình Core ML nào dưới dạng yêu cầu Vision. Mô hình được bao bọc trong VNCoreMLModel, truyền đến VNCoreMLRequest và Vision tự động xử lý tiền xử lý hình ảnh (thay đổi kích thước, cắt theo kích thước đầu vào của mô hình).
VNCoreMLRequest kế thừa VNRequest, do đó hỗ trợ tất cả các tính năng tiêu chuẩn: regionOfInterest, completion handler, nhiều yêu cầu. Điều này cho phép kết hợp mô hình ML tùy chỉnh với các bộ phát hiện tích hợp sẵn của Vision trong một đường ống duy nhất.
import Vision
import CoreML
// Bao bọc mô hình Core ML
guard let mlModel = try VNCoreMLModel(
for: MyCustomClassifier().model)
else { return }
// Tạo 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 xác định cách Vision thay đổi kích thước hình ảnh cho đầu vào mô hình: .centerCrop (cắt trung tâm), .scaleFill (kéo giãn) hoặc .scaleFit (thay đổi kích thước giữ nguyên tỷ lệ). Sự lựa chọn phụ thuộc vào loại mô hình và vị trí của đối tượng trong hình ảnh.
Ví dụ thực tế: phát hiện khuôn mặt qua VNDetectFaceRectanglesRequest, sau đó phân loại từng khuôn mặt qua VNCoreMLRequest với mô hình tùy chỉnh (ví dụ: ước tính giới tính hoặc tuổi). Bằng cách kết hợp hai yêu cầu trong một perform(), bạn có được một đường ống phân tích khuôn mặt hoàn chỉnh trong một lần.
Các Câu hỏi Thường Gặp
Có, mỗi VNRequest có thuộc tính cancel() để hủy thực hiện yêu cầu. Tuy nhiên, việc hủy chỉ hoạt động trước khi bắt đầu xử lý — nếu mô hình ML đã được khởi động, việc hủy sẽ không làm gián đoạn tính toán. Để hủy đáng tin cậy, hãy sử dụng DispatchWorkItem.cancel() kết hợp với VNRequest.cancel() trong completion handler.
VNDetectFaceRectanglesRequest chỉ tìm hình chữ nhật bao quanh khuôn mặt. VNDetectFaceLandmarksRequest xác định thêm 68 điểm mốc chính trên khuôn mặt (mắt, lông mày, mũi, miệng, đường viền). VNDetectFaceLandmarksRequest chậm hơn nhưng cung cấp nhiều dữ liệu hơn cho hoạt ảnh, mặt nạ và hiệu ứng AR. Để đếm khuôn mặt đơn giản, VNDetectFaceRectanglesRequest là đủ.
Có, VNDetectBarcodesRequest là yêu cầu chính xác cho tất cả các loại mã vạch và mã QR. Nó hỗ trợ EAN, UPC, Code 39, Code 128, PDF417, Aztec, QR và các định dạng khác. Kết quả được trả về trong VNBarcodeObservation với payload và symbology. Đối với luồng video, hãy sử dụng AVCaptureMetadataOutput — nó nhanh hơn cho việc quét trực tiếp.
Có, VNImageRequestHandler chấp nhận CIImage qua bộ khởi tạo init(ciImage:options:). Nó cũng hỗ trợ Data (JPEG/PNG) và NSURL (đường dẫn tập tin). CIImage thuận tiện khi hình ảnh đã được tải qua đường ống Core Image — điều này tránh sao chép dữ liệu không cần thiết trong bộ nhớ.
Không có giới hạn về số lượng, nhưng trong thực tế 3–5 yêu cầu là tối ưu. Hơn 5 yêu cầu có thể gây tăng mức tiêu thụ bộ nhớ vì mỗi yêu cầu tải mô hình ML riêng. Nếu bạn cần thực hiện 10+ phân tích khác nhau, hãy chia chúng thành 2–3 nhóm và thực hiện tuần tự.
Tổng Kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm