Распознавайте текст на изображениях с помощью ML Kit на iOS

Вы можете использовать ML Kit для распознавания текста на изображениях или видео, например, текста на уличных знаках. Основные характеристики этой функции:

API распознавания текста v2
Описание Распознавание текста на изображениях и видео, поддержка латинского, китайского, деванагари, японского и корейского алфавитов и широкого спектра языков .
Имена SDK GoogleMLKit/TextRecognition
GoogleMLKit/TextRecognitionChinese
GoogleMLKit/TextRecognitionDevanagari
GoogleMLKit/TextRecognitionJapanese
GoogleMLKit/TextRecognitionKorean
Выполнение Активы статически привязываются к вашему приложению во время сборки.
Влияние размера приложения Около 38 МБ на скрипт SDK
Производительность В режиме реального времени на большинстве устройств для SDK латинского алфавита, медленнее на других.

Попробуйте это

Прежде чем начать

  1. Включите следующие модули ML Kit в свой Podfile:
     # 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' 
  2. После установки или обновления модулей вашего проекта откройте проект Xcode, используя его .xcworkspace . ML Kit поддерживается в Xcode версии 12.4 и выше.

1. Создайте экземпляр TextRecognizer

Создайте экземпляр TextRecognizer , вызвав +textRecognizer(options:) , передав параметры, относящиеся к SDK, который вы объявили как зависимость выше:

Быстрый

// 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 .

    Быстрый

    let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation

    Objective-C

    MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;

    Если вы используете CMSampleBuffer , выполните следующие действия:

    • Укажите ориентацию данных изображения, содержащихся в CMSampleBuffer .

      Чтобы получить ориентацию изображения:

      Быстрый

      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 и ориентацию:

      Быстрый

      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:) :

      Быстрый

      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 вы можете получить текст, распознанный в области, и граничные координаты области.

      Например:

      Быстрый

      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 входные изображения должны содержать текст, представленный достаточным количеством пикселей. В идеале размер каждого символа должен быть не менее 16x16 пикселей. Символы размером более 24x24 пикселей, как правило, не повышают точность распознавания.

        Например, изображение размером 640x480 пикселей может подойти для сканирования визитной карточки, занимающей всю её ширину. Для сканирования документа, напечатанного на бумаге формата Letter, может потребоваться изображение размером 720x1280 пикселей.

      • Плохая фокусировка изображения может повлиять на точность распознавания текста. Если результаты неудовлетворительны, попробуйте попросить пользователя повторно сделать снимок.

      • При распознавании текста в приложении реального времени следует учитывать общие размеры входных изображений. Изображения меньшего размера обрабатываются быстрее. Чтобы сократить задержку, убедитесь, что текст занимает как можно большую часть изображения, и снимайте изображения с более низким разрешением (с учетом требований к точности, упомянутых выше). Подробнее см. в разделе «Советы по повышению производительности» .

      Советы по повышению производительности

      • Для обработки видеокадров используйте синхронный API results(in:) детектора. Вызовите этот метод из функции captureOutput(_, didOutput:from:) AVCaptureVideoDataOutputSampleBufferDelegate для синхронного получения результатов из заданного видеокадра. true ограничения вызовов детектора установите alwaysDiscardsLateVideoFrames класса AVCaptureVideoDataOutput . Если новый видеокадр станет доступен во время работы детектора, он будет отброшен.
      • Если вы используете выходные данные детектора для наложения графики на входное изображение, сначала получите результат из ML Kit, а затем визуализируйте изображение и наложение за один шаг. Таким образом, визуализация на поверхности дисплея выполняется только один раз для каждого обработанного входного кадра. См. пример updatePreviewOverlayViewWithLastFrame в кратком руководстве по ML Kit.
      • Рассмотрите возможность захвата изображений в более низком разрешении. Однако учитывайте требования API к размерам изображений.
      • Чтобы избежать потенциального снижения производительности, не запускайте несколько экземпляров TextRecognizer с различными параметрами скрипта одновременно.