Vous pouvez utiliser ML Kit pour reconnaître du texte dans des images ou des vidéos, comme le texte d'un panneau indicateur. Les principales caractéristiques de cette fonctionnalité sont les suivantes:
API Text Recognition | |
---|---|
Description | Reconnaître du texte en alphabet latin dans les images ou les vidéos |
Nom du SDK | Google |
Intégration | Les assets sont associés à votre application de manière statique au moment de la compilation. |
Impact sur la taille de l'application | Environ 20 Mo |
Performance | En temps réel sur la plupart des appareils. |
Essayer
- Testez l'exemple d'application pour voir un exemple d'utilisation de cette API.
- Testez le code vous-même avec l'atelier de programmation.
Avant de commencer
- Incluez les pods ML Kit suivants dans votre Podfile :
pod 'GoogleMLKit/TextRecognition','2.2.0'
- Après avoir installé ou mis à jour les pods de votre projet, ouvrez votre projet Xcode à l'aide de son
.xcworkspace
. ML Kit est compatible avec Xcode version 12.4 ou ultérieure.
1. Créer une instance de TextRecognizer
Créez une instance de TextRecognizer
en appelant +textRecognizer
:
let textRecognizer = TextRecognizer.textRecognizer()
MLKTextRecognizer *textRecognizer = [MLKTextRecognizer textRecognizer];
2. Préparer l'image d'entrée
Transmettez l'image en tant queUIImage
ou CMSampleBufferRef
à la méthode process(_:completion:)
de TextRecognizer
:
Créez un objet VisionImage
à l'aide d'un objet UIImage
ou CMSampleBuffer
.
Si vous utilisez un UIImage
, procédez comme suit:
- Créez un objet
VisionImage
avecUIImage
. Veillez à indiquer le bon.orientation
.let image = VisionImage(image: UIImage)
visionImage.orientation = image.imageOrientationMLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
visionImage.orientation = image.imageOrientation;
Si vous utilisez un CMSampleBuffer
, procédez comme suit:
-
Spécifiez l'orientation des données d'image contenues dans
CMSampleBuffer
.Pour obtenir l'orientation de l'image:
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
}
}
- (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;
}
}
- Créez un objet
VisionImage
à l'aide de l'objet et de l'orientationCMSampleBuffer
:let image = VisionImage(buffer: sampleBuffer)
image.orientation = imageOrientation(
deviceOrientation: UIDevice.current.orientation,
cameraPosition: cameraPosition)MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer];
image.orientation =
[self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
cameraPosition:cameraPosition];
3. Traiter l'image
Transmettez ensuite l'image à la méthode process(_:completion:)
:
textRecognizer.process(visionImage) { result, error in
guard error == nil, let result = result else {
// Error handling
return
}
// Recognized text
}
[textRecognizer processImage:image
completion:^(MLKText *_Nullable result,
NSError *_Nullable error) {
if (error != nil || result == nil) {
// Error handling
return;
}
// Recognized text
}];
4. Extraire le texte des blocs de texte reconnu
Si l'opération de reconnaissance de texte réussit, elle renvoie un objet Text
. Un objet Text
contient le texte complet reconnu dans l'image et zéro ou plusieurs objets TextBlock
.
Chaque TextBlock
représente un bloc de texte rectangulaire contenant zéro, un ou plusieurs objets TextLine
. Chaque objet TextLine
contient zéro, un ou plusieurs objets TextElement
, qui représentent des mots et des entités semblables à un mot, telles que des dates et des chiffres.
Pour chaque objet TextBlock
, TextLine
et TextElement
, vous pouvez faire reconnaître le texte dans la région et les coordonnées de la région.
Exemple :
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
}
}
}
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;
}
}
}
Consignes pour les images d'entrée
-
Pour que ML Kit reconnaisse le texte avec précision, les images d'entrée doivent contenir du texte représenté par suffisamment de données de pixels. Dans l'idéal, chaque caractère doit mesurer au moins 16 x 16 pixels. Il n'y a généralement aucun avantage en termes de précision pour les caractères d'une taille supérieure à 24 x 24 pixels.
Ainsi, une image de 640 x 480 peut être idéale pour scanner une carte de visite qui occupe toute la largeur de l'image. Pour numériser un document imprimé sur papier papier, une image de 720 x 1 280 pixels peut être requise.
-
Une image floue peut nuire à la précision de la reconnaissance textuelle. Si vous n'obtenez pas de résultats acceptables, essayez de demander à l'utilisateur de reprendre l'image.
-
Si vous reconnaissez du texte dans une application en temps réel, vous devez prendre en compte les dimensions globales des images d'entrée. Les images plus petites peuvent être traitées plus rapidement. Pour réduire la latence, assurez-vous que le texte occupe autant d'images que possible, et capturez les images à des résolutions inférieures (en tenant compte des exigences de précision mentionnées ci-dessus). Pour en savoir plus, consultez Conseils pour améliorer les performances.
Conseils pour améliorer les performances
- Pour traiter les images vidéo, utilisez l'API synchrone
results(in:)
du détecteur. Appelez cette méthode à partir de la fonctioncaptureOutput(_, didOutput:from:)
deAVCaptureVideoDataOutputSampleBufferDelegate
pour obtenir les résultats de manière synchrone à partir d'une image vidéo donnée. Conservez la propriétéalwaysDiscardsLateVideoFrames
deAVCaptureVideoDataOutput
commetrue
pour limiter les appels au détecteur. Si une nouvelle image vidéo devient disponible pendant l'exécution du détecteur, elle sera supprimée. - Si vous utilisez la sortie du détecteur pour superposer des graphiques sur l'image d'entrée, commencez par obtenir le résultat de ML Kit, puis effectuez le rendu de l'image et de la superposition en une seule étape. Ainsi, vous n'affichez la surface d'affichage qu'une seule fois pour chaque trame d'entrée traitée. Pour obtenir un exemple, consultez la section updatePreviewOverlayViewWithLastFrame dans l'exemple de démarrage rapide de ML Kit.
- Envisagez de capturer des images avec une résolution inférieure. Gardez toutefois à l'esprit les exigences liées aux dimensions d'image de cette API.