Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Reconnaître le texte dans les images avec ML Kit sur iOS

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

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

Avant que tu commences

  1. Si vous n'avez pas encore ajouté Firebase à votre application, faites-le en suivant les étapes du 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, assurez-vous d'ouvrir votre projet Xcode à l'aide de son .xcworkspace .
  3. Dans votre application, importez Firebase :

    Rapide

    import Firebase

    Objectif c

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

    1. Ouvrez la page API du kit ML de la console Firebase.
    2. Si vous n'avez pas encore mis à niveau votre projet vers un plan tarifaire Blaze, cliquez sur Mettre à niveau pour le faire. (Vous serez invité à mettre à niveau uniquement si votre projet n'est pas sur le plan Blaze.)

      Seuls les projets de niveau Blaze peuvent utiliser des API basées sur le cloud.

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

    Si vous souhaitez utiliser uniquement le modèle sur appareil, vous pouvez ignorer cette étape.

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

Directives pour les images d'entrée

  • Pour que ML Kit reconnaisse avec précision le texte, les images d'entrée doivent contenir du texte représenté par suffisamment de données de pixels. Idéalement, pour le texte latin, chaque caractère doit faire au moins 16 x 16 pixels. Pour le texte chinois, japonais et coréen (uniquement pris en charge par les API basées sur le cloud), chaque caractère doit être de 24 x 24 pixels. Pour toutes les langues, il n'y a généralement aucun avantage en termes de précision pour les caractères supérieurs à 24 x 24 pixels.

    Ainsi, par exemple, une image 640x480 peut bien fonctionner pour numériser une carte de visite qui occupe toute la largeur de l'image. Pour numériser un document imprimé sur du papier de format lettre, une image de 720 x 1280 pixels peut être nécessaire.

  • Une mauvaise mise au point de l'image peut nuire à la précision de la reconnaissance de texte. Si vous n'obtenez pas de 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 prendre en compte les dimensions globales des images d'entrée. Les images plus petites peuvent être traitées plus rapidement, donc pour réduire la latence, capturez des images à des résolutions inférieures (en gardant à l'esprit les exigences de précision ci-dessus) et assurez-vous que le texte occupe le plus possible de l'image. Consultez également Conseils pour améliorer les performances en temps réel .


Reconnaître le texte dans les images

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

1. Exécutez la reconnaissance de texte

Passez l'image en tant que `UIImage` ou `CMSampleBufferRef` à la méthode `process(_:completion:)` de `VisionTextRecognizer` :
  1. Obtenez une instance de VisionTextRecognizer en appelant onDeviceTextRecognizer ou cloudTextRecognizer :

    Rapide

    Pour utiliser le modèle sur 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)
    

    Objectif c

    Pour utiliser le modèle sur 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 une UIImage :

    1. Si nécessaire, faites pivoter l'image afin que sa propriété imageOrientation soit .up .
    2. Créez un objet VisionImage à l'aide de l'objet UIImage correctement pivoté. Ne spécifiez aucune métadonnée de rotation—la valeur par défaut, .topLeft , doit être utilisée.

      Rapide

      let image = VisionImage(image: uiImage)

      Objectif c

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

    Pour utiliser un CMSampleBufferRef :

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

      Pour obtenir l'orientation de l'image :

      Rapide

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

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

      Créez ensuite l'objet de métadonnées :

      Rapide

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

      Objectif 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 l'objet CMSampleBufferRef et des métadonnées de rotation :

      Rapide

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

      Objectif c

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Ensuite, passez l'image à la process(_:completion:) :

    Rapide

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

    Objectif c

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

2. Extraire du texte à partir de blocs de texte reconnu

Si l'opération de reconnaissance de texte réussit, elle renverra un objet [`VisionText`][VisionText]. Un objet `VisionText` contient le texte intégral reconnu dans l'image et zéro ou plusieurs objets [`VisionTextBlock`][VisionTextBlock]. Chaque `VisionTextBlock` représente un bloc de texte rectangulaire contenant zéro ou plusieurs objets [`VisionTextLine`][VisionTextLine]. Chaque objet `VisionTextLine` contient zéro 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`, vous pouvez obtenir le texte reconnu dans la région et les coordonnées de délimitation de la région. Par exemple:

Rapide

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

Objectif 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 appareil pour reconnaître du texte dans une application en temps réel, suivez ces instructions pour obtenir les meilleures fréquences d'images :

  • Limiter les appels au logiciel de reconnaissance de texte. Si une nouvelle image vidéo devient disponible alors que la reconnaissance de texte est en cours d'exécution, supprimez l'image.
  • Si vous utilisez la sortie de la reconnaissance de texte pour superposer des graphiques sur l'image d'entrée, obtenez d'abord le résultat de ML Kit, puis affichez l'image et la superposition en une seule étape. Ce faisant, vous effectuez le rendu sur la surface d'affichage une seule fois pour chaque image d'entrée. Voir les classes previewOverlayView et FIRDetectionOverlayView dans l'exemple d'application vitrine pour un exemple.
  • Envisagez de capturer des images à une résolution inférieure. Cependant, gardez également à l'esprit les exigences de dimension d'image de cette API.

Prochaines étapes


Reconnaître du texte dans des images de documents

Pour reconnaître le texte d'un document, configurez et exécutez la reconnaissance de texte de document basée sur le cloud comme décrit ci-dessous.

L'API de reconnaissance de texte de document, décrite ci-dessous, fournit une interface conçue pour être plus pratique pour travailler avec des images de documents. Toutefois, si vous préférez l'interface fournie par l'API de texte clairsemé, vous pouvez l'utiliser à la place pour numériser des documents en configurant la reconnaissance de texte en nuage pour utiliser le modèle de texte dense .

Pour utiliser l'API de reconnaissance de texte de document :

1. Exécutez la reconnaissance de texte

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

  1. Obtenez une instance de VisionDocumentTextRecognizer en appelant cloudDocumentTextRecognizer :

    Rapide

    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)
    

    Objectif 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 une UIImage :

    1. Si nécessaire, faites pivoter l'image afin que sa propriété imageOrientation soit .up .
    2. Créez un objet VisionImage à l'aide de l'objet UIImage correctement pivoté. Ne spécifiez aucune métadonnée de rotation—la valeur par défaut, .topLeft , doit être utilisée.

      Rapide

      let image = VisionImage(image: uiImage)

      Objectif c

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

    Pour utiliser un CMSampleBufferRef :

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

      Pour obtenir l'orientation de l'image :

      Rapide

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

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

      Créez ensuite l'objet de métadonnées :

      Rapide

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

      Objectif 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 l'objet CMSampleBufferRef et des métadonnées de rotation :

      Rapide

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

      Objectif c

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Ensuite, passez l'image à la process(_:completion:) :

    Rapide

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

    Objectif c

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

2. Extraire du texte à partir de blocs de texte reconnu

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

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

Par exemple:

Rapide

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

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

Prochaines étapes