Reconnaître du texte dans des images avec ML Kit sur iOS

Vous pouvez utiliser ML Kit pour reconnaître du texte dans des images. ML Kit dispose à la fois d'un une API à usage général adaptée à la reconnaissance de texte dans des images, comme le texte d'un panneau indicateur et une API optimisée pour reconnaître documents. L'API à usage général dispose de modèles sur l'appareil et dans le cloud. La reconnaissance de document texte n'est disponible qu'en tant que modèle dans le cloud. Consultez le Présentation pour comparer les cloud et sur appareil.

Avant de commencer

  1. Si vous n'avez pas encore ajouté Firebase à votre application, suivez les les étapes décrites dans le guide de démarrage.
  2. Incluez les bibliothèques ML Kit dans votre Podfile:
    pod 'Firebase/MLVision', '6.25.0'
    # If using an on-device API:
    pod 'Firebase/MLVisionTextModel', '6.25.0'
    
    Après avoir installé ou mis à jour les pods de votre projet, ouvrez votre Xcode projet à l'aide de son .xcworkspace.
  3. Dans votre application, importez Firebase:

    Swift

    import Firebase

    Objective-C

    @import Firebase;
  4. Si vous souhaitez utiliser le modèle basé dans le cloud et que vous n'avez pas encore activé les API dans le cloud pour votre projet, faites-le maintenant:

    1. Ouvrez le ML Kit page des API de la console Firebase.
    2. Si vous n'avez pas encore migré votre projet vers un forfait Blaze, cliquez sur Mettre à niveau pour le faire. (Vous ne serez invité à effectuer la mise à niveau que si votre projet n'est pas associé au forfait Blaze.)

      Seuls les projets de niveau Blaze peuvent utiliser des API dans le cloud.

    3. Si les API dans le cloud ne sont pas déjà activées, cliquez sur Activer les services API.

    Si vous souhaitez utiliser uniquement le modèle intégré à l'appareil, vous pouvez ignorer cette étape.

Vous êtes maintenant prêt à commencer à reconnaître du texte dans des images.

Consignes pour les images d'entrée

  • Pour que ML Kit reconnaisse précisément le texte, les images d'entrée doivent contenir du texte représenté par suffisamment de données de pixel. Dans l'idéal, chaque caractère du texte latin doit mesurer au moins 16 x 16 pixels. Pour le chinois, le japonais et le coréen (uniquement pris en charge par les API dans le cloud), chacun doit mesurer 24 x 24 pixels. Pour toutes les langues, il n'y a généralement aucun avantage de précision à ce que les caractères soient plus grands que 24 x 24 pixels.

    Par exemple, une image de 640 x 480 pixels peut convenir pour numériser une carte de visite. qui occupe toute la largeur de l'image. Pour numériser un document imprimé sur du papier au format lettre, une image de 720 x 1 280 pixels peut être requise.

  • Une mise au point médiocre de l'image peut nuire à la précision de la reconnaissance du texte. Si vous n'êtes pas obtenir des résultats acceptables, essayez de demander à l'utilisateur de reprendre l'image.

  • Si vous reconnaissez du texte dans une application en temps réel, vous pouvez également les dimensions globales des images d'entrée. Plus petite les images peuvent être traitées plus rapidement. Pour réduire la latence, capturez-les à une résolution inférieure (en gardant à l'esprit les exigences de précision ci-dessus) ; pour s'assurer que le texte occupe le plus de place possible dans l'image. Voir aussi Conseils pour améliorer les performances en temps réel


Détectez du texte dans des images

Pour reconnaître du texte dans une image à l'aide d'un modèle sur l'appareil ou dans le cloud, exécutez la reconnaissance de texte comme décrit ci-dessous.

1. Exécuter la reconnaissance de texte

Transmettez l'image en tant que "UIImage" ou "CMSampleBufferRef" au paramètre "process(_:completion:)" de "VisionTextRecognizer" méthode:
  1. Obtenez une instance de VisionTextRecognizer en appelant l'une des onDeviceTextRecognizer ou cloudTextRecognizer:

    Swift

    Pour utiliser le modèle sur l'appareil:

    let vision = Vision.vision()
    let textRecognizer = vision.onDeviceTextRecognizer()

    Pour utiliser le modèle cloud:

    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

    Pour utiliser le modèle sur l'appareil:

    FIRVision *vision = [FIRVision vision];
    FIRVisionTextRecognizer *textRecognizer = [vision onDeviceTextRecognizer];

    Pour utiliser le modèle cloud:

    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. Créez un objet VisionImage à l'aide d'un UIImage ou d'un CMSampleBufferRef

    Pour utiliser un UIImage:

    1. Si nécessaire, faites pivoter l'image pour que sa propriété imageOrientation soit .up.
    2. Créez un objet VisionImage en utilisant la rotation correcte UIImage Ne spécifiez aucune métadonnée de rotation (valeur par défaut : (.topLeft).

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    Pour utiliser un CMSampleBufferRef:

    1. Créez un objet VisionImageMetadata qui spécifie le l'orientation des données d'image contenues dans le Mémoire tampon CMSampleBufferRef.

      Pour obtenir l'orientation de l'image:

      Swift

      func imageOrientation(
          deviceOrientation: UIDeviceOrientation,
          cameraPosition: AVCaptureDevice.Position
          ) -> VisionDetectorImageOrientation {
          switch deviceOrientation {
          case .portrait:
              return cameraPosition == .front ? .leftTop : .rightTop
          case .landscapeLeft:
              return cameraPosition == .front ? .bottomLeft : .topLeft
          case .portraitUpsideDown:
              return cameraPosition == .front ? .rightBottom : .leftBottom
          case .landscapeRight:
              return cameraPosition == .front ? .topRight : .bottomRight
          case .faceDown, .faceUp, .unknown:
              return .leftTop
          }
      }

      Objective-C

      - (FIRVisionDetectorImageOrientation)
          imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                                 cameraPosition:(AVCaptureDevicePosition)cameraPosition {
        switch (deviceOrientation) {
          case UIDeviceOrientationPortrait:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationLeftTop;
            } else {
              return FIRVisionDetectorImageOrientationRightTop;
            }
          case UIDeviceOrientationLandscapeLeft:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationBottomLeft;
            } else {
              return FIRVisionDetectorImageOrientationTopLeft;
            }
          case UIDeviceOrientationPortraitUpsideDown:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationRightBottom;
            } else {
              return FIRVisionDetectorImageOrientationLeftBottom;
            }
          case UIDeviceOrientationLandscapeRight:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationTopRight;
            } else {
              return FIRVisionDetectorImageOrientationBottomRight;
            }
          default:
            return FIRVisionDetectorImageOrientationTopLeft;
        }
      }

      Ensuite, créez l'objet de métadonnées:

      Swift

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )

      Objective-C

      FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
      AVCaptureDevicePosition cameraPosition =
          AVCaptureDevicePositionBack;  // Set to the capture device you used.
      metadata.orientation =
          [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                       cameraPosition:cameraPosition];
    2. Créez un objet VisionImage à l'aide de la méthode CMSampleBufferRef et les métadonnées de rotation:

      Swift

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Transmettez ensuite l'image à la méthode process(_:completion:) :

    Swift

    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. Extraire le texte de blocs de texte reconnu

Si l'opération de reconnaissance de texte réussit, elle renvoie une Objet [`VisionText`][VisionText]. Un objet VisionText contient le texte complet reconnu dans l'image et zéro, un ou plusieurs [`VisionTextBlock`][VisionTextBlock] d'objets. Chaque "VisionTextBlock" représente un bloc de texte rectangulaire, qui contient zéro ou plusieurs objets [`VisionTextLine`][VisionTextLine]. Chaque "VisionTextLine" contient zéro, un ou plusieurs objets [`VisionTextElement`][VisionTextElement]. qui représentent des mots et des entités semblables à des mots (dates, nombres, etc.). Pour chaque objet "VisionTextBlock", "VisionTextLine" et "VisionTextElement", pour que le texte soit reconnu dans la région et les coordonnées la région. Exemple :

Swift

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;
    }
  }
}

Conseils pour améliorer les performances en temps réel

Si vous souhaitez utiliser le modèle sur l'appareil pour reconnaître du texte en temps réel application, suivez ces consignes pour obtenir une fréquence d'images optimale:

  • Limitez les appels vers le programme de reconnaissance de texte. Si une nouvelle image vidéo devient disponible lorsque l'outil de reconnaissance de texte est en cours d'exécution, supprimez le cadre.
  • Si vous utilisez la sortie de l'outil de reconnaissance de texte pour superposer des graphiques sur l'image d'entrée, récupérez d'abord le résultat à partir de ML Kit, puis effectuez le rendu de l'image. et les superposer en une seule étape. Cela vous permet d'afficher sur la surface d'affichage une seule fois pour chaque trame d'entrée. Pour en savoir plus, consultez les classes previewOverlayView et FIRDetectionOverlayView dans l'application exemple de démonstration.
  • Envisagez de prendre des images en basse résolution. Cependant, gardez aussi à l'esprit aux exigences de cette API concernant les dimensions de l'image.

Étapes suivantes


Reconnaître le texte dans les images de documents

Pour reconnaître le texte d'un document, configurez et exécutez de documents texte comme décrit ci-dessous.

L'API de reconnaissance de texte de document, décrite ci-dessous, fournit une interface conçue pour faciliter le travail avec des images de documents. Toutefois, Si vous préférez l'interface fournie par l'API de texte creux, vous pouvez l'utiliser au lieu d'analyser des documents, configurez l'outil de reconnaissance de texte cloud utiliser le modèle de texte dense.

Pour utiliser l'API de reconnaissance de document texte:

1. Exécuter la reconnaissance de texte

Transmettez l'image en tant que UIImage ou CMSampleBufferRef à la process(_:completion:) de VisionDocumentTextRecognizer méthode:

  1. Obtenez une instance de VisionDocumentTextRecognizer en appelant cloudDocumentTextRecognizer:

    Swift

    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. Créez un objet VisionImage à l'aide d'un UIImage ou d'un CMSampleBufferRef

    Pour utiliser un UIImage:

    1. Si nécessaire, faites pivoter l'image pour que sa propriété imageOrientation soit .up.
    2. Créez un objet VisionImage en utilisant la rotation correcte UIImage Ne spécifiez aucune métadonnée de rotation (valeur par défaut : (.topLeft).

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    Pour utiliser un CMSampleBufferRef:

    1. Créez un objet VisionImageMetadata qui spécifie le l'orientation des données d'image contenues dans le Mémoire tampon CMSampleBufferRef.

      Pour obtenir l'orientation de l'image:

      Swift

      func imageOrientation(
          deviceOrientation: UIDeviceOrientation,
          cameraPosition: AVCaptureDevice.Position
          ) -> VisionDetectorImageOrientation {
          switch deviceOrientation {
          case .portrait:
              return cameraPosition == .front ? .leftTop : .rightTop
          case .landscapeLeft:
              return cameraPosition == .front ? .bottomLeft : .topLeft
          case .portraitUpsideDown:
              return cameraPosition == .front ? .rightBottom : .leftBottom
          case .landscapeRight:
              return cameraPosition == .front ? .topRight : .bottomRight
          case .faceDown, .faceUp, .unknown:
              return .leftTop
          }
      }

      Objective-C

      - (FIRVisionDetectorImageOrientation)
          imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                                 cameraPosition:(AVCaptureDevicePosition)cameraPosition {
        switch (deviceOrientation) {
          case UIDeviceOrientationPortrait:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationLeftTop;
            } else {
              return FIRVisionDetectorImageOrientationRightTop;
            }
          case UIDeviceOrientationLandscapeLeft:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationBottomLeft;
            } else {
              return FIRVisionDetectorImageOrientationTopLeft;
            }
          case UIDeviceOrientationPortraitUpsideDown:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationRightBottom;
            } else {
              return FIRVisionDetectorImageOrientationLeftBottom;
            }
          case UIDeviceOrientationLandscapeRight:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationTopRight;
            } else {
              return FIRVisionDetectorImageOrientationBottomRight;
            }
          default:
            return FIRVisionDetectorImageOrientationTopLeft;
        }
      }

      Ensuite, créez l'objet de métadonnées:

      Swift

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )

      Objective-C

      FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
      AVCaptureDevicePosition cameraPosition =
          AVCaptureDevicePositionBack;  // Set to the capture device you used.
      metadata.orientation =
          [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                       cameraPosition:cameraPosition];
    2. Créez un objet VisionImage à l'aide de la méthode CMSampleBufferRef et les métadonnées de rotation:

      Swift

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Transmettez ensuite l'image à la méthode process(_:completion:) :

    Swift

    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. Extraire le texte de blocs de texte reconnu

Si l'opération de reconnaissance de texte réussit, elle renvoie une objet VisionDocumentText. Un objet VisionDocumentText contient l'intégralité du texte reconnu dans l'image, ainsi qu'une hiérarchie d'objets qui reflètent la structure du document reconnu:

Pour chaque VisionDocumentTextBlock, VisionDocumentTextParagraph, VisionDocumentTextWord et VisionDocumentTextSymbol, vous pouvez obtenir texte reconnu dans la région et ses coordonnées de délimitation.

Exemple :

Swift

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;
      }
    }
  }
}

Étapes suivantes