Você pode 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 | |
---|---|
Descrição | Reconhecer texto em script latino em imagens ou vídeos. |
Nome do SDK | GoogleMLKit/TextRecognition (version 2.2.0) |
Implementação | Os recursos são vinculados estaticamente ao app durante a compilação. |
Impacto do tamanho do app | Cerca de 20 MB |
Desempenho | Em tempo real na maioria dos dispositivos. |
Faça um teste
- Teste o app de exemplo para ver um exemplo de uso dessa API.
- Teste o código por conta própria com o codelab (em inglês).
Antes de começar
- Inclua os seguintes pods de Kit de ML no seu Podfile:
pod 'GoogleMLKit/TextRecognition','2.2.0'
- Depois de instalar ou atualizar os pods do projeto, abra o projeto do Xcode usando o
.xcworkspace
. O Kit de ML é compatível com a versão 12.4 ou superior do Xcode.
1. Criar uma instância de TextRecognizer
Crie uma instância de TextRecognizer
chamando
+textRecognizer
:
Swift
let textRecognizer = TextRecognizer.textRecognizer()
Objective-C
MLKTextRecognizer *textRecognizer = [MLKTextRecognizer textRecognizer];
2. Preparar a imagem de entrada
Transmita a imagem comoUIImage
ou CMSampleBufferRef
para o método process(_:completion:)
do 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 em
CMSampleBuffer
.Para ver 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 objetoCMSampleBuffer
e a orientação: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 reconhecidos
Se a operação de reconhecimento de texto for bem-sucedida, ela retornará um objeto
Text
. Um objeto Text
contém o texto completo
reconhecido na imagem e zero ou mais objetos TextBlock
.
Cada TextBlock
representa um bloco de texto retangular, que
contém zero ou mais objetos TextLine
. Cada objeto TextLine
contém zero ou mais objetos TextElement
,
que representam palavras e entidades semelhantes, como datas e números.
Para cada objeto TextBlock
, TextLine
e
TextElement
, é possível obter o texto 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 imagem de entrada
-
Para que o Kit de ML reconheça o texto com precisão, as imagens de entrada devem conter texto representado por dados de pixel suficientes. O ideal é que cada caractere tenha 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 pixels pode funcionar para digitalizar um cartão de visita que ocupe toda a largura da imagem. Para digitalizar um documento impresso em papel de tamanho carta, talvez seja necessária uma imagem de 720 x 1280 pixels.
-
O foco inadequado da imagem pode afetar a precisão do reconhecimento de texto. Se você não estiver conseguindo resultados aceitáveis, peça para o usuário recapturar a imagem.
-
Se você estiver fazendo reconhecimento de texto em um aplicativo em tempo real, considere as dimensões gerais das imagens de entrada. Imagens menores podem ser processadas mais rapidamente. Para reduzir a latência, verifique se o texto está ocupando o máximo possível da imagem e capture imagens em resoluções mais baixas, tendo em mente os requisitos de precisão 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. Chame esse método da funçãocaptureOutput(_, didOutput:from:)
deAVCaptureVideoDataOutputSampleBufferDelegate
para receber resultados de maneira síncrona do frame de vídeo especificado. Mantenha oalwaysDiscardsLateVideoFrames
deAVCaptureVideoDataOutput
comotrue
para limitar as chamadas para o detector. Se um novo frame de vídeo for disponibilizado enquanto o detector estiver em execução, ele será descartado. - Se você usar a saída do detector para sobrepor elementos gráficos na imagem de entrada, primeiro acesse o resultado do Kit de ML e, em seguida, renderize a imagem e a 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. Consulte updatePreviewOverlayViewWithLastFrame no exemplo do guia de início rápido do Kit de ML para ver um exemplo.
- Capture imagens em uma resolução menor. No entanto, lembre-se também dos requisitos de dimensão de imagem da API.