iOS'te Makine Öğrenimi Kiti ile Görsellerdeki Metinleri Tanıma

Resimlerdeki metinleri tanımak için ML Kit'i kullanabilirsiniz. ML Kit'te hem resimlerdeki metinleri (ör. sokak tabelasındaki metin) tanımaya uygun genel amaçlı bir API hem de belgelerdeki metinleri tanımaya yönelik optimize edilmiş bir API bulunur. Genel amaçlı API'de hem cihaz üzerinde hem de bulut tabanlı modeller bulunur. Belge metni tanıma yalnızca bulut tabanlı bir model olarak kullanılabilir. Bulut ve cihaz üzerindeki modellerin karşılaştırması için genel bakış bölümüne bakın.

Başlamadan önce

  1. Firebase'i uygulamanıza henüz eklemediyseniz Başlangıç kılavuzundaki adımları uygulayarak ekleyin.
  2. ML Kit kitaplıklarını Podfile'ınıza ekleyin:
    pod 'Firebase/MLVision', '6.25.0'
    # If using an on-device API:
    pod 'Firebase/MLVisionTextModel', '6.25.0'
    
    Projenizin Pod'larını yükledikten veya güncelledikten sonra Xcode projenizi .xcworkspace kullanarak açtığınızdan emin olun.
  3. Uygulamanızda Firebase'i içe aktarın:

    Swift

    import Firebase

    Objective-C

    @import Firebase;
  4. Cloud tabanlı modeli kullanmak istiyorsanız ve projeniz için Cloud tabanlı API'leri henüz etkinleştirmediyseniz şimdi etkinleştirin:

    1. Firebase konsolunun ML Kit API'leri sayfasını açın.
    2. Projenizi henüz Blaze fiyatlandırma planına yükseltmediyseniz yükseltmek için Yükselt'i tıklayın. (Yalnızca projeniz Blaze planında değilse yükseltmeniz istenir.)

      Yalnızca Blaze düzeyindeki projeler bulut tabanlı API'leri kullanabilir.

    3. Bulut tabanlı API'ler etkinleştirilmemişse Bulut tabanlı API'leri etkinleştir'i tıklayın.

    Yalnızca cihaz üzerinde modeli kullanmak istiyorsanız bu adımı atlayabilirsiniz.

Artık resimlerdeki metinleri tanımaya başlayabilirsiniz.

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, Latin metinlerde her karakter en az 16x16 piksel olmalıdır. Çince, Japonca ve Korece metinlerde (yalnızca bulut tabanlı API'ler tarafından desteklenir) her karakter 24x24 piksel olmalıdır. Genel olarak, tüm dillerde 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 net olmaması, metin tanıma doğruluğunu olumsuz etkileyebilir. Kabul edilebilir sonuçlar alamıyorsanız kullanıcıdan resmi yeniden çekmesini isteyin.

  • Metni gerçek zamanlı bir uygulamada tanıyorsanız giriş resimlerinin genel boyutlarını da göz önünde bulundurmanız gerekebilir. Daha küçük görüntüler daha hızlı işlenebilir. Bu nedenle, gecikmeyi azaltmak için görüntüleri daha düşük çözünürlüklerde çekin (yukarıdaki doğruluk şartlarını göz önünde bulundurarak) ve metnin, görüntünün mümkün olduğunca büyük bir bölümünü kapladığından emin olun. Ayrıca Gerçek zamanlı performansı artırmaya yönelik ipuçları başlıklı makaleye de göz atın.


Resimlerdeki metinleri tanıyın

Cihaz üzerinde veya bulut tabanlı bir model kullanarak resimdeki metni tanımak için metin tanıyıcıyı aşağıda açıklandığı şekilde çalıştırın.

1. Metin tanıyıcıyı çalıştırma

Görüntüyü, `UIImage` veya `CMSampleBufferRef` olarak `VisionTextRecognizer`ın `process(_:completion:)` yöntemine iletin:
  1. VisionTextRecognizer ürününün bir örneğini almak için onDeviceTextRecognizer veya cloudTextRecognizer numaralı telefonu arayın:

    Swift

    Cihaz üzerinde modeli kullanmak için:

    let vision = Vision.vision()
    let textRecognizer = vision.onDeviceTextRecognizer()

    Bulut modelini kullanmak için:

    let vision = Vision.vision()
    let textRecognizer = vision.cloudTextRecognizer()
    
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    let options = VisionCloudTextRecognizerOptions()
    options.languageHints = ["en", "hi"]
    let textRecognizer = vision.cloudTextRecognizer(options: options)

    Objective-C

    Cihaz üzerinde modeli kullanmak için:

    FIRVision *vision = [FIRVision vision];
    FIRVisionTextRecognizer *textRecognizer = [vision onDeviceTextRecognizer];

    Bulut modelini kullanmak için:

    FIRVision *vision = [FIRVision vision];
    FIRVisionTextRecognizer *textRecognizer = [vision cloudTextRecognizer];
    
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    FIRVisionCloudTextRecognizerOptions *options =
            [[FIRVisionCloudTextRecognizerOptions alloc] init];
    options.languageHints = @[@"en", @"hi"];
    FIRVisionTextRecognizer *textRecognizer = [vision cloudTextRecognizerWithOptions:options];
  2. UIImage veya CMSampleBufferRef kullanarak VisionImage nesnesi oluşturun.

    UIImage kullanmak için:

    1. Gerekirse resmi imageOrientation özelliği .up olacak şekilde döndürün.
    2. Doğru şekilde döndürülmüş VisionImage kullanarak bir UIImage nesnesi oluşturun. Dönüşüm meta verileri belirtmeyin. Varsayılan değer olan .topLeft kullanılmalıdır.

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    CMSampleBufferRef kullanmak için:

    1. VisionImageMetadata nesnesi oluşturun. Bu nesne, CMSampleBufferRef arabelleğinde bulunan görüntü verilerinin yönünü belirtir.

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

      Swift

      func imageOrientation(
          deviceOrientation: UIDeviceOrientation,
          cameraPosition: AVCaptureDevice.Position
          ) -> VisionDetectorImageOrientation {
          switch deviceOrientation {
          case .portrait:
              return cameraPosition == .front ? .leftTop : .rightTop
          case .landscapeLeft:
              return cameraPosition == .front ? .bottomLeft : .topLeft
          case .portraitUpsideDown:
              return cameraPosition == .front ? .rightBottom : .leftBottom
          case .landscapeRight:
              return cameraPosition == .front ? .topRight : .bottomRight
          case .faceDown, .faceUp, .unknown:
              return .leftTop
          }
      }

      Objective-C

      - (FIRVisionDetectorImageOrientation)
          imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                                 cameraPosition:(AVCaptureDevicePosition)cameraPosition {
        switch (deviceOrientation) {
          case UIDeviceOrientationPortrait:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationLeftTop;
            } else {
              return FIRVisionDetectorImageOrientationRightTop;
            }
          case UIDeviceOrientationLandscapeLeft:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationBottomLeft;
            } else {
              return FIRVisionDetectorImageOrientationTopLeft;
            }
          case UIDeviceOrientationPortraitUpsideDown:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationRightBottom;
            } else {
              return FIRVisionDetectorImageOrientationLeftBottom;
            }
          case UIDeviceOrientationLandscapeRight:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationTopRight;
            } else {
              return FIRVisionDetectorImageOrientationBottomRight;
            }
          default:
            return FIRVisionDetectorImageOrientationTopLeft;
        }
      }

      Ardından, meta veri nesnesini oluşturun:

      Swift

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )

      Objective-C

      FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
      AVCaptureDevicePosition cameraPosition =
          AVCaptureDevicePositionBack;  // Set to the capture device you used.
      metadata.orientation =
          [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                       cameraPosition:cameraPosition];
    2. VisionImage nesnesini ve döndürme meta verilerini kullanarak CMSampleBufferRef nesnesi oluşturun:

      Swift

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. 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 {
        // ...
        return
      }
    
      // Recognized text
    }

    Objective-C

    [textRecognizer processImage:image
                      completion:^(FIRVisionText *_Nullable result,
                                   NSError *_Nullable error) {
      if (error != nil || result == nil) {
        // ...
        return;
      }
    
      // Recognized text
    }];

2. Tanınan metin bloklarından metin çıkarma

Metin tanıma işlemi başarılı olursa [`VisionText`][VisionText] nesnesi döndürülür. `VisionText` nesnesi, resimde tanınan tam metni ve sıfır veya daha fazla [`VisionTextBlock`][VisionTextBlock] nesnesini içerir. Her `VisionTextBlock`, sıfır veya daha fazla [`VisionTextLine`][VisionTextLine] nesnesi içeren dikdörtgen bir metin bloğunu temsil eder. Her `VisionTextLine` nesnesi, kelimeleri ve kelime benzeri öğeleri (tarihler, sayılar vb.) temsil eden sıfır veya daha fazla [`VisionTextElement`][VisionTextElement] nesnesi içerir. Her bir "VisionTextBlock", "VisionTextLine" ve "VisionTextElement" 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 blockConfidence = block.confidence
    let blockLanguages = block.recognizedLanguages
    let blockCornerPoints = block.cornerPoints
    let blockFrame = block.frame
    for line in block.lines {
        let lineText = line.text
        let lineConfidence = line.confidence
        let lineLanguages = line.recognizedLanguages
        let lineCornerPoints = line.cornerPoints
        let lineFrame = line.frame
        for element in line.elements {
            let elementText = element.text
            let elementConfidence = element.confidence
            let elementLanguages = element.recognizedLanguages
            let elementCornerPoints = element.cornerPoints
            let elementFrame = element.frame
        }
    }
}

Objective-C

NSString *resultText = result.text;
for (FIRVisionTextBlock *block in result.blocks) {
  NSString *blockText = block.text;
  NSNumber *blockConfidence = block.confidence;
  NSArray<FIRVisionTextRecognizedLanguage *> *blockLanguages = block.recognizedLanguages;
  NSArray<NSValue *> *blockCornerPoints = block.cornerPoints;
  CGRect blockFrame = block.frame;
  for (FIRVisionTextLine *line in block.lines) {
    NSString *lineText = line.text;
    NSNumber *lineConfidence = line.confidence;
    NSArray<FIRVisionTextRecognizedLanguage *> *lineLanguages = line.recognizedLanguages;
    NSArray<NSValue *> *lineCornerPoints = line.cornerPoints;
    CGRect lineFrame = line.frame;
    for (FIRVisionTextElement *element in line.elements) {
      NSString *elementText = element.text;
      NSNumber *elementConfidence = element.confidence;
      NSArray<FIRVisionTextRecognizedLanguage *> *elementLanguages = element.recognizedLanguages;
      NSArray<NSValue *> *elementCornerPoints = element.cornerPoints;
      CGRect elementFrame = element.frame;
    }
  }
}

Anlık performansı artırmaya yönelik ipuçları

Cihaz üzerinde modeli kullanarak gerçek zamanlı bir uygulamada metni tanımak istiyorsanız en iyi kare hızlarını elde etmek için aşağıdaki yönergeleri uygulayın:

  • Metin tanıyıcıya yapılan çağrıları sınırlayın. Metin tanıma aracı çalışırken yeni bir video karesi kullanılabilir hale gelirse kareyi bırakın.
  • Metin tanıyıcının çıkışını, giriş resmine grafik yerleştirmek için kullanıyorsanız önce ML Kit'ten sonucu alın, ardından resmi tek adımda oluşturup yerleştirin. Bunu yaptığınızda, her giriş çerçevesi için yalnızca bir kez görüntüleme yüzeyine işleme yaparsınız. Örnek için tanıtım amaçlı örnek uygulamadaki previewOverlayView ve FIRDetectionOverlayView sınıflarına 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.

Sonraki adımlar


Belge resimlerindeki metinleri tanıma

Bir belgedeki metni tanımak için bulut tabanlı belge metni tanıyıcıyı aşağıda açıklandığı şekilde yapılandırın ve çalıştırın.

Aşağıda açıklanan belge metni tanıma API'si, belge resimleriyle çalışmayı kolaylaştırmak için tasarlanmış bir arayüz sağlar. Ancak, seyrek metin API'sinin sağladığı arayüzü tercih ederseniz bulut metin tanıyıcıyı yoğun metin modelini kullanacak şekilde yapılandırarak belgeleri taramak için bu arayüzü kullanabilirsiniz.

Belge metni tanıma API'sini kullanmak için:

1. Metin tanıyıcıyı çalıştırma

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

  1. VisionDocumentTextRecognizer numaralı telefonu arayarak VisionDocumentTextRecognizer örneğini alın: cloudDocumentTextRecognizer:

    Swift

    let vision = Vision.vision()
    let textRecognizer = vision.cloudDocumentTextRecognizer()
    
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    let options = VisionCloudDocumentTextRecognizerOptions()
    options.languageHints = ["en", "hi"]
    let textRecognizer = vision.cloudDocumentTextRecognizer(options: options)

    Objective-C

    FIRVision *vision = [FIRVision vision];
    FIRVisionDocumentTextRecognizer *textRecognizer = [vision cloudDocumentTextRecognizer];
    
    // Or, to provide language hints to assist with language detection:
    // See https://cloud.google.com/vision/docs/languages for supported languages
    FIRVisionCloudDocumentTextRecognizerOptions *options =
            [[FIRVisionCloudDocumentTextRecognizerOptions alloc] init];
    options.languageHints = @[@"en", @"hi"];
    FIRVisionDocumentTextRecognizer *textRecognizer = [vision cloudDocumentTextRecognizerWithOptions:options];
  2. UIImage veya CMSampleBufferRef kullanarak VisionImage nesnesi oluşturun.

    UIImage kullanmak için:

    1. Gerekirse resmi imageOrientation özelliği .up olacak şekilde döndürün.
    2. Doğru şekilde döndürülmüş VisionImage kullanarak bir UIImage nesnesi oluşturun. Dönüşüm meta verileri belirtmeyin. Varsayılan değer olan .topLeft kullanılmalıdır.

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    CMSampleBufferRef kullanmak için:

    1. VisionImageMetadata nesnesi oluşturun. Bu nesne, CMSampleBufferRef arabelleğinde bulunan görüntü verilerinin yönünü belirtir.

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

      Swift

      func imageOrientation(
          deviceOrientation: UIDeviceOrientation,
          cameraPosition: AVCaptureDevice.Position
          ) -> VisionDetectorImageOrientation {
          switch deviceOrientation {
          case .portrait:
              return cameraPosition == .front ? .leftTop : .rightTop
          case .landscapeLeft:
              return cameraPosition == .front ? .bottomLeft : .topLeft
          case .portraitUpsideDown:
              return cameraPosition == .front ? .rightBottom : .leftBottom
          case .landscapeRight:
              return cameraPosition == .front ? .topRight : .bottomRight
          case .faceDown, .faceUp, .unknown:
              return .leftTop
          }
      }

      Objective-C

      - (FIRVisionDetectorImageOrientation)
          imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                                 cameraPosition:(AVCaptureDevicePosition)cameraPosition {
        switch (deviceOrientation) {
          case UIDeviceOrientationPortrait:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationLeftTop;
            } else {
              return FIRVisionDetectorImageOrientationRightTop;
            }
          case UIDeviceOrientationLandscapeLeft:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationBottomLeft;
            } else {
              return FIRVisionDetectorImageOrientationTopLeft;
            }
          case UIDeviceOrientationPortraitUpsideDown:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationRightBottom;
            } else {
              return FIRVisionDetectorImageOrientationLeftBottom;
            }
          case UIDeviceOrientationLandscapeRight:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationTopRight;
            } else {
              return FIRVisionDetectorImageOrientationBottomRight;
            }
          default:
            return FIRVisionDetectorImageOrientationTopLeft;
        }
      }

      Ardından, meta veri nesnesini oluşturun:

      Swift

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )

      Objective-C

      FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
      AVCaptureDevicePosition cameraPosition =
          AVCaptureDevicePositionBack;  // Set to the capture device you used.
      metadata.orientation =
          [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                       cameraPosition:cameraPosition];
    2. VisionImage nesnesini ve döndürme meta verilerini kullanarak CMSampleBufferRef nesnesi oluşturun:

      Swift

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. 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 {
        // ...
        return
      }
    
      // Recognized text
    }

    Objective-C

    [textRecognizer processImage:image
                      completion:^(FIRVisionDocumentText *_Nullable result,
                                   NSError *_Nullable error) {
      if (error != nil || result == nil) {
        // ...
        return;
      }
    
        // Recognized text
    }];

2. Tanınan metin bloklarından metin çıkarma

Metin tanıma işlemi başarılı olursa VisionDocumentText nesnesi döndürülür. VisionDocumentText nesnesi, resimde tanınan metnin tamamını ve tanınan belgenin yapısını yansıtan bir nesne hiyerarşisini içerir:

Her VisionDocumentTextBlock, VisionDocumentTextParagraph, VisionDocumentTextWord ve VisionDocumentTextSymbol nesnesi için bölgede tanınan metni ve bölgenin sınırlama koordinatlarını alabilirsiniz.

Örneğin:

Swift

let resultText = result.text
for block in result.blocks {
    let blockText = block.text
    let blockConfidence = block.confidence
    let blockRecognizedLanguages = block.recognizedLanguages
    let blockBreak = block.recognizedBreak
    let blockCornerPoints = block.cornerPoints
    let blockFrame = block.frame
    for paragraph in block.paragraphs {
        let paragraphText = paragraph.text
        let paragraphConfidence = paragraph.confidence
        let paragraphRecognizedLanguages = paragraph.recognizedLanguages
        let paragraphBreak = paragraph.recognizedBreak
        let paragraphCornerPoints = paragraph.cornerPoints
        let paragraphFrame = paragraph.frame
        for word in paragraph.words {
            let wordText = word.text
            let wordConfidence = word.confidence
            let wordRecognizedLanguages = word.recognizedLanguages
            let wordBreak = word.recognizedBreak
            let wordCornerPoints = word.cornerPoints
            let wordFrame = word.frame
            for symbol in word.symbols {
                let symbolText = symbol.text
                let symbolConfidence = symbol.confidence
                let symbolRecognizedLanguages = symbol.recognizedLanguages
                let symbolBreak = symbol.recognizedBreak
                let symbolCornerPoints = symbol.cornerPoints
                let symbolFrame = symbol.frame
            }
        }
    }
}

Objective-C

NSString *resultText = result.text;
for (FIRVisionDocumentTextBlock *block in result.blocks) {
  NSString *blockText = block.text;
  NSNumber *blockConfidence = block.confidence;
  NSArray<FIRVisionTextRecognizedLanguage *> *blockRecognizedLanguages = block.recognizedLanguages;
  FIRVisionTextRecognizedBreak *blockBreak = block.recognizedBreak;
  CGRect blockFrame = block.frame;
  for (FIRVisionDocumentTextParagraph *paragraph in block.paragraphs) {
    NSString *paragraphText = paragraph.text;
    NSNumber *paragraphConfidence = paragraph.confidence;
    NSArray<FIRVisionTextRecognizedLanguage *> *paragraphRecognizedLanguages = paragraph.recognizedLanguages;
    FIRVisionTextRecognizedBreak *paragraphBreak = paragraph.recognizedBreak;
    CGRect paragraphFrame = paragraph.frame;
    for (FIRVisionDocumentTextWord *word in paragraph.words) {
      NSString *wordText = word.text;
      NSNumber *wordConfidence = word.confidence;
      NSArray<FIRVisionTextRecognizedLanguage *> *wordRecognizedLanguages = word.recognizedLanguages;
      FIRVisionTextRecognizedBreak *wordBreak = word.recognizedBreak;
      CGRect wordFrame = word.frame;
      for (FIRVisionDocumentTextSymbol *symbol in word.symbols) {
        NSString *symbolText = symbol.text;
        NSNumber *symbolConfidence = symbol.confidence;
        NSArray<FIRVisionTextRecognizedLanguage *> *symbolRecognizedLanguages = symbol.recognizedLanguages;
        FIRVisionTextRecognizedBreak *symbolBreak = symbol.recognizedBreak;
        CGRect symbolFrame = symbol.frame;
      }
    }
  }
}

Sonraki adımlar