Mit ML Kit können Sie Text in Bildern oder Videos erkennen, z. B. den Text eines Straßenschilds. Die Hauptmerkmale dieser Funktion sind:
Text Recognition API | |
---|---|
Beschreibung | Erkennt lateinischen Text in Bildern oder Videos. |
SDK-Name | GoogleMLKit/TextRecognition (version 2.2.0) |
Implementierung | Assets werden bei der Erstellung statisch mit Ihrer App verknüpft. |
Auswirkungen auf die App-Größe | Etwa 20 MB |
Leistung | In Echtzeit auf den meisten Geräten. |
Testen
- Probieren Sie die Beispiel-App aus, um sich ein Anwendungsbeispiel dieser API anzusehen.
- Probiere den Code selbst mit dem Codelab aus.
Hinweis
- Fügen Sie die folgenden ML Kit-Pods in Ihre Podfile ein:
pod 'GoogleMLKit/TextRecognition','2.2.0'
- Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, öffnen Sie das Xcode-Projekt mit dessen
.xcworkspace
. ML Kit wird ab Xcode Version 12.4 unterstützt.
1. Instanz von TextRecognizer
erstellen
Erstellen Sie eine Instanz von TextRecognizer
, indem Sie +textRecognizer
aufrufen:
Swift
let textRecognizer = TextRecognizer.textRecognizer()
Objective-C
MLKTextRecognizer *textRecognizer = [MLKTextRecognizer textRecognizer];
2. Eingabebild vorbereiten
Übergeben Sie das Bild alsUIImage
oder CMSampleBufferRef
an die Methode process(_:completion:)
von TextRecognizer
:
Erstellen Sie ein VisionImage
-Objekt mit einem UIImage
oder einem CMSampleBuffer
.
Wenn Sie UIImage
verwenden, gehen Sie so vor:
- Erstellen Sie ein
VisionImage
-Objekt mitUIImage
. Achten Sie darauf, die richtige.orientation
anzugeben.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Wenn Sie CMSampleBuffer
verwenden, gehen Sie so vor:
-
Gib die Ausrichtung der Bilddaten an, die in
CMSampleBuffer
enthalten sind.So erhalten Sie die Bildausrichtung:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- Erstellen Sie ein
VisionImage
-Objekt mit dem ObjektCMSampleBuffer
und der Ausrichtung:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. Bild verarbeiten
Übergeben Sie dann das Bild an die Methode process(_:completion:)
:
Swift
textRecognizer.process(visionImage) { result, error in guard error == nil, let result = result else { // Error handling return } // Recognized text }
Objective-C
[textRecognizer processImage:image completion:^(MLKText *_Nullable result, NSError *_Nullable error) { if (error != nil || result == nil) { // Error handling return; } // Recognized text }];
4. Text aus Textblöcken erkennen
Wenn die Texterkennung erfolgreich ist, wird ein Text
-Objekt zurückgegeben. Ein Text
-Objekt enthält den vollständigen Text im Bild und null oder mehr TextBlock
-Objekte.
Jeder TextBlock
steht für einen rechteckigen Textblock, der null oder mehr TextLine
-Objekte enthält. Jedes TextLine
-Objekt enthält null oder mehr TextElement
-Objekte, die Wörter und wortähnliche Entitäten wie Datumsangaben und Zahlen darstellen.
Für jedes Objekt vom Typ TextBlock
, TextLine
und TextElement
kann der Text in der Region und die Begrenzungskoordinaten der Region erkannt werden.
Beispiel:
Swift
let resultText = result.text for block in result.blocks { let blockText = block.text let blockLanguages = block.recognizedLanguages let blockCornerPoints = block.cornerPoints let blockFrame = block.frame for line in block.lines { let lineText = line.text let lineLanguages = line.recognizedLanguages let lineCornerPoints = line.cornerPoints let lineFrame = line.frame for element in line.elements { let elementText = element.text let elementCornerPoints = element.cornerPoints let elementFrame = element.frame } } }
Objective-C
NSString *resultText = result.text; for (MLKTextBlock *block in result.blocks) { NSString *blockText = block.text; NSArray<MLKTextRecognizedLanguage *> *blockLanguages = block.recognizedLanguages; NSArray<NSValue *> *blockCornerPoints = block.cornerPoints; CGRect blockFrame = block.frame; for (MLKTextLine *line in block.lines) { NSString *lineText = line.text; NSArray<MLKTextRecognizedLanguage *> *lineLanguages = line.recognizedLanguages; NSArray<NSValue *> *lineCornerPoints = line.cornerPoints; CGRect lineFrame = line.frame; for (MLKTextElement *element in line.elements) { NSString *elementText = element.text; NSArray<NSValue *> *elementCornerPoints = element.cornerPoints; CGRect elementFrame = element.frame; } } }
Richtlinien für Eingabebilder
-
Damit ML Kit Text präzise erkennen kann, müssen Eingabebilder Text enthalten, der durch genügend Pixeldaten dargestellt wird. Idealerweise sollte jedes Zeichen mindestens 16 x 16 Pixel groß sein. Zeichen, die größer als 24 x 24 Pixel sind, haben im Allgemeinen keinen Vorteil.
Ein Bild mit 640 × 480 kann also gut zum Scannen einer Visitenkarte verwendet werden, die die volle Breite des Bildes einnimmt. Zum Scannen eines Dokuments, das auf Briefpapier gedruckt wird, ist möglicherweise ein Bild mit 720 x 1280 Pixeln erforderlich.
-
Ein schlechter Bildfokus kann die Genauigkeit der Texterkennung beeinträchtigen. Wenn du keine akzeptablen Ergebnisse erhältst, bitte den Nutzer, das Bild noch einmal aufzunehmen.
-
Wenn Sie Text in einer Echtzeitanwendung erkennen, sollten Sie die Gesamtabmessungen der Eingabebilder berücksichtigen. Kleinere Bilder können schneller verarbeitet werden. Damit die Latenz verringert wird, muss der Text einen möglichst großen Teil des Bilds einnehmen und Bilder mit niedrigerer Auflösung erfassen. Beachte dabei die oben genannten Anforderungen an die Genauigkeit. Weitere Informationen finden Sie unter Tipps zur Leistungssteigerung.
Tipps zur Verbesserung der Leistung
- Verwenden Sie zur Verarbeitung von Videoframes die synchrone API des Detektors
results(in:)
. Rufen Sie diese Methode über diecaptureOutput(_, didOutput:from:)
-Funktion derAVCaptureVideoDataOutputSampleBufferDelegate
auf, um synchron Ergebnisse aus dem angegebenen Videoframe zu erhalten. Behalten SiealwaysDiscardsLateVideoFrames
vonAVCaptureVideoDataOutput
alstrue
bei, um Aufrufe an den Detektor zu drosseln. Wenn während der Ausführung des Detektors ein neuer Videoframe verfügbar ist, wird er verworfen. - Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken auf dem Eingabebild einzublenden, rufen Sie zuerst das Ergebnis aus ML Kit ab und rendern dann das Bild und das Overlay in einem einzigen Schritt. Dadurch wird die Anzeige für jeden verarbeiteten Eingabeframe nur einmal auf der Anzeigeoberfläche gerendert. Ein Beispiel findest du in der Kurzanleitung zu updatePreviewOverlayViewWithLastFrame.
- Bilder mit einer geringeren Auflösung aufnehmen Beachten Sie jedoch die Anforderungen an die Bildabmessungen dieser API.