Mit ML Kit unter iOS Text in Bildern erkennen

Sie können ML Kit verwenden, um Text in Bildern zu erkennen. ML Kit hat sowohl ein API für allgemeine Zwecke, die zum Erkennen von Text in Bildern geeignet ist, z. B. und einer API, die für die Erkennung des Textes Dokumente. Die API für allgemeine Zwecke bietet sowohl On-Device- als auch cloudbasierte Modelle. Die Erkennung von Dokumenttext ist nur als cloudbasiertes Modell verfügbar. Weitere Informationen finden Sie in der Übersicht für einen Vergleich der Cloud- und On-Device-Modelle.

Hinweis

  1. Wenn Sie Ihrer App noch nicht Firebase hinzugefügt haben, folgen Sie der im Startleitfaden.
  2. Fügen Sie die ML Kit-Bibliotheken in Ihre Podfile-Datei ein:
    pod 'Firebase/MLVision', '6.25.0'
    # If using an on-device API:
    pod 'Firebase/MLVisionTextModel', '6.25.0'
    
    Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, öffnen Sie unbedingt Ihren Xcode mithilfe der .xcworkspace zu erstellen.
  3. Importieren Sie Firebase in Ihre App:

    Swift

    import Firebase

    Objective-C

    @import Firebase;
  4. Wenn Sie das cloudbasierte Modell verwenden möchten und es noch nicht aktiviert haben die cloudbasierten APIs für Ihr Projekt zu nutzen, tun Sie dies jetzt:

    1. ML Kit öffnen API-Seite der Firebase-Konsole.
    2. Wenn Sie für Ihr Projekt noch kein Upgrade auf ein Blaze-Preismodell durchgeführt haben, klicken Sie auf Führen Sie ein Upgrade durch. Sie werden nur dann zum Upgrade aufgefordert, Projekt nicht im Tarif "Blaze" ist.)

      Nur Projekte auf Blaze-Ebene können cloudbasierte APIs verwenden.

    3. Wenn cloudbasierte APIs noch nicht aktiviert sind, klicken Sie auf Cloudbasierte APIs aktivieren.

    Wenn Sie nur das On-Device-Modell verwenden möchten, können Sie diesen Schritt überspringen.

Jetzt können Sie mit der Texterkennung in Bildern beginnen.

Richtlinien für Eingabebilder

  • Damit ML Kit Text richtig erkennt, müssen die Eingabebilder Folgendes enthalten: Text, der durch ausreichende Pixeldaten dargestellt wird. Ideal für Latein Text eingeben, muss jedes Zeichen mindestens 16 x 16 Pixel groß sein. Für Chinesisch: Japanischer und koreanischer Text (nur von den cloudbasierten APIs unterstützt), jeweils sollte 24 x 24 Pixel groß sein. In der Regel gibt es für alle Sprachen Verbesserung der Genauigkeit bei Zeichen, die größer als 24 x 24 Pixel sind.

    So eignet sich beispielsweise ein Bild mit einer Auflösung von 640 × 480 Pixeln gut zum Scannen einer Visitenkarte, die die gesamte Breite des Bildes einnimmt. Wenn Sie ein Dokument scannen möchten, das auf Papier im Letter-Format gedruckt wurde, ist möglicherweise ein Bild mit 720 × 1.280 Pixeln erforderlich.

  • Ein unscharfer Bildfokus kann die Genauigkeit der Texterkennung beeinträchtigen. Wenn nicht akzeptable Ergebnisse erzielen, versuchen Sie, das Bild erneut aufzunehmen.

  • Wenn Sie Text in einer Echtzeitanwendung erkennen, die Gesamtabmessungen der eingegebenen Bilder berücksichtigen. Kleiner Bilder schneller verarbeitet werden. Um die Latenz zu verringern, niedrigere Auflösungen (unter Berücksichtigung der oben genannten Anforderungen an die Genauigkeit) und Stellen Sie sicher, dass der Text einen möglichst großen Teil des Bildes einnimmt. Siehe auch Tipps zum Verbessern der Leistung in Echtzeit


Erkennt Text in Bildern

Um Text in einem Bild mit einem gerätebasierten oder cloudbasierten Modell zu erkennen, führen Sie die Texterkennung wie unten beschrieben aus.

1. Texterkennung ausführen

Übergeben Sie das Bild als UIImage oder CMSampleBufferRef an die Methode „process(_:completion:)“ von VisionTextRecognizer:
  1. Rufen Sie eine Instanz von VisionTextRecognizer ab, indem Sie entweder onDeviceTextRecognizer oder cloudTextRecognizer:

    Swift

    So verwenden Sie das On-Device-Modell:

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

    So verwenden Sie das Cloud-Modell:

    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

    So verwenden Sie das On-Device-Modell:

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

    So verwenden Sie das Cloud-Modell:

    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. Erstellen Sie ein VisionImage-Objekt mithilfe von UIImage oder einem CMSampleBufferRef

    So verwenden Sie ein UIImage:

    1. Drehen Sie das Bild bei Bedarf so, dass die imageOrientation-Property .up ist.
    2. Erstellen Sie ein VisionImage-Objekt mithilfe der korrekt gedrehten UIImage. Geben Sie keine Rotationsmetadaten an. Dies ist die Standardeinstellung. Wert .topLeft muss verwendet werden.

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

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

    So verwendest du CMSampleBufferRef:

    1. Erstellen Sie ein VisionImageMetadata-Objekt, das die Ausrichtung der Bilddaten im CMSampleBufferRef-Zwischenspeicher.

      So ermitteln Sie die Bildausrichtung:

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

      Erstellen Sie dann das Metadatenobjekt:

      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. Erstellen Sie ein VisionImage-Objekt mithilfe der CMSampleBufferRef-Objekt und die Rotationsmetadaten:

      Swift

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

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Übergeben Sie dann das Bild an die Methode 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. Text aus Blöcken erkannten Texts extrahieren

Wenn der Vorgang der Texterkennung erfolgreich ist, wird ein [`VisionText`][VisionText]-Objekt. Ein „VisionText“-Objekt enthält den vollständigen Text im Bild erkannt und null oder mehr [`VisionTextBlock`][VisionTextBlock] Objekte. Jeder „VisionTextBlock“ stellt einen rechteckigen Textblock dar, der Folgendes enthält: Null oder mehr [`VisionTextLine`][VisionTextLine]-Objekte. Jedes VisionTextLine-Objekt enthält null oder mehr [`VisionTextElement`][VisionTextElement]-Objekte, die Wörter und wortähnliche Entitäten (z. B. Datumsangaben und Zahlen) darstellen. Führen Sie für jedes „VisionTextBlock“-, „VisionTextLine“- und „VisionTextElement“-Objekt“ die folgenden Schritte aus: können Sie den in der Region erkannten Text und die Begrenzungskoordinaten die Region. Beispiel:

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

Tipps zum Verbessern der Leistung in Echtzeit

Wenn das On-Device-Modell Text in Echtzeit erkennen soll -App sollten Sie die folgenden Richtlinien beachten, um optimale Framerates zu erzielen:

  • Drosselung von Aufrufen an die Texterkennung Wenn ein neuer Videoframe wenn die Texterkennung ausgeführt wird, lassen Sie den Frame weg.
  • Wenn Sie die Ausgabe der Texterkennung verwenden, um Grafiken Eingabebild, rufen Sie zuerst das Ergebnis aus ML Kit ab und rendern Sie das Bild in einem Schritt übereinanderlegen. Dadurch rendern Sie auf der Anzeigeoberfläche für jeden Eingabe-Frame nur einmal. Weitere Informationen finden Sie unter previewOverlayView. und FIRDetectionOverlayView in der Showcase-Beispiel-App als Beispiel.
  • Nehmen Sie Bilder mit einer niedrigeren Auflösung auf. Beachten Sie jedoch auch, Anforderungen an die Bildabmessungen dieser API.

Nächste Schritte


Text in Bildern von Dokumenten erkennen

Um den Text eines Dokuments zu erkennen, konfigurieren Sie das cloudbasierte die Dokumenttexterkennung, wie unten beschrieben.

Die unten beschriebene API zur Texterkennung in Dokumenten bietet eine Oberfläche, die die Arbeit mit Bildern von Dokumenten vereinfachen soll. Wenn Sie jedoch die von der Sparse Text API bereitgestellte Benutzeroberfläche bevorzugen, können Sie sie stattdessen zum Scannen von Dokumenten verwenden. Konfigurieren Sie dazu den Cloud-Texterkennungsdienst so, dass das Modell für dichten Text verwendet wird.

So verwenden Sie die API zur Texterkennung in Dokumenten:

1. Texterkennung ausführen

Übergeben Sie das Bild als UIImage oder CMSampleBufferRef an den process(_:completion:) von VisionDocumentTextRecognizer :

  1. Rufen Sie eine VisionDocumentTextRecognizer-Instanz mit dem folgenden Befehl ab: 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. Erstellen Sie ein VisionImage-Objekt mithilfe von UIImage oder einem CMSampleBufferRef

    So verwenden Sie ein UIImage:

    1. Drehen Sie das Bild bei Bedarf so, dass die imageOrientation-Property .up ist.
    2. Erstellen Sie ein VisionImage-Objekt mithilfe der korrekt gedrehten UIImage. Geben Sie keine Rotationsmetadaten an. Dies ist die Standardeinstellung. Wert .topLeft muss verwendet werden.

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

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

    So verwendest du CMSampleBufferRef:

    1. Erstellen Sie ein VisionImageMetadata-Objekt, das die Ausrichtung der Bilddaten im CMSampleBufferRef-Zwischenspeicher.

      So ermitteln Sie die Bildausrichtung:

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

      Erstellen Sie dann das Metadatenobjekt:

      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. Erstellen Sie ein VisionImage-Objekt mithilfe der CMSampleBufferRef-Objekt und die Rotationsmetadaten:

      Swift

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

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Übergeben Sie dann das Bild an die Methode 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. Text aus erkannten Textblöcken extrahieren

Wenn der Vorgang zur Texterkennung erfolgreich war, wird ein VisionDocumentText-Objekt zurückgegeben. Ein VisionDocumentText-Objekt enthält den vollständigen im Bild erkannten Text und eine Hierarchie von Objekten, die müssen die Struktur des anerkannten Dokuments widerspiegeln:

Für jeden VisionDocumentTextBlock, VisionDocumentTextParagraph, VisionDocumentTextWord und VisionDocumentTextSymbol können Sie das Objekt in der Region erkannten Text und die Begrenzungskoordinaten der Region.

Beispiel:

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

Nächste Schritte