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

Resim veya videolardaki metinleri (ör. sokak tabelasındaki metin) tanımak için ML Kit'i kullanabilirsiniz. Bu özelliğin temel nitelikleri şunlardır:

Text Recognition v2 API
AçıklamaResim veya videolardaki metinleri tanıma; Latin, Çince, Devanagari, Japonca ve Korece alfabelerinin yanı sıra birçok dili destekleme.
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 boyutunun etkisiKomut dosyası SDK'sı başına yaklaşık 38 MB
PerformansLatin alfabesi SDK'sı için çoğu cihazda gerçek zamanlı, diğerlerinde daha yavaş.

Deneyin

Başlamadan önce

  1. Podfile'ınıza aşağıdaki ML Kiti 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 .xcworkspace kullanarak Xcode projenizi açın. ML Kiti, Xcode 12.4 veya sonraki sürümlerde desteklenir.

1. TextRecognizer örneği oluşturma

+textRecognizer(options:) yöntemini çağırarak TextRecognizer örneği oluşturun ve yukarıda bağımlılık olarak tanımladığınız 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ş görüntüsünü hazırlama

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

UIImage veya CMSampleBuffer kullanarak bir VisionImage nesnesi oluşturun.

UIImage kullanıyorsanız aşağıdaki adımları uygulayın:

  • UIImage ile bir VisionImage nesnesi oluşturun. Doğru .orientation değerini 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 aşağıdaki adımları uygulayın:

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

    Resim yönünü öğrenmek 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ü kullanarak bir 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 ayıklama

Metin tanıma işlemi başarılı olursa bir Text nesnesi döndürü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 blokunu temsil eder. Her TextLine nesnesi, kelimeleri ve kelime benzeri varlıkları (ör. tarihler ve sayılar) temsil eden sıfır veya daha fazla TextElement nesnesi içerir.

Her 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 metinler bulunmalıdır. İdeal olarak, her karakter en az 16x16 piksel olmalıdır. Karakterlerin 24x24 pikselden büyük olması genellikle doğruluk açısından bir avantaj sağlamaz.

    Örneğin, 640x480 boyutundaki bir resim, resmin tamamını kaplayan bir kartviziti taramak için uygun olabilir. Letter boyutunda kağıda basılı bir belgeyi taramak için 720x1280 piksellik bir resim gerekebilir.

  • Görüntü odağının zayıf olması, metin tanıma doğruluğunu etkileyebilir. Kabul edilebilir sonuçlar alamıyorsanız kullanıcıdan görüntüyü yeniden yakalamasını isteyin.

  • Gerçek zamanlı 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 resmin mümkün olduğunca büyük bir kısmını kapladığından emin olun ve resimleri 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:) eşzamanlı API'sini kullanın. Belirli bir video karesinden eşzamanlı olarak sonuç almak için bu yöntemi AVCaptureVideoDataOutputSampleBufferDelegate'ın captureOutput(_, didOutput:from:) işlevinden çağırın. Dedektöre yapılan çağrıları kısıtlamak için AVCaptureVideoDataOutput'ın alwaysDiscardsLateVideoFrames değerini true olarak tutun. Dedektör çalışırken yeni bir video karesi kullanılabilir hale gelirse bu kare silinir.
  • Algılayıcının çıkışını giriş resminin üzerine grafik yerleştirmek için kullanıyorsanız önce ML Kit'ten sonucu alın, ardından resmi ve yer paylaşımını tek bir adımda oluşturun. Bunu yaparak, işlenen her giriş karesi için görüntüleme yüzeyine yalnızca bir kez oluşturma işlemi uygularsı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 yakalamayı deneyin. Ancak bu API'nin resim boyutu koşullarını da göz önünde bulundurun.
  • Olası performans düşüşlerini önlemek için farklı komut dosyası seçeneklerine sahip birden fazla TextRecognizer örneğini aynı anda çalıştırmayın.