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
DeskripsiMengenali teks skrip Latin dalam gambar atau video.
Nama SDKGoogleMLKit/TextRecognition (version 2.2.0)
PenerapanAset ditautkan secara statis ke aplikasi Anda pada waktu build.
Dampak ukuran aplikasiSekitar 20 MB
PerformaReal-time di sebagian besar perangkat.

Cobalah

Sebelum memulai

  1. Sertakan pod ML Kit berikut di Podfile Anda:
    pod 'GoogleMLKit/TextRecognition','2.2.0'
    
  2. Setelah Anda menginstal atau mengupdate Pod project, buka project Xcode menggunakan .xcworkspace-nya. ML Kit didukung di Xcode versi 12.4 atau yang lebih baru.

1. Membuat instance TextRecognizer

Buat instance TextRecognizer dengan memanggil +textRecognizer:

Swift

let textRecognizer = TextRecognizer.textRecognizer()
      

Objective-C

MLKTextRecognizer *textRecognizer = [MLKTextRecognizer textRecognizer];
      

2. Persiapkan 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. Mengekstrak 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 objek TextLine atau lebih. Setiap objek TextLine berisi nol objek TextElement atau lebih, 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 area 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 secara akurat mengenali teks, gambar input harus berisi teks yang diwakili oleh data piksel yang cukup. Idealnya, setiap karakter harus berukuran minimal 16x16 piksel. Umumnya, tidak ada manfaat akurasi yang lebih besar untuk karakter yang berukuran lebih besar dari 24x24 piksel.

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

  • Fokus gambar yang buruk dapat memengaruhi akurasi pengenalan teks. Jika tidak memperoleh hasil yang layak, 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 sebanyak mungkin gambar, dan ambil gambar dengan resolusi lebih rendah (dengan tetap memperhatikan 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 secara sinkron dari frame video yang diberikan. Simpan alwaysDiscardsLateVideoFrames AVCaptureVideoDataOutput sebagai true untuk membatasi panggilan ke detektor. Jika frame video baru tersedia saat detektor sedang berjalan, frame 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 untuk mengetahui contohnya.
  • Pertimbangkan untuk mengambil gambar dengan resolusi lebih rendah. Namun, perhatikan juga persyaratan dimensi gambar API ini.