Puedes usar ML Kit para reconocer texto en imágenes o videos, como el texto de un letrero de la calle. Las principales características de esta función son las siguientes:
| API de Text Recognition v2 | |
|---|---|
| Descripción | Reconoce texto en imágenes o videos, admite secuencias de comandos latinas, chinas, devanagari, japonesas y coreanas, y una amplia variedad de idiomas. |
| Nombres del SDK | GoogleMLKit/TextRecognition |
| Implementación | Los recursos se vinculan de forma estática a tu app en el tiempo de compilación. |
| Impacto en el tamaño de la app | Aproximadamente 38 MB por SDK de secuencia de comandos |
| Rendimiento | En tiempo real en la mayoría de los dispositivos para el SDK de secuencias de comandos latinas, más lento para otros |
Probar
- Juega con la app de ejemplo para ver un ejemplo de uso de esta API.
- Prueba el código por tu cuenta con el codelab.
Antes de comenzar
- Incluye los siguientes pods de ML Kit en tu Podfile:
# To recognize Latin script pod 'GoogleMLKit/TextRecognition', '8.0.0' # To recognize Chinese script pod 'GoogleMLKit/TextRecognitionChinese', '8.0.0' # To recognize Devanagari script pod 'GoogleMLKit/TextRecognitionDevanagari', '8.0.0' # To recognize Japanese script pod 'GoogleMLKit/TextRecognitionJapanese', '8.0.0' # To recognize Korean script pod 'GoogleMLKit/TextRecognitionKorean', '8.0.0'
- Después de instalar o actualizar los pods de tu proyecto, abre el proyecto de Xcode con su
.xcworkspace. ML Kit es compatible con Xcode 12.4 o versiones posteriores.
1. Crea una instancia de TextRecognizer.
Para crear una instancia de TextRecognizer, llama a
+textRecognizer(options:) y pasa las opciones relacionadas con el SDK que declaraste como
dependencia anteriormente:
Swift
// When using Latin script recognition SDK let latinOptions = TextRecognizerOptions() let latinTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Chinese script recognition SDK let chineseOptions = ChineseTextRecognizerOptions() let chineseTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Devanagari script recognition SDK let devanagariOptions = DevanagariTextRecognizerOptions() let devanagariTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Japanese script recognition SDK let japaneseOptions = JapaneseTextRecognizerOptions() let japaneseTextRecognizer = TextRecognizer.textRecognizer(options:options) // When using Korean script recognition SDK let koreanOptions = KoreanTextRecognizerOptions() let koreanTextRecognizer = TextRecognizer.textRecognizer(options:options)
Objective-C
// When using Latin script recognition SDK MLKTextRecognizerOptions *latinOptions = [[MLKTextRecognizerOptions alloc] init]; MLKTextRecognizer *latinTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Chinese script recognition SDK MLKChineseTextRecognizerOptions *chineseOptions = [[MLKChineseTextRecognizerOptions alloc] init]; MLKTextRecognizer *chineseTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Devanagari script recognition SDK MLKDevanagariTextRecognizerOptions *devanagariOptions = [[MLKDevanagariTextRecognizerOptions alloc] init]; MLKTextRecognizer *devanagariTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Japanese script recognition SDK MLKJapaneseTextRecognizerOptions *japaneseOptions = [[MLKJapaneseTextRecognizerOptions alloc] init]; MLKTextRecognizer *japaneseTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options]; // When using Korean script recognition SDK MLKKoreanTextRecognizerOptions *koreanOptions = [[MLKKoreanTextRecognizerOptions alloc] init]; MLKTextRecognizer *koreanTextRecognizer = [MLKTextRecognizer textRecognizerWithOptions:options];
2. Prepara la imagen de entrada
Pasa la imagen como unaUIImage o una CMSampleBufferRef al
TextRecognizer's process(_:completion:) método:
Crea un objeto VisionImage con un UIImage o un
CMSampleBuffer.
Si usas una UIImage, sigue estos pasos:
- Crea un
VisionImageobjeto con laUIImage. Asegúrate de especificar la.orientationcorrecta.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Si usas un CMSampleBuffer, sigue estos pasos:
-
Especifica la orientación de los datos de imagen contenidos en el
CMSampleBuffer.Para obtener la orientación de la imagen, haz lo siguiente:
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; } }
- Crea un objeto
VisionImagecon elCMSampleBufferobjeto y la orientación: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. Procesa la imagen
Por último, pasa la imagen al método 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. Extrae texto de bloques de texto reconocido
Si la operación de reconocimiento de texto se ejecuta correctamente, se mostrará un
Text objeto. Un objeto Text contiene el texto completo
reconocido en la imagen, y cero o más objetos TextBlock.
Cada TextBlock representa un bloque rectangular de texto que
contiene cero o más objetos TextLine. Cada TextLine
objeto contiene cero o más TextElement objetos,
que representan palabras y entidades similares a palabras, como fechas y números.
Para cada objeto TextBlock, TextLine y
TextElement, puedes obtener el texto reconocido en la
región y las coordenadas que limitan la región.
Por ejemplo:
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;
}
}
}Lineamientos para imágenes de entrada
-
Para que ML Kit reconozca texto con exactitud, las imágenes de entrada deben contener texto representado con datos de píxeles suficientes. Lo ideal es que cada carácter sea de al menos 16 × 16 píxeles. Generalmente, no se obtiene un beneficio de exactitud cuando el tamaño de los caracteres es superior a 24 × 24 píxeles.
Por ejemplo, una imagen de 640 × 480 puede funcionar bien para escanear una tarjeta de presentación que ocupa todo el ancho de la imagen. Para escanear un documento impreso en tamaño de papel carta, es posible que se requiera una imagen de 720 × 1,280 píxeles.
-
Un enfoque de imagen deficiente puede afectar la exactitud del reconocimiento de texto. Si no obtienes resultados aceptables, intenta pedirle al usuario que vuelva a capturar la imagen.
-
Si reconoces texto en una aplicación en tiempo real, te recomendamos tener en cuenta las dimensiones generales de las imágenes de entrada. Las imágenes más pequeñas se pueden procesar más rápido. Para reducir la latencia, asegúrate de que el texto ocupe la mayor porción de la imagen que sea posible y captura las imágenes con resoluciones más bajas (teniendo en cuenta los requisitos de exactura anteriores). Para obtener más información, consulta Sugerencias para mejorar el rendimiento.
Sugerencias para mejorar el rendimiento
- Para procesar fotogramas de video, usa la API síncrona
results(in:)del detector. Llama a este método desde laAVCaptureVideoDataOutputSampleBufferDelegate'scaptureOutput(_, didOutput:from:)función para obtener de forma síncrona los resultados del fotograma de video determinado. ManténAVCaptureVideoDataOutputdealwaysDiscardsLateVideoFramescomotruepara limitar las llamadas al detector. Si hay un fotograma de video nuevo disponible mientras se ejecuta el detector, se descartará. - Si estás usando la salida del detector para superponer gráficos en la imagen de entrada, primero obtén el resultado de la detección de ML Kit y, luego, procesa la imagen y la superposición en un solo paso. De esta manera, procesas en la superficie de visualización solo una vez por cada fotograma de entrada procesado. Consulta updatePreviewOverlayViewWithLastFrame en la muestra de inicio rápido del ML Kit para ver un ejemplo.
- Captura imágenes con una resolución más baja. Sin embargo, también ten en cuenta los requisitos de dimensiones de imágenes de esta API.
- Para evitar una posible degradación del rendimiento, no ejecutes varias
TextRecognizerinstancias con diferentes opciones de secuencia de comandos de forma simultánea.