Vision framework provides powerful computer vision capabilities. Learn to detect faces, recognize text, and analyze images.
Vision Setup
Import Vision
swift
import Vision
import UIKit
import CoreGraphics
class VisionProcessor {
func processImage(_ image: UIImage) {
guard let cgImage = image.cgImage else {
return
}
let orientation = CGImagePropertyOrientation(image.imageOrientation)
let requestHandler = VNImageRequestHandler(cgImage: cgImage, orientation: orientation) { request, error in
// Handle results
}
let requests = [VNRecognizeAnimalsRequest(), VNRecognizeTextRequest()]
for request in requests {
requestHandler(request)
}
}
}Face Detection
Detect Faces
swift
class FaceDetector: ObservableObject {
@Published var faceCount: Int = 0
@Published var faceBounds: [CGRect] = []
func detectFaces(in image: UIImage) {
guard let cgImage = image.cgImage else {
return
}
let faceDetectionRequest = VNDetectFaceRectanglesRequest { request, error in
guard let results = request.results as? [VNFaceObservation], error == nil else {
return
}
DispatchQueue.main.async {
self.faceCount = results.count
self.faceBounds = results.map { $0.boundingBox }
}
}
let handler = VNImageRequestHandler(cgImage: cgImage, orientation: .up, completionHandler: faceDetectionRequest)
try? VNImageRequestHandler(cgImage: cgImage, orientation: .up).perform([faceDetectionRequest])
}
func detectFaceLandmarks(in image: UIImage) {
let landmarkDetectionRequest = VNDetectFaceLandmarksRequest { request, error in
guard let results = request.results as? [VNFaceObservation], error == nil else {
return
}
for face in results {
if let landmarks = face.landmarks {
print("Face detected at: \(landmarks.leftEye?.location)")
}
}
}
let handler = VNImageRequestHandler(cgImage: image.cgImage!, orientation: .up)
try? handler.perform([landmarkDetectionRequest])
}
func captureQuality(in image: UIImage) {
let qualityRequest = VNDetectFaceCaptureQualityRequest { request, error in
guard let results = request.results as? [VNFaceObservation], error == nil else {
return
}
for face in results {
if let quality = face.faceCaptureQuality {
print("Quality: \(quality)")
}
}
}
let handler = VNImageRequestHandler(cgImage: image.cgImage!, orientation: .up)
try? handler.perform([qualityRequest])
}
}Text Recognition
OCR
swift
class TextRecognizer: ObservableObject {
@Published var recognizedText: String = ""
func recognizeText(in image: UIImage) {
guard let cgImage = image.cgImage else {
return
}
let request = VNRecognizeTextRequest { request, error in
guard let results = request.results as? [VNRecognizedTextObservation], error == nil else {
return
}
let text = results.compactMap { $0.topCandidates(1).first?.string }
let combinedText = text.joined(separator: "\n")
DispatchQueue.main.async {
self.recognizedText = combinedText
}
}
let handler = VNImageRequestHandler(cgImage: cgImage, orientation: .up)
try? handler.perform([request])
}
func recognizeTextRectangles(in image: UIImage) {
let request = VNRecognizeTextRequest { request, error in
guard let results = request.results as? [VNRecognizedTextObservation], error == nil else {
return
}
for result in results {
if let textBox = result.boundingBox {
print("Text box: \(textBox)")
}
}
}
let handler = VNImageRequestHandler(cgImage: image.cgImage!, orientation: .up)
try? handler.perform([request])
}
}Object Detection
Detect Objects
swift
class ObjectDetector: ObservableObject {
@Published var detectedObjects: [(label: String, confidence: VNConfidence, location: CGRect)] = []
func detectObjects(in image: UIImage) {
guard let cgImage = image.cgImage else {
return
}
let request = VNRecognizeAnimalsRequest { request, error in
guard let results = request.results as? [VNRecognizedObservation], error == nil else {
return
}
let objects = results.map { observation in
(
label: observation.labels.first?.identifier ?? "Unknown",
confidence: observation.confidence,
location: observation.boundingBox
)
}
DispatchQueue.main.async {
self.detectedObjects = objects
}
}
let handler = VNImageRequestHandler(cgImage: cgImage, orientation: up)
try? handler.perform([request])
}
func detectRectangles(in image: UIImage) {
let request = VNDetectRectanglesRequest { request, error in
guard let results = request.results as? [VNRectangleObservation], error == nil else {
return
}
for rectangle in results {
print("Rectangle: \(rectangle.boundingBox)")
}
}
let handler = VNImageRequestHandler(cgImage: cgImage!, orientation: .up)
try? handler.perform([request])
}
func detectBarcodes(in image: UIImage) {
let request = VNDetectBarcodesRequest { request, error in
guard let results = request.results as? [VNBarcodeObservation], error == nil else {
return
}
for barcode in results {
print("Barcode: \(barcode.payloadStringValue ?? "")")
}
}
let handler = VNImageRequestHandler(cgImage: cgImage!, orientation: .up)
try? handler.perform([request])
}
}Image Classification
Classify Images
swift
class ImageClassifier {
func classify(image: UIImage) async throws -> [String] {
guard let cgImage = image.cgImage else {
throw ClassifyError.invalidImage
}
let model = try VNCoreMLModel(for: MLModel(contentsOf: Bundle.main.url(forResource: "ImageClassifier", withExtension: "mlmodelc")!)
let classificationRequest = VNCoreMLRequest(model: model) { request, error in
guard let results = request.results as? [VNClassificationObservation], error == nil else {
return
}
let classifications = results.prefix(5).map {
$0.identifier
}
print("Classifications: \(classifications)")
}
let handler = VNImageRequestHandler(cgImage: cgImage, orientation: up)
try await handler.perform([classificationRequest])
}
enum ClassifyError: Error {
case invalidImage
}
}Core ML Integration
ML Models
swift
class MLImageProcessor {
func processImageWithModel(image: UIImage) async throws -> String {
guard let cgImage = image.cgImage else {
throw ProcessingError.invalidImage
}
let configuration = MLModelConfiguration()
let model = try VNCoreMLModel(for: MLModel(contentsOf: Bundle.main.url(forResource: "CustomModel", withExtension: "mlmodelc")!)
let request = VNCoreMLRequest(model: model) { request, error in
guard let results = request.results as? [VNClassificationObservation] else {
return
}
if let topResult = results.first {
DispatchQueue.main.async {
print("Classification: \(topResult.identifier), Confidence: \(topResult.confidence)")
}
}
}
let handler = VNImageRequestHandler(cgImage: cgImage, orientation: up)
try await handler.perform([request])
}
enum ProcessingError: Error {
case invalidImage
}
}Visual Search
Similarity Search
swift
class VisualSearchManager {
func generateFeatureVector(for image: UIImage) async throws -> [Float] {
guard let cgImage = image.cgImage else {
throw SearchError.invalidImage
}
let request = VNGenerateImageFeaturePrintRequest { request, error in
if let featurePrint = request.results?.first as? VNFeaturePrintObservation {
let data = featurePrint.data
let featureVector = data.withUnsafeBytes { pointer in
Array(UnsafeBufferPointer(start: pointer, count: 128).compactMap { $0 as? Float })
}
DispatchQueue.main.async {
print("Feature vector: \(featureVector.count) dimensions")
}
return featureVector
}
}
let handler = VNImageRequestHandler(cgImage: cgImage, orientation: up)
try await handler.perform([request])
}
func compareImages(_ image1: UIImage, _ image2: UIImage) async throws -> Float {
let vector1 = try await generateFeatureVector(for: image1)
let vector2 = try await generateFeatureVector(for: image2)
let similarity = cosineSimilarity(vector1, vector2)
return similarity
}
private func cosineSimilarity(_ a: [Float], _ b: [Float]) -> Float {
guard a.count == b.count else { return 0 }
let dotProduct = zip(a, b).map(*).reduce(0, +)
let magnitudeA = sqrt(a.map { $0 * $0 }.reduce(0, +))
let magnitudeB = sqrt(b.map { $0 * $0 }.reduce(0, +))
return dotProduct / (magnitudeA * magnitudeB)
}
enum SearchError: Error {
case invalidImage
}
}Text Tracking
Video Text Recognition
swift
class VideoTextProcessor {
func processVideoFrame(_ image: UIImage) {
let request = VNRecognizeTextRequest { request, error in
guard let results = request.results as? [VNRecognizedTextObservation], error == nil else {
return
}
for observation in results {
print("Text: \(observation.topCandidates(1).first?.string ?? "")")
print("Box: \(observation.boundingBox)")
}
}
guard let cgImage = image.cgImage else { return }
let handler = VNImageRequestHandler(cgImage: cgImage, orientation: .up)
try? handler.perform([request])
}
}Best Practices
- 1Performance: Process images efficiently
- 2Memory: Manage memory for large images
- 3Accuracy: Choose appropriate models
- 4Thread: Use appropriate threading
- 5Error Handling: Handle errors gracefully
- 6Testing: Test with various images
- 7Models: Use optimized models
- 8UX: Provide feedback to users
Vision Framework enables powerful computer vision capabilities!