É possível usar o Kit de ML para reconhecer texto em imagens ou vídeos, como o texto de uma placa de rua. As principais características desse recurso são:
API Text Recognition v2 | |
---|---|
Descrição | Reconhece texto em imagens ou vídeos, suporte para Scripts latinos, chinês, devanágari, japonês e coreano e uma vários idiomas. |
Nomes de SDK | GoogleMLKit/TextRecognition |
Implementação | Os recursos são vinculados estaticamente ao app no tempo de build |
Impacto no tamanho do app | Cerca de 38 MB por SDK de script |
Desempenho | Em tempo real na maioria dos dispositivos para o SDK de script latino, mas mais lento para outros. |
Faça um teste
- Teste o app de exemplo para um exemplo de uso dessa API.
- Experimente o código com a codelab.
Antes de começar
- Inclua os seguintes pods do kit de ML no seu Podfile:
# To recognize Latin script pod 'GoogleMLKit/TextRecognition', '3.2.0' # To recognize Chinese script pod 'GoogleMLKit/TextRecognitionChinese', '3.2.0' # To recognize Devanagari script pod 'GoogleMLKit/TextRecognitionDevanagari', '3.2.0' # To recognize Japanese script pod 'GoogleMLKit/TextRecognitionJapanese', '3.2.0' # To recognize Korean script pod 'GoogleMLKit/TextRecognitionKorean', '3.2.0'
- Depois de instalar ou atualizar os pods do seu projeto, abra o projeto Xcode usando o
.xcworkspace
: O Kit de ML é compatível com a versão 12.4 ou mais recente do Xcode.
1. Criar uma instância de TextRecognizer
Crie uma instância de TextRecognizer
chamando
+textRecognizer(options:)
, transmitindo as opções relacionadas ao SDK declarado como
dependência acima:
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. Preparar a imagem de entrada
Transmita a imagem como umUIImage
ou um CMSampleBufferRef
para o
Método process(_:completion:)
de TextRecognizer
:
Crie um objeto VisionImage
usando um UIImage
ou um
CMSampleBuffer
.
Se você usa um UIImage
, siga estas etapas:
- Crie um objeto
VisionImage
com oUIImage
. Especifique o.orientation
correto.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Se você usa um CMSampleBuffer
, siga estas etapas:
-
Especifique a orientação dos dados da imagem contidos no
CMSampleBuffer
:Para saber qual é a orientação da imagem:
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; } }
- Crie um objeto
VisionImage
usando o Objeto e orientaçãoCMSampleBuffer
: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. Processar a imagem
Em seguida, transmita a imagem para o 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. Extrair texto de blocos de texto reconhecido
Se a operação de reconhecimento de texto for bem-sucedida, ela retornará uma
Objeto Text
. Um objeto Text
contém o texto completo
reconhecido na imagem e zero ou mais TextBlock
objetos.
Cada TextBlock
representa um bloco retangular de texto, que
conter zero ou mais objetos TextLine
. Cada TextLine
contém zero ou mais objetos TextElement
,
que representam palavras e entidades semelhantes a palavras, como datas e números.
Para cada TextBlock
, TextLine
e
TextElement
, poderá fazer com que o texto seja reconhecido na
região e as coordenadas delimitadoras da região.
Exemplo:
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; } } }
Diretrizes de imagens de entrada
-
Para que o Kit de ML reconheça o texto com precisão, as imagens de entrada precisam conter que é representado por dados de pixel suficientes. Idealmente, cada caractere deve ter pelo menos 16 x 16 pixels. Geralmente, não há benefício de precisão para caracteres maiores que 24 x 24 pixels.
Por exemplo, uma imagem de 640 x 480 pode funcionar bem para digitalizar um cartão de visita que ocupa a largura total da imagem. Para digitalizar um documento impresso em papel de tamanho carta, uma imagem de 720 x 1280 pixels pode ser necessária.
-
Uma imagem com foco inadequado pode afetar a precisão do reconhecimento de texto. Se você não for conseguir resultados aceitáveis, peça para o usuário recapturar a imagem.
-
Se você estiver reconhecendo texto em um aplicativo em tempo real, considere as dimensões gerais das imagens de entrada. Menor as imagens podem ser processadas mais rapidamente. Para reduzir a latência, certifique-se de que o texto ocupe o máximo a imagem possível e capture imagens em resoluções menores (tendo em mente a precisão requisitos mencionados acima). Para mais informações, consulte Dicas para melhorar o desempenho.
Dicas para melhorar o desempenho
- Para processar frames de vídeo, use a API síncrona
results(in:)
do detector. Ligação esse método daAVCaptureVideoDataOutputSampleBufferDelegate
captureOutput(_, didOutput:from:)
para receber resultados do vídeo fornecido de forma síncrona frame. Manter deAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
comotrue
para limitar as chamadas ao detector. Se um novo frame de vídeo ficar disponível enquanto o detector estiver em execução, ele será descartado. - Se você usar a saída do detector para sobrepor elementos gráficos a imagem de entrada, primeiro acesse o resultado do Kit de ML e, em seguida, renderize a imagem e sobreposição em uma única etapa. Ao fazer isso, você renderiza a superfície de exibição apenas uma vez para cada frame de entrada processado. Veja a classe updatePreviewOverlayViewWithLastFrame na amostra do guia de início rápido do Kit de ML.
- Capture imagens em uma resolução mais baixa. No entanto, também tenha em mente os requisitos de dimensão de imagem dessa API.
- Para evitar uma possível degradação do desempenho, não execute vários
TextRecognizer
instâncias com diferentes opções de script simultaneamente.