ML Kit позволяет распознавать текст на изображениях и в видео, например на дорожных знаках. Основные характеристики этой функции:
| Text Recognition v2 API | |
|---|---|
| Описание | Распознавание текста на изображениях и в видео. Поддерживаются латиница, деванагари, китайское, японское и корейское письмо, а также множество языков. |
| Названия SDK | GoogleMLKit/TextRecognition |
| Реализация | Объекты статически связываются с приложением во время сборки. |
| Влияние на размер приложения | Около 38 МБ на SDK скрипта |
| Эффективность | В реальном времени на большинстве устройств для SDK с латинским шрифтом, медленнее для других. |
Попробовать
- Попробуйте поработать с примером приложения, чтобы понять, как использовать этот API.
- Попробуйте написать код самостоятельно, используя практическую работу.
Подготовка
- Добавьте в Podfile следующие поды ML Kit:
# To recognize Latin script pod 'GoogleMLKit/TextRecognition', '8.0.0' # To recognize Chinese script pod 'GoogleMLKit/TextRecognitionChinese', '8.0.0' # To recognize Devanagari script pod 'GoogleMLKit/TextRecognitionDevanagari', '8.0.0' # To recognize Japanese script pod 'GoogleMLKit/TextRecognitionJapanese', '8.0.0' # To recognize Korean script pod 'GoogleMLKit/TextRecognitionKorean', '8.0.0'
- После установки или обновления Pods откройте проект Xcode, используя файл
.xcworkspace. ML Kit поддерживается в Xcode версии 12.4 и более поздних.
1. Создайте экземпляр TextRecognizer.
Создайте экземпляр TextRecognizer, вызвав +textRecognizer(options:) и передав параметры, связанные с SDK, который вы объявили как зависимость выше:
Swift
// When using Latin script recognition SDK let latinOptions = TextRecognizerOptions() let latinTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Chinese script recognition SDK let chineseOptions = ChineseTextRecognizerOptions() let chineseTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Devanagari script recognition SDK let devanagariOptions = DevanagariTextRecognizerOptions() let devanagariTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Japanese script recognition SDK let japaneseOptions = JapaneseTextRecognizerOptions() let japaneseTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Korean script recognition SDK let koreanOptions = KoreanTextRecognizerOptions() let koreanTextRecognizer = TextRecognizer.textRecognizer(options:options)
Objective-C
// When using Latin script recognition SDK MLKTextRecognizerOptions *latinOptions = [[MLKTextRecognizerOptions alloc] init]; MLKTextRecognizer *latinTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Chinese script recognition SDK MLKChineseTextRecognizerOptions *chineseOptions = [[MLKChineseTextRecognizerOptions alloc] init]; MLKTextRecognizer *chineseTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Devanagari script recognition SDK MLKDevanagariTextRecognizerOptions *devanagariOptions = [[MLKDevanagariTextRecognizerOptions alloc] init]; MLKTextRecognizer *devanagariTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Japanese script recognition SDK MLKJapaneseTextRecognizerOptions *japaneseOptions = [[MLKJapaneseTextRecognizerOptions alloc] init]; MLKTextRecognizer *japaneseTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Korean script recognition SDK MLKKoreanTextRecognizerOptions *koreanOptions = [[MLKKoreanTextRecognizerOptions alloc] init]; MLKTextRecognizer *koreanTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options];
2. Подготовьте входное изображение
Передайте изображение в видеUIImage или CMSampleBufferRef в метод process(_:completion:) класса TextRecognizer:
Создайте объект VisionImage, используя UIImage или CMSampleBuffer.
Если вы используете UIImage, выполните следующие действия:
- Создайте объект
VisionImageсUIImage. Убедитесь, что вы указали правильный.orientation.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Если вы используете CMSampleBuffer, выполните следующие действия:
-
Укажите ориентацию изображения, содержащегося в
CMSampleBuffer.Чтобы узнать ориентацию изображения:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- Создайте объект
VisionImage, используя объектCMSampleBufferи ориентацию:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. Обработка изображения
Затем передайте изображение методу process(_:completion:):
Swift
textRecognizer.process(visionImage) { result, error in
guard error == nil, let result = result else {
// Error handling
return
}
// Recognized text
}Objective-C
[textRecognizer processImage:image completion:^(MLKText *_Nullable result, NSError *_Nullable error) { if (error != nil || result == nil) { // Error handling return; } // Recognized text }];
4. Извлечение текста из блоков распознанного текста
Если операция распознавания текста выполнена успешно, она возвращает объект Text. Объект Text содержит полный текст, распознанный на изображении, и ноль или более объектов TextBlock.
Каждый объект TextBlock представляет собой прямоугольный блок текста, который содержит один или несколько объектов TextLine. Каждый объект TextLine содержит ноль или более объектов TextElement, которые представляют слова и подобные им элементы, например даты и числа.
Для каждого объекта TextBlock, TextLine и TextElement можно получить текст, распознанный в области, и координаты ее границ.
Пример:
Swift
let resultText = result.text
for block in result.blocks {
let blockText = block.text
let blockLanguages = block.recognizedLanguages
let blockCornerPoints = block.cornerPoints
let blockFrame = block.frame
for line in block.lines {
let lineText = line.text
let lineLanguages = line.recognizedLanguages
let lineCornerPoints = line.cornerPoints
let lineFrame = line.frame
for element in line.elements {
let elementText = element.text
let elementCornerPoints = element.cornerPoints
let elementFrame = element.frame
}
}
}Objective-C
NSString *resultText = result.text;
for (MLKTextBlock *block in result.blocks) {
NSString *blockText = block.text;
NSArray<MLKTextRecognizedLanguage *> *blockLanguages = block.recognizedLanguages;
NSArray<NSValue *> *blockCornerPoints = block.cornerPoints;
CGRect blockFrame = block.frame;
for (MLKTextLine *line in block.lines) {
NSString *lineText = line.text;
NSArray<MLKTextRecognizedLanguage *> *lineLanguages = line.recognizedLanguages;
NSArray<NSValue *> *lineCornerPoints = line.cornerPoints;
CGRect lineFrame = line.frame;
for (MLKTextElement *element in line.elements) {
NSString *elementText = element.text;
NSArray<NSValue *> *elementCornerPoints = element.cornerPoints;
CGRect elementFrame = element.frame;
}
}
}Требования к исходным изображениям
-
Чтобы ML Kit мог точно распознавать текст, входные изображения должны содержать текст, представленный достаточным количеством пиксельных данных. В идеале каждый символ должен быть не меньше 16 x 16 пикселей. Как правило, точность распознавания не повышается, если размер символов превышает 24 x 24 пикселя.
Например, изображение размером 640 x 480 может подойти для сканирования визитной карточки, которая занимает всю ширину изображения. Для сканирования документа, напечатанного на бумаге формата Letter, может потребоваться изображение размером 720 x 1280 пикселей.
-
Плохая фокусировка изображения может повлиять на точность распознавания текста. Если вы не получаете приемлемых результатов, попросите пользователя сделать снимок заново.
-
Если вы распознаете текст в приложении реального времени, вам следует учитывать общие размеры входных изображений. Изображения меньшего размера обрабатываются быстрее. Чтобы сократить задержку, убедитесь, что текст занимает как можно большую часть изображения, и делайте снимки с более низким разрешением (с учетом требований к точности, упомянутых выше). Подробнее о том, как повысить эффективность…
Советы по повышению эффективности
- Для обработки кадров видео используйте синхронный API детектора
results(in:). Вызовите этот метод из функцииcaptureOutput(_, didOutput:from:)объектаAVCaptureVideoDataOutputSampleBufferDelegate, чтобы синхронно получить результаты для заданного кадра видео. Оставьте для параметраalwaysDiscardsLateVideoFramesвAVCaptureVideoDataOutputзначениеtrue, чтобы ограничить количество вызовов детектора. Если во время работы детектора станет доступен новый кадр видео, он будет отброшен. - Если вы используете выходные данные детектора для наложения графики на входное изображение, сначала получите результат от ML Kit, а затем визуализируйте изображение и наложение за один шаг. Это позволит вам выполнять рендеринг на поверхности экрана только один раз для каждого обработанного входного кадра. Пример можно найти в разделе updatePreviewOverlayViewWithLastFrame в руководстве по быстрому началу работы с ML Kit.
- Попробуйте сделать снимки с более низким разрешением. Однако не забывайте о требованиях к размерам изображений, которые предъявляет этот API.
- Чтобы избежать снижения производительности, не запускайте одновременно несколько экземпляров
TextRecognizerс разными параметрами скрипта.