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

Вы можете использовать Firebase ML для распознавания текста на изображениях. Firebase ML имеет как универсальный API, подходящий для распознавания текста на изображениях, например, текста на дорожном знаке, так и API, оптимизированный для распознавания текста в документах.

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

    Если вы еще не добавили Firebase в свое приложение, сделайте это, следуя инструкциям в руководстве по началу работы .

    Используйте Swift Package Manager для установки и управления зависимостями Firebase.

    1. В Xcode, открыв проект приложения, перейдите в меню File > Add Packages .
    2. При появлении запроса добавьте репозиторий Firebase Apple Platforms SDK:
    3.   https://github.com/firebase/firebase-ios-sdk.git
    4. Выберите библиотеку Firebase ML .
    5. Добавьте флаг -ObjC в раздел «Другие флаги компоновщика» в настройках сборки вашей целевой системы.
    6. После завершения Xcode автоматически начнет разрешение и загрузку ваших зависимостей в фоновом режиме.

    Далее выполните некоторые настройки внутри приложения:

    1. В вашем приложении импортируйте Firebase:

      Быстрый

      import FirebaseMLModelDownloader

      Objective-C

      @import FirebaseMLModelDownloader;
  1. Если вы еще не включили облачные API для своего проекта, сделайте это сейчас:

    1. Откройте страницу API Firebase ML в консоли Firebase .
    2. Если вы еще не перевели свой проект на тарифный план Blaze с оплатой по факту использования , нажмите «Обновить» , чтобы сделать это. (Вам будет предложено обновить тарифный план только в том случае, если ваш проект не подключен к тарифному плану Blaze.)

      Использовать облачные API могут только проекты, использующие тарифный план Blaze.

    3. Если облачные API еще не включены, нажмите «Включить облачные API» .

Теперь вы готовы начать распознавать текст на изображениях.

рекомендации по входным изображениям

  • Для точного распознавания текста Firebase ML входные изображения должны содержать текст, представленный достаточным количеством пикселей. В идеале, для латинского текста каждый символ должен быть не менее 16x16 пикселей. Для китайского, японского и корейского текста каждый символ должен быть 24x24 пикселя. Для всех языков, как правило, нет никакого преимущества в точности, если символы больше 24x24 пикселей.

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

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


Распознавание текста на изображениях

Для распознавания текста на изображении запустите средство распознавания текста, как описано ниже.

1. Запустите программу распознавания текста.

Передайте изображение в виде UIImage или CMSampleBufferRef в метод process(_:completion:) объекта VisionTextRecognizer :

  1. Получите экземпляр VisionTextRecognizer , вызвав cloudTextRecognizer :

    Быстрый

    let vision = Vision.vision()
    let textRecognizer = vision.cloudTextRecognizer()
    
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    let options = VisionCloudTextRecognizerOptions()
    options.languageHints = ["en", "hi"]
    let textRecognizer = vision.cloudTextRecognizer(options: options)

    Objective-C

    FIRVision *vision = [FIRVision vision];
    FIRVisionTextRecognizer *textRecognizer = [vision cloudTextRecognizer];
    
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    FIRVisionCloudTextRecognizerOptions *options =
            [[FIRVisionCloudTextRecognizerOptions alloc] init];
    options.languageHints = @[@"en", @"hi"];
    FIRVisionTextRecognizer *textRecognizer = [vision cloudTextRecognizerWithOptions:options];
  2. Для вызова Cloud Vision изображение должно быть отформатировано как строка, закодированная в base64. Для обработки UIImage :

    Быстрый

    guard let imageData = uiImage.jpegData(compressionQuality: 1.0) else { return }
    let base64encodedImage = imageData.base64EncodedString()

    Objective-C

    NSData *imageData = UIImageJPEGRepresentation(uiImage, 1.0f);
    NSString *base64encodedImage =
      [imageData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
  3. Затем передайте изображение методу process(_:completion:) :

    Быстрый

    textRecognizer.process(visionImage) { result, error in
      guard error == nil, let result = result else {
        // ...
        return
      }
    
      // Recognized text
    }

    Objective-C

    [textRecognizer processImage:image
                      completion:^(FIRVisionText *_Nullable result,
                                   NSError *_Nullable error) {
      if (error != nil || result == nil) {
        // ...
        return;
      }
    
      // Recognized text
    }];

2. Извлечение текста из блоков распознанного текста.

Если операция распознавания текста прошла успешно, она вернет объект VisionText . Объект VisionText содержит полный текст, распознанный на изображении, и ноль или более объектов VisionTextBlock .

Каждый VisionTextBlock представляет собой прямоугольный блок текста, содержащий ноль или более объектов VisionTextLine . Каждый объект VisionTextLine содержит ноль или более объектов VisionTextElement , которые представляют слова и словесные сущности (даты, числа и т. д.).

Для каждого объекта VisionTextBlock , VisionTextLine и VisionTextElement можно получить текст, распознанный в данной области, и ограничивающие координаты этой области.

Например:

Быстрый

let resultText = result.text
for block in result.blocks {
    let blockText = block.text
    let blockConfidence = block.confidence
    let blockLanguages = block.recognizedLanguages
    let blockCornerPoints = block.cornerPoints
    let blockFrame = block.frame
    for line in block.lines {
        let lineText = line.text
        let lineConfidence = line.confidence
        let lineLanguages = line.recognizedLanguages
        let lineCornerPoints = line.cornerPoints
        let lineFrame = line.frame
        for element in line.elements {
            let elementText = element.text
            let elementConfidence = element.confidence
            let elementLanguages = element.recognizedLanguages
            let elementCornerPoints = element.cornerPoints
            let elementFrame = element.frame
        }
    }
}

Objective-C

NSString *resultText = result.text;
for (FIRVisionTextBlock *block in result.blocks) {
  NSString *blockText = block.text;
  NSNumber *blockConfidence = block.confidence;
  NSArray<FIRVisionTextRecognizedLanguage *> *blockLanguages = block.recognizedLanguages;
  NSArray<NSValue *> *blockCornerPoints = block.cornerPoints;
  CGRect blockFrame = block.frame;
  for (FIRVisionTextLine *line in block.lines) {
    NSString *lineText = line.text;
    NSNumber *lineConfidence = line.confidence;
    NSArray<FIRVisionTextRecognizedLanguage *> *lineLanguages = line.recognizedLanguages;
    NSArray<NSValue *> *lineCornerPoints = line.cornerPoints;
    CGRect lineFrame = line.frame;
    for (FIRVisionTextElement *element in line.elements) {
      NSString *elementText = element.text;
      NSNumber *elementConfidence = element.confidence;
      NSArray<FIRVisionTextRecognizedLanguage *> *elementLanguages = element.recognizedLanguages;
      NSArray<NSValue *> *elementCornerPoints = element.cornerPoints;
      CGRect elementFrame = element.frame;
    }
  }
}

Следующие шаги


Распознавание текста на изображениях документов

Для распознавания текста документа настройте и запустите средство распознавания текста документа, как описано ниже.

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

Для использования API распознавания текста в документах:

1. Запустите программу распознавания текста.

Передайте изображение в виде UIImage или CMSampleBufferRef в метод process(_:completion:) объекта VisionDocumentTextRecognizer :

  1. Получите экземпляр VisionDocumentTextRecognizer , вызвав cloudDocumentTextRecognizer :

    Быстрый

    let vision = Vision.vision()
    let textRecognizer = vision.cloudDocumentTextRecognizer()
    
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    let options = VisionCloudDocumentTextRecognizerOptions()
    options.languageHints = ["en", "hi"]
    let textRecognizer = vision.cloudDocumentTextRecognizer(options: options)

    Objective-C

    FIRVision *vision = [FIRVision vision];
    FIRVisionDocumentTextRecognizer *textRecognizer = [vision cloudDocumentTextRecognizer];
    
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    FIRVisionCloudDocumentTextRecognizerOptions *options =
            [[FIRVisionCloudDocumentTextRecognizerOptions alloc] init];
    options.languageHints = @[@"en", @"hi"];
    FIRVisionDocumentTextRecognizer *textRecognizer = [vision cloudDocumentTextRecognizerWithOptions:options];
  2. Для вызова Cloud Vision изображение должно быть отформатировано как строка, закодированная в base64. Для обработки UIImage :

    Быстрый

    guard let imageData = uiImage.jpegData(compressionQuality: 1.0) else { return }
    let base64encodedImage = imageData.base64EncodedString()

    Objective-C

    NSData *imageData = UIImageJPEGRepresentation(uiImage, 1.0f);
    NSString *base64encodedImage =
      [imageData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
  3. Затем передайте изображение методу process(_:completion:) :

    Быстрый

    textRecognizer.process(visionImage) { result, error in
      guard error == nil, let result = result else {
        // ...
        return
      }
    
      // Recognized text
    }

    Objective-C

    [textRecognizer processImage:image
                      completion:^(FIRVisionDocumentText *_Nullable result,
                                   NSError *_Nullable error) {
      if (error != nil || result == nil) {
        // ...
        return;
      }
    
        // Recognized text
    }];

2. Извлечение текста из блоков распознанного текста.

Если операция распознавания текста прошла успешно, она вернет объект VisionDocumentText . Объект VisionDocumentText содержит полный текст, распознанный на изображении, и иерархию объектов, отражающих структуру распознанного документа:

Для каждого объекта VisionDocumentTextBlock , VisionDocumentTextParagraph , VisionDocumentTextWord и VisionDocumentTextSymbol можно получить текст, распознанный в данной области, и ограничивающие координаты этой области.

Например:

Быстрый

let resultText = result.text
for block in result.blocks {
    let blockText = block.text
    let blockConfidence = block.confidence
    let blockRecognizedLanguages = block.recognizedLanguages
    let blockBreak = block.recognizedBreak
    let blockCornerPoints = block.cornerPoints
    let blockFrame = block.frame
    for paragraph in block.paragraphs {
        let paragraphText = paragraph.text
        let paragraphConfidence = paragraph.confidence
        let paragraphRecognizedLanguages = paragraph.recognizedLanguages
        let paragraphBreak = paragraph.recognizedBreak
        let paragraphCornerPoints = paragraph.cornerPoints
        let paragraphFrame = paragraph.frame
        for word in paragraph.words {
            let wordText = word.text
            let wordConfidence = word.confidence
            let wordRecognizedLanguages = word.recognizedLanguages
            let wordBreak = word.recognizedBreak
            let wordCornerPoints = word.cornerPoints
            let wordFrame = word.frame
            for symbol in word.symbols {
                let symbolText = symbol.text
                let symbolConfidence = symbol.confidence
                let symbolRecognizedLanguages = symbol.recognizedLanguages
                let symbolBreak = symbol.recognizedBreak
                let symbolCornerPoints = symbol.cornerPoints
                let symbolFrame = symbol.frame
            }
        }
    }
}

Objective-C

NSString *resultText = result.text;
for (FIRVisionDocumentTextBlock *block in result.blocks) {
  NSString *blockText = block.text;
  NSNumber *blockConfidence = block.confidence;
  NSArray<FIRVisionTextRecognizedLanguage *> *blockRecognizedLanguages = block.recognizedLanguages;
  FIRVisionTextRecognizedBreak *blockBreak = block.recognizedBreak;
  CGRect blockFrame = block.frame;
  for (FIRVisionDocumentTextParagraph *paragraph in block.paragraphs) {
    NSString *paragraphText = paragraph.text;
    NSNumber *paragraphConfidence = paragraph.confidence;
    NSArray<FIRVisionTextRecognizedLanguage *> *paragraphRecognizedLanguages = paragraph.recognizedLanguages;
    FIRVisionTextRecognizedBreak *paragraphBreak = paragraph.recognizedBreak;
    CGRect paragraphFrame = paragraph.frame;
    for (FIRVisionDocumentTextWord *word in paragraph.words) {
      NSString *wordText = word.text;
      NSNumber *wordConfidence = word.confidence;
      NSArray<FIRVisionTextRecognizedLanguage *> *wordRecognizedLanguages = word.recognizedLanguages;
      FIRVisionTextRecognizedBreak *wordBreak = word.recognizedBreak;
      CGRect wordFrame = word.frame;
      for (FIRVisionDocumentTextSymbol *symbol in word.symbols) {
        NSString *symbolText = symbol.text;
        NSNumber *symbolConfidence = symbol.confidence;
        NSArray<FIRVisionTextRecognizedLanguage *> *symbolRecognizedLanguages = symbol.recognizedLanguages;
        FIRVisionTextRecognizedBreak *symbolBreak = symbol.recognizedBreak;
        CGRect symbolFrame = symbol.frame;
      }
    }
  }
}

Следующие шаги