Mit ML Kit können Sie Text in Bildern erkennen. ML Kit bietet sowohl eine Allzweck-API, die sich zum Erkennen von Text in Bildern eignet, z. B. Text auf einem Straßenschild, als auch eine API, die für das Erkennen von Text in Dokumenten optimiert ist. Die Allzweck-API bietet sowohl Modelle auf dem Gerät als auch cloudbasierte Modelle. Die Texterkennung in Dokumenten ist nur als cloudbasiertes Modell verfügbar. Einen Vergleich der Cloud- und On-Device-Modelle finden Sie in der Übersicht.
Hinweis
- Wenn Sie Firebase noch nicht in Ihre App eingebunden haben, folgen Sie der Anleitung im Leitfaden für den Einstieg.
- Fügen Sie die ML Kit-Bibliotheken in Ihre Podfile ein:
Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, müssen Sie Ihr Xcode-Projekt über die Dateipod 'Firebase/MLVision', '6.25.0' # If using an on-device API: pod 'Firebase/MLVisionTextModel', '6.25.0'
.xcworkspace
öffnen. - Importieren Sie Firebase in Ihre App:
Swift
import Firebase
Objective-C
@import Firebase;
-
Wenn Sie das cloudbasierte Modell verwenden möchten und die cloudbasierten APIs für Ihr Projekt noch nicht aktiviert haben, tun Sie dies jetzt:
- Öffnen Sie in der Firebase-Konsole die Seite ML Kit APIs.
-
Wenn Sie Ihr Projekt noch nicht auf den Blaze-Tarif umgestellt haben, klicken Sie auf Upgrade, um dies zu tun. (Sie werden nur dann zum Upgrade aufgefordert, wenn Ihr Projekt nicht im Blaze-Tarif ist.)
Cloudbasierte APIs können nur in Projekten auf Blaze-Ebene verwendet werden.
- 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 Text von ML Kit genau erkannt werden kann, müssen Eingabebilder Text enthalten, der durch ausreichend Pixeldaten dargestellt wird. Idealerweise sollte jedes Zeichen bei lateinischem Text mindestens 16 × 16 Pixel groß sein. Bei chinesischem, japanischem und koreanischem Text (nur von den cloudbasierten APIs unterstützt) sollte jedes Zeichen 24 × 24 Pixel groß sein. Bei allen Sprachen ist die Genauigkeit bei Zeichen, die größer als 24 × 24 Pixel sind, in der Regel nicht höher.
Ein Bild mit 640 × 480 Pixeln eignet sich beispielsweise gut zum Scannen einer Visitenkarte, die die gesamte Breite des Bildes einnimmt. Wenn Sie ein auf Papier im Letter-Format gedrucktes Dokument scannen möchten, ist möglicherweise ein Bild mit 720 × 1.280 Pixeln erforderlich.
-
Eine schlechte Bildschärfe kann die Genauigkeit der Texterkennung beeinträchtigen. Wenn Sie keine akzeptablen Ergebnisse erhalten, bitten Sie den Nutzer, das Bild noch einmal aufzunehmen.
-
Wenn Sie Text in einer Echtzeitanwendung erkennen, sollten Sie auch die Gesamtabmessungen der Eingabebilder berücksichtigen. Kleinere Bilder können schneller verarbeitet werden. Um die Latenz zu verringern, sollten Sie Bilder mit niedrigeren Auflösungen aufnehmen (unter Berücksichtigung der oben genannten Anforderungen an die Genauigkeit) und darauf achten, dass der Text so viel wie möglich vom Bild einnimmt. Weitere Informationen finden Sie unter Tipps zur Verbesserung der Echtzeitleistung.
Erkennt Text in Bildern
Wenn Sie Text in einem Bild mit einem geräteinternen oder Cloud-basierten Modell erkennen möchten, 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`:- Sie erhalten eine Instanz von
VisionTextRecognizer
, indem Sie entwederonDeviceTextRecognizer
odercloudTextRecognizer
aufrufen: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];
-
Erstellen Sie ein
VisionImage
-Objekt mit einemUIImage
oder einemCMSampleBufferRef
.So verwenden Sie ein
UIImage
:- Drehen Sie das Bild bei Bedarf so, dass die Property
imageOrientation
den Wert.up
hat. - Erstellen Sie ein
VisionImage
-Objekt mit dem korrekt gedrehtenUIImage
. Geben Sie keine Metadaten zur Drehung an. Es muss der Standardwert.topLeft
verwendet werden.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
So verwenden Sie ein
CMSampleBufferRef
:-
Erstellen Sie ein
VisionImageMetadata
-Objekt, das die Ausrichtung der Bilddaten imCMSampleBufferRef
-Puffer angibt.So rufen Sie die Bildausrichtung ab:
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];
- Erstellen Sie ein
VisionImage
-Objekt mit demCMSampleBufferRef
-Objekt und den Rotationsmetadaten:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Drehen Sie das Bild bei Bedarf so, dass die Property
-
Übergeben Sie das Bild dann an die
process(_:completion:)
-Methode: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 mit erkanntem Text extrahieren
Wenn der Vorgang zur Texterkennung erfolgreich ist, wird ein [`VisionText`][VisionText]-Objekt zurückgegeben. Ein `VisionText`-Objekt enthält den gesamten im Bild erkannten Text und null oder mehr [`VisionTextBlock`][VisionTextBlock]-Objekte. Jeder `VisionTextBlock` stellt einen rechteckigen Textblock dar, der null oder mehr [`VisionTextLine`][VisionTextLine]-Objekte enthält. Jedes `VisionTextLine`-Objekt enthält null oder mehr [`VisionTextElement`][VisionTextElement]-Objekte, die Wörter und wortähnliche Einheiten (Datumsangaben, Zahlen usw.) darstellen. Für jedes Objekt vom Typ `VisionTextBlock`, `VisionTextLine` und `VisionTextElement` können Sie den in der Region erkannten Text und die Begrenzungskoordinaten der Region abrufen. 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 zur Verbesserung der Echtzeitleistung
Wenn Sie das On-Device-Modell verwenden möchten, um Text in einer Echtzeitanwendung zu erkennen, sollten Sie die folgenden Richtlinien beachten, um die besten Framerates zu erzielen:
- Drosseln Sie Aufrufe des Texterkennungssystems. Wenn ein neuer Videoframes verfügbar wird, während die Texterkennung ausgeführt wird, verwerfen Sie den Frame.
- Wenn Sie die Ausgabe der Texterkennung verwenden, um Grafiken auf das Eingabebild zu legen, rufen Sie zuerst das Ergebnis von ML Kit ab und rendern Sie dann das Bild und das Overlay in einem einzigen Schritt. Dadurch wird für jeden Eingabe-Frame nur einmal auf die Displayoberfläche gerendert. Ein Beispiel finden Sie in den Klassen previewOverlayView und FIRDetectionOverlayView in der Showcase-Beispiel-App.
- Nehmen Sie Bilder mit einer niedrigeren Auflösung auf. Beachten Sie jedoch auch die Anforderungen an die Bildabmessungen für diese API.
Nächste Schritte
- Bevor Sie eine App, die eine Cloud API verwendet, in der Produktionsumgebung bereitstellen, sollten Sie einige zusätzliche Schritte unternehmen, um unbefugten API-Zugriff zu verhindern und seine Auswirkungen zu minimieren.
Text in Bildern von Dokumenten erkennen
Wenn Sie den Text eines Dokuments erkennen möchten, konfigurieren Sie den cloudbasierten Dokumenttexterkenner und führen Sie ihn wie unten beschrieben aus.
Die unten beschriebene API zur Texterkennung in Dokumenten bietet eine Schnittstelle, die für die Arbeit mit Bildern von Dokumenten gedacht ist. Wenn Sie jedoch die von der Sparse Text API bereitgestellte Schnittstelle bevorzugen, können Sie sie stattdessen zum Scannen von Dokumenten verwenden, indem Sie den Cloud-Texterkenner so konfigurieren, dass er das Dense Text-Modell verwendet.
So verwenden Sie die API zur Texterkennung in Dokumenten:
1. Texterkennung ausführen
Übergeben Sie das Bild alsUIImage
oder CMSampleBufferRef
an die process(_:completion:)
-Methode von VisionDocumentTextRecognizer
:
- Rufen Sie eine Instanz von
VisionDocumentTextRecognizer
ab, indem SiecloudDocumentTextRecognizer
aufrufen: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];
-
Erstellen Sie ein
VisionImage
-Objekt mit einemUIImage
oder einemCMSampleBufferRef
.So verwenden Sie ein
UIImage
:- Drehen Sie das Bild bei Bedarf so, dass die Property
imageOrientation
den Wert.up
hat. - Erstellen Sie ein
VisionImage
-Objekt mit dem korrekt gedrehtenUIImage
. Geben Sie keine Metadaten zur Drehung an. Es muss der Standardwert.topLeft
verwendet werden.Swift
let image = VisionImage(image: uiImage)
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];
So verwenden Sie ein
CMSampleBufferRef
:-
Erstellen Sie ein
VisionImageMetadata
-Objekt, das die Ausrichtung der Bilddaten imCMSampleBufferRef
-Puffer angibt.So rufen Sie die Bildausrichtung ab:
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];
- Erstellen Sie ein
VisionImage
-Objekt mit demCMSampleBufferRef
-Objekt und den Rotationsmetadaten:Swift
let image = VisionImage(buffer: sampleBuffer) image.metadata = metadata
Objective-C
FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer]; image.metadata = metadata;
- Drehen Sie das Bild bei Bedarf so, dass die Property
-
Übergeben Sie das Bild dann an die
process(_:completion:)
-Methode: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 Blöcken mit erkanntem Text extrahieren
Wenn die Texterkennung erfolgreich ist, wird einVisionDocumentText
-Objekt zurückgegeben. Ein VisionDocumentText
-Objekt enthält den gesamten im Bild erkannten Text und eine Hierarchie von Objekten, die die Struktur des erkannten Dokuments widerspiegelt:
Für jedes VisionDocumentTextBlock
-, VisionDocumentTextParagraph
-, VisionDocumentTextWord
- und VisionDocumentTextSymbol
-Objekt können Sie den in der Region erkannten Text und die Begrenzungskoordinaten der Region abrufen.
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
- Bevor Sie eine App, die eine Cloud API verwendet, in der Produktionsumgebung bereitstellen, sollten Sie einige zusätzliche Schritte unternehmen, um unbefugten API-Zugriff zu verhindern und seine Auswirkungen zu minimieren.