Vision для Swift: полное руководство с примерами
Добро пожаловать в подробное руководство по фреймворку Vision от Apple для языка Swift. Эта статья предназначена для разработчиков всех уровней — от новичков, только начинающих знакомство с компьютерным зрением на iOS/macOS, до опытных инженеров, желающих углубить свои знания и освоить продвинутые техники.
Мы разберём всё: от установки и первого запуска до сложных пайплайнов обработки изображений и советов по оптимизации производительности. Все примеры кода написаны на Swift 5.9+ и протестированы с Xcode 15.
1. Что это и зачем нужна
Vision — это мощный фреймворк компьютерного зрения, встроенный в экосистему Apple (iOS, macOS, tvOS, watchOS). Он предоставляет разработчикам высокоуровневый API для выполнения сложных задач анализа изображений и видео в реальном времени, используя как традиционные алгоритмы, так и модели машинного обучения (Core ML).
Зачем он нужен? Если вам требуется распознать лица на фотографии, найти текст на изображении, отследить движение объекта в видео, классифицировать сцену или даже выполнить сегментацию объектов — Vision берёт на себя всю низкоуровневую работу. Вам не нужно писать сложные алгоритмы обработки пикселей или оптимизировать нейросети для работы на устройствах Apple. Vision делает это за вас, используя аппаратное ускорение (Neural Engine, GPU) и оптимизированные фреймворки (Metal, Accelerate).
Ключевые возможности Vision включают:
- Обнаружение и распознавание лиц (с определением черт лица, эмоций, ориентации).
- Распознавание текста (OCR) на нескольких языках, включая кириллицу.
- Обнаружение и классификация объектов (с использованием встроенных или пользовательских моделей Core ML).
- Анализ движения (оптический поток, отслеживание точек).
- Сегментация изображений (через модели Core ML).
- Обнаружение штрихкодов и QR-кодов.
- Анализ контуров и геометрии (обнаружение прямоугольников, горизонтов).
Vision идеально подходит для создания приложений дополненной реальности, автоматизации ввода данных, систем безопасности, фоторедакторов и многих других продуктов.
2. Установка
В отличие от сторонних библиотек, Vision является частью SDK Apple и не требует установки через менеджеры пакетов (CocoaPods, Swift Package Manager, Carthage). Всё, что нужно — это импортировать фреймворк в ваш проект.
2.1. Импорт в коде
Добавьте следующую строку в начало вашего Swift-файла:
import Vision
2.2. Настройка проекта в Xcode
- Откройте ваш проект в Xcode.
- Выберите цель (Target) вашего приложения.
- Перейдите на вкладку Frameworks, Libraries, and Embedded Content.
- Нажмите на кнопку +.
- Найдите Vision.framework в списке и добавьте его.
NSCameraUsageDescription) в Info.plist, если планируете работать с живым видео.
Всё! Фреймворк готов к использованию. Никаких дополнительных команд pip install или npm install не требуется.
3. Быстрый старт — минимальный рабочий пример
Давайте напишем простейшую программу, которая загружает изображение и находит на нём все лица. Этот пример демонстрирует основной паттерн работы с Vision: создание запроса, его настройка, выполнение и обработка результатов.
import Cocoa
import Vision
// 1. Загружаем изображение (замените путь на свой)
guard let image = NSImage(byReferencingFile: "/path/to/your/image.jpg") else {
fatalError("Не удалось загрузить изображение")
}
// 2. Создаем обработчик запроса на основе изображения
guard let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil) else {
fatalError("Не удалось получить CGImage")
}
let requestHandler = VNImageRequestHandler(cgImage: cgImage, options: [:])
// 3. Создаем запрос на обнаружение лиц
let faceDetectionRequest = VNDetectFaceRectanglesRequest { request, error in
if let error = error {
print("Ошибка: \(error.localizedDescription)")
return
}
// 4. Обрабатываем результаты
guard let observations = request.results as? [VNFaceObservation] else {
print("Лица не найдены")
return
}
print("Найдено лиц: \(observations.count)")
for (index, face) in observations.enumerated() {
let boundingBox = face.boundingBox
print("Лицо \(index + 1): x=\(boundingBox.origin.x), y=\(boundingBox.origin.y), ширина=\(boundingBox.width), высота=\(boundingBox.height)")
}
}
// 5. Выполняем запрос
do {
try requestHandler.perform([faceDetectionRequest])
} catch {
print("Не удалось выполнить запрос: \(error)")
}
Этот код выведет в консоль количество найденных лиц и их координаты в нормализованной системе (от 0 до 1).
4. Основные методы/функции/классы
Рассмотрим 8 ключевых классов и методов Vision, которые покроют 90% ваших задач. Для каждого приведена сигнатура, описание и рабочий пример.
4.1. VNImageRequestHandler
Сигнатура:
class VNImageRequestHandler {
init(cgImage: CGImage, options: [VNImageOption: Any] = [:])
init(cvPixelBuffer: CVPixelBuffer, options: [VNImageOption: Any] = [:])
init(data: Data, orientation: CGImagePropertyOrientation, options: [VNImageOption: Any] = [:])
func perform(_ requests: [VNRequest]) throws
}
Что делает: Это основной класс для запуска запросов Vision. Он принимает изображение в различных форматах (CGImage, CVPixelBuffer, Data) и выполняет массив запросов. Каждый вызов perform — это синхронная операция, которая блокирует текущий поток.
Пример:
// Создаем обработчик из данных изображения
guard let imageData = try? Data(contentsOf: URL(fileURLWithPath: "photo.jpg")) else { return }
let handler = VNImageRequestHandler(data: imageData, orientation: .up, options: [:])
// Выполняем запросы
try handler.perform([someRequest])
4.2. VNDetectFaceRectanglesRequest
Сигнатура:
class VNDetectFaceRectanglesRequest : VNImageBasedRequest {
var results: [VNFaceObservation]? { get }
init(completionHandler: VNRequestCompletionHandler? = nil)
}
Что делает: Обнаруживает лица на изображении и возвращает массив VNFaceObservation, каждый из которых содержит bounding box (прямоугольник, ограничивающий лицо) в нормализованных координатах.
Пример:
let request = VNDetectFaceRectanglesRequest { request, error in
guard let faces = request.results as? [VNFaceObservation] else { return }
for face in faces {
print("Лицо: \(face.boundingBox)")
// face.boundingBox.origin.x, .origin.y, .width, .height
}
}
try handler.perform([request])
4.3. VNDetectFaceLandmarksRequest
Сигнатура:
class VNDetectFaceLandmarksRequest : VNImageBasedRequest {
var results: [VNFaceObservation]? { get }
init(completionHandler: VNRequestCompletionHandler? = nil)
}
Что делает: Расширенная версия запроса на лица. Помимо bounding box, возвращает детальные ориентиры (landmarks): контур лица, брови, глаза, нос, губы. Каждый ориентир — это массив точек (VNFaceLandmarkRegion2D).
Пример:
let request = VNDetectFaceLandmarksRequest { request, error in
guard let faces = request.results as? [VNFaceObservation] else { return }
for face in faces {
if let leftEye = face.landmarks?.leftEye {
print("Левый глаз: \(leftEye.pointCount) точек")
// leftEye.normalizedPoints — массив CGPoint
}
if let faceContour = face.landmarks?.faceContour {
print("Контур лица: \(faceContour.pointCount) точек")
}
}
}
try handler.perform([request])
4.4. VNRecognizeTextRequest
Сигнатура:
class VNRecognizeTextRequest : VNImageBasedRequest {
var results: [VNRecognizedTextObservation]? { get }
var recognitionLevel: VNRequestTextRecognitionLevel { get set }
var usesLanguageCorrection: Bool { get set }
var recognitionLanguages: [String] { get set }
init(completionHandler: VNRequestCompletionHandler? = nil)
}
Что делает: Распознаёт текст на изображении (OCR). Поддерживает множество языков, включая русский. Можно настроить уровень точности (.fast или .accurate) и включить автокоррекцию языка.
Пример:
let request = VNRecognizeTextRequest { request, error in
guard let observations = request.results as? [VNRecognizedTextObservation] else { return }
for observation in observations {
// Берем самый надежный вариант распознанного текста
if let topCandidate = observation.topCandidates(1).first {
print("Текст: \(topCandidate.string)")
// observation.boundingBox — где находится текст на изображении
}
}
}
request.recognitionLevel = .accurate
request.usesLanguageCorrection = true
request.recognitionLanguages = ["ru-RU", "en-US"]
try handler.perform([request])
4.5. VNCoreMLRequest
Сигнатура:
class VNCoreMLRequest : VNImageBasedRequest {
var results: [VNObservation]? { get }
var imageCropAndScaleOption: VNImageCropAndScaleOption { get set }
init(model: VNCoreMLModel, completionHandler: VNRequestCompletionHandler? = nil)
}
Что делает: Позволяет использовать любую модель Core ML для анализа изображений. Модель должна быть предварительно загружена в VNCoreMLModel. Результаты зависят от типа модели (классификация, обнаружение объектов, сегментация и т.д.).
Пример (классификация изображений с MobileNetV2):
// Предположим, у вас есть MobileNetV2.mlmodel в проекте
guard let mlModel = try? VNCoreMLModel(for: MobileNetV2(configuration: MLModelConfiguration()).model) else {
fatalError("Не удалось загрузить модель")
}
let request = VNCoreMLRequest(model: mlModel) { request, error in
guard let results = request Также в библиотеке
Helmet для JavaScript (Node.js): полное руководство с примерами
Планировщик задач на PHP: библиотека cron‑expression для гибкого расписания
lo для Go: полное руководство с примерами