Mengenali teks dalam gambar dengan ML Kit di iOS

Anda dapat menggunakan ML Kit untuk mengenali teks dalam gambar atau video, seperti teks rambu jalan. Karakteristik utama fitur ini adalah:

API Pengenalan Teks v2
DeskripsiMengenali teks dalam gambar atau video, dukungan untuk skrip Latin, China, Devanagari, Jepang, dan Korea, serta berbagai bahasa.
Nama SDKGoogleMLKit/TextRecognition
GoogleMLKit/TextRecognitionChinese
GoogleMLKit/TextRecognitionDevanagari
GoogleMLKit/TextRecognitionJapanese
GoogleMLKit/TextRecognitionKorean
PenerapanAset ditautkan secara statis ke aplikasi Anda pada waktu build
Dampak ukuran aplikasiSekitar 38 MB per skrip SDK
PerformaReal-time di sebagian besar perangkat untuk SDK skrip Latin, lebih lambat di perangkat lainnya.

Cobalah

Sebelum memulai

  1. Sertakan pod ML Kit berikut di Podfile Anda:
    # To recognize Latin script
    pod 'GoogleMLKit/TextRecognition', '3.2.0'
    # To recognize Chinese script
    pod 'GoogleMLKit/TextRecognitionChinese', '3.2.0'
    # To recognize Devanagari script
    pod 'GoogleMLKit/TextRecognitionDevanagari', '3.2.0'
    # To recognize Japanese script
    pod 'GoogleMLKit/TextRecognitionJapanese', '3.2.0'
    # To recognize Korean script
    pod 'GoogleMLKit/TextRecognitionKorean', '3.2.0'
    
  2. Setelah menginstal atau mengupdate Pod project, buka project Xcode menggunakan .xcworkspace. ML Kit didukung di Xcode versi 12.4 atau yang lebih baru.

1. Membuat instance TextRecognizer

Buat instance TextRecognizer dengan memanggil +textRecognizer(options:), dengan meneruskan opsi terkait SDK yang Anda deklarasikan sebagai dependensi di atas:

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. Siapkan gambar input

Teruskan gambar sebagai UIImage atau CMSampleBufferRef ke metode process(_:completion:) TextRecognizer:

Buat objek VisionImage menggunakan UIImage atau CMSampleBuffer.

Jika Anda menggunakan UIImage, ikuti langkah-langkah berikut:

  • Buat objek VisionImage dengan UIImage. Pastikan untuk menentukan .orientation yang benar.

    Swift

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

    Objective-C

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

Jika Anda menggunakan CMSampleBuffer, ikuti langkah-langkah berikut:

  • Tentukan orientasi data gambar yang terdapat dalam CMSampleBuffer.

    Untuk mendapatkan orientasi gambar:

    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;
      }
    }
          
  • Buat objek VisionImage menggunakan objek dan orientasi CMSampleBuffer:

    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. Memproses gambar

Lalu, teruskan gambar ke metode 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. Ekstrak teks dari blok teks yang dikenali

Jika operasi pengenalan teks berhasil, objek Text akan ditampilkan. Objek Text berisi teks lengkap yang dikenali dalam gambar, serta berisi nol objek TextBlock atau lebih.

Setiap TextBlock mewakili blok teks persegi panjang yang berisi nol atau beberapa objek TextLine. Setiap objek TextLine berisi nol atau beberapa objek TextElement, yang mewakili kata dan entitas seperti kata seperti tanggal dan angka.

Untuk setiap objek TextBlock, TextLine, dan TextElement, Anda bisa mendapatkan teks yang dikenali di wilayah dan koordinat pembatas area tersebut.

Contoh:

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

Panduan gambar input

  • Agar ML Kit dapat mengenali teks secara akurat, gambar input harus berisi teks yang diwakili oleh data piksel yang memadai. Idealnya, setiap karakter harus berukuran minimal 16x16 piksel. Secara umum, ukuran karakter yang lebih besar dari 24x24 piksel tidak akan meningkatkan akurasi.

    Jadi, misalnya, gambar 640x480 mungkin sudah cukup untuk memindai kartu nama yang menempati lebar penuh gambar. Untuk memindai dokumen yang dicetak pada kertas berukuran huruf, gambar 720x1280 piksel mungkin diperlukan.

  • Fokus gambar yang buruk dapat memengaruhi akurasi pengenalan teks. Jika tidak mendapatkan hasil yang dapat diterima, coba minta pengguna untuk mengambil ulang gambar.

  • Jika mengenali teks dalam aplikasi real-time, Anda harus mempertimbangkan dimensi keseluruhan gambar input. Gambar yang lebih kecil dapat diproses lebih cepat. Untuk mengurangi latensi, pastikan teks menempati gambar sebanyak mungkin, dan ambil gambar pada resolusi lebih rendah (ingatlah persyaratan akurasi yang disebutkan di atas). Untuk mengetahui informasi selengkapnya, lihat Tips untuk meningkatkan performa.

Tips untuk meningkatkan performa

  • Untuk memproses frame video, gunakan API sinkron results(in:) dari detektor. Panggil metode ini dari fungsi captureOutput(_, didOutput:from:) AVCaptureVideoDataOutputSampleBufferDelegate untuk mendapatkan hasil dari frame video tertentu secara sinkron. Biarkan alwaysDiscardsLateVideoFrames AVCaptureVideoDataOutput sebagai true untuk membatasi panggilan ke detektor. Jika frame video baru tersedia saat detektor sedang berjalan, frame video tersebut akan dihapus.
  • Jika Anda menggunakan output detektor untuk menempatkan grafis pada gambar input, pertama-tama dapatkan hasilnya dari ML Kit, lalu render gambar dan tempatkan grafis dalam satu langkah. Dengan demikian, Anda hanya merender ke permukaan tampilan sekali untuk setiap frame input yang diproses. Lihat updatePreviewOverlayViewWithLastFrame dalam contoh panduan memulai ML Kit sebagai contoh.
  • Pertimbangkan untuk mengambil gambar dengan resolusi lebih rendah. Namun, perhatikan juga persyaratan dimensi gambar API ini.
  • Untuk menghindari kemungkinan penurunan performa, jangan jalankan beberapa instance TextRecognizer dengan opsi skrip yang berbeda secara serentak.