iOS'te ML Kit ile görüntülerdeki metinleri tanıma

ML Kit'i kullanarak resimlerdeki veya videolardaki metinleri (ör. trafik işareti metni) tanıyabilirsiniz. Bu özelliğin temel özellikleri şunlardır:

Text Recognition v2 API
AçıklamaResimlerdeki veya videolardaki metinleri tanıma, Latin, Çince, Devanagari, Japonca ve Korece alfabeler ile çok çeşitli dillerde destek.
SDK adlarıGoogleMLKit/TextRecognition
GoogleMLKit/TextRecognitionChinese
GoogleMLKit/TextRecognitionDevanagari
GoogleMLKit/TextRecognitionJapanese
GoogleMLKit/TextRecognitionKorean
UygulamaÖğeler, derleme sırasında uygulamanıza statik olarak bağlanır.
Uygulama boyutu etkisiKomut dosyası SDK'sı başına yaklaşık 38 MB
PerformansLatin alfabesi SDK'sı için çoğu cihazda gerçek zamanlı, diğerleri için daha yavaş.

Deneyin

Başlamadan önce

  1. Podfile'ınıza aşağıdaki ML Kit kapsüllerini ekleyin:
    # 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'
    
  2. Projenizin Pod'larını yükledikten veya güncelledikten sonra Xcode projenizi .xcworkspace kullanarak açın. ML Kit, Xcode 12.4 veya sonraki sürümlerde desteklenir.

1. TextRecognizer örneği oluşturma

TextRecognizer örneği oluşturmak için +textRecognizer(options:) işlevini çağırın ve yukarıda bağımlılık olarak bildirdiğiniz SDK ile ilgili seçenekleri iletin:

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. Giriş resmini hazırlama

Resmi UIImage veya CMSampleBufferRef olarak TextRecognizer'in process(_:completion:) yöntemine iletin:

UIImage veya CMSampleBuffer kullanarak VisionImage nesnesi oluşturun.

UIImage kullanıyorsanız şu adımları uygulayın:

  • UIImage ile VisionImage nesnesi oluşturun. Doğru .orientation belirttiğinizden emin olun.

    Swift

    let image = VisionImage(image: UIImage)
    visionImage.orientation = image.imageOrientation

    Objective-C

    MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
    visionImage.orientation = image.imageOrientation;

CMSampleBuffer kullanıyorsanız şu adımları uygulayın:

  • CMSampleBuffer içinde yer alan resim verilerinin yönünü belirtin.

    Resim yönünü almak için:

    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;
      }
    }
          
  • CMSampleBuffer nesnesini ve yönünü kullanarak VisionImage nesnesi oluşturun:

    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. Resmi işleme

Ardından, görüntüyü process(_:completion:) yöntemine iletin:

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. Tanınan metin bloklarından metin çıkarma

Metin tanıma işlemi başarılı olursa Text nesnesi döndürülür. Text nesnesi, resimde tanınan tam metni ve sıfır veya daha fazla TextBlock nesnesini içerir.

Her TextBlock, sıfır veya daha fazla TextLine nesnesi içeren dikdörtgen bir metin bloğunu temsil eder. Her TextLine nesnesi, kelimeleri ve kelime benzeri öğeleri (ör. tarihler ve sayılar) temsil eden sıfır veya daha fazla TextElement nesnesi içerir.

Her bir TextBlock, TextLine ve TextElement nesnesi için bölgede tanınan metni ve bölgenin sınırlayıcı koordinatlarını alabilirsiniz.

Örneğin:

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;
    }
  }
}

Giriş resmi kuralları

  • ML Kit'in metni doğru şekilde tanıması için giriş resimlerinde yeterli piksel verisiyle temsil edilen metin bulunmalıdır. İdeal olarak, her karakter en az 16x16 piksel olmalıdır. Genellikle karakterlerin 24x24 pikselden büyük olması doğruluk açısından bir avantaj sağlamaz.

    Bu nedenle, örneğin, resmin tam genişliğini kaplayan bir kartviziti taramak için 640x480 boyutundaki bir resim iyi sonuç verebilir. Mektup boyutunda kağıda yazdırılmış bir belgeyi taramak için 720x1280 piksel boyutunda bir görüntü gerekebilir.

  • Resmin iyi odaklanmaması, metin tanıma doğruluğunu etkileyebilir. Kabul edilebilir sonuçlar alamıyorsanız kullanıcıdan resmi yeniden çekmesini isteyin.

  • Anlık bir uygulamada metin tanıma işlemi yapıyorsanız giriş resimlerinin genel boyutlarını göz önünde bulundurmanız gerekir. Daha küçük resimler daha hızlı işlenebilir. Gecikmeyi azaltmak için metnin mümkün olduğunca büyük bir bölümünü kapladığından emin olun ve görüntüleri daha düşük çözünürlüklerde çekin (yukarıda belirtilen doğruluk şartlarını göz önünde bulundurarak). Daha fazla bilgi için Performansı artırmaya yönelik ipuçları başlıklı makaleyi inceleyin.

Performansı artırmaya yönelik ipuçları

  • Video karelerini işlemek için algılayıcının results(in:) senkron API'sini kullanın. Belirli bir video karesinden sonuçları eşzamanlı olarak almak için bu yöntemi AVCaptureVideoDataOutputSampleBufferDelegate'ın captureOutput(_, didOutput:from:) işlevinden çağırın. Algılayıcıya yapılan çağrıları sınırlamak için AVCaptureVideoDataOutput'ın alwaysDiscardsLateVideoFrames değerini true olarak tutun. Dedektör çalışırken yeni bir video karesi kullanılabilir hale gelirse bu kare bırakılır.
  • Giriş resmine grafik yerleştirmek için algılayıcının çıkışını kullanıyorsanız önce ML Kit'ten sonucu alın, ardından resmi tek adımda oluşturun ve yerleştirin. Bunu yaptığınızda, işlenen her giriş karesi için yalnızca bir kez görüntüleme yüzeyine işleme yaparsınız. Örnek için ML Kit hızlı başlangıç örneğindeki updatePreviewOverlayViewWithLastFrame bölümüne bakın.
  • Görüntüleri daha düşük çözünürlükte çekmeyi deneyin. Ancak bu API'nin resim boyutu koşullarını da göz önünde bulundurun.
  • Performansın düşmesini önlemek için farklı komut dosyası seçenekleriyle birden fazla TextRecognizer örneğini aynı anda çalıştırmayın.