شناسایی کردن نوشتار در تصاویر با ML Kit در iOS

می‌توانید از ML Kit برای تشخیص نوشتار در تصاویر یا ویدیوها، مثل نوشتار تابلو خیابان، استفاده کنید. ویژگی‌های اصلی این ویژگی عبارت‌اند از:

Text Recognition v2 API
شرحتشخیص نوشتار در تصاویر یا ویدیوها، پشتیبانی از الفبای لاتین، چینی، دوناگری، ژاپنی، و کره‌ای و طیف گسترده‌ای از زبان‌ها.
نام‌های کیت توسعه نرم‌افزارGoogleMLKit/TextRecognition
GoogleMLKit/TextRecognitionChinese
GoogleMLKit/TextRecognitionDevanagari
GoogleMLKit/TextRecognitionJapanese
GoogleMLKit/TextRecognitionKorean
پیاده‌سازیدارایی‌ها در زمان ساخت به‌صورت ایستا به برنامه شما پیوند داده می‌شوند
تأثیر اندازه برنامهحدود ۳۸ مگابایت برای هر کیت توسعه نرم‌افزار دستورگان
عملکرددر اکثر دستگاه‌ها برای «کیت توسعه نرم‌افزار» خط لاتین به‌صورت هم‌زمان، برای بقیه کندتر.

امتحان کنید

  • با برنامه نمونه بازی کنید تا نمونه‌ای از استفاده از این API را ببینید.
  • با codelab خودتان کد را امتحان کنید.

قبل‌از شروع

  1. پادهای ML Kit زیر را در Podfile خود اضافه کنید:
    # 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. پس‌از نصب یا به‌روزرسانی Pods پروژه، پروژه Xcode خود را بااستفاده از .xcworkspace باز کنید. ‫ML Kit در Xcode نسخه ۱۲.۴ یا بالاتر پشتیبانی می‌شود.

۱. ایجاد نمونه‌ای از TextRecognizer

با فراخوانی +textRecognizer(options:)، نمونه‌ای از TextRecognizer ایجاد کنید و گزینه‌های مربوط به کیت توسعه نرم‌افزار را که به‌عنوان وابستگی در بالا اعلام کرده‌اید ارسال کنید:

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)

آبجکتیو-سی

// 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];

۲. آماده کردن تصویر ورودی

تصویر را به‌عنوان UIImage یا CMSampleBufferRef به روش process(_:completion:) در TextRecognizer ارسال کنید:

بااستفاده از UIImage یا CMSampleBuffer، یک شیء VisionImage ایجاد کنید.

اگر از UIImage استفاده می‌کنید، این مراحل را دنبال کنید:

  • یک شیء VisionImage با UIImage ایجاد کن. حتماً .orientation صحیح را مشخص کنید.

    Swift

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

    آبجکتیو-سی

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

اگر از CMSampleBuffer استفاده می‌کنید، این مراحل را دنبال کنید:

  • جهت داده‌های تصویر موجود در CMSampleBuffer را مشخص کنید.

    برای دریافت جهت تصویر:

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

    آبجکتیو-سی

    - (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 و جهت‌گیری، شیء VisionImage ایجاد کنید:

    Swift

    let image = VisionImage(buffer: sampleBuffer)
    image.orientation = imageOrientation(
      deviceOrientation: UIDevice.current.orientation,
      cameraPosition: cameraPosition)

    آبجکتیو-سی

     MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer];
     image.orientation =
       [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                    cameraPosition:cameraPosition];

۳. پردازش تصویر

سپس تصویر را به روش process(_:completion:) ارسال کنید:

Swift

textRecognizer.process(visionImage) { result, error in
  guard error == nil, let result = result else {
    // Error handling
    return
  }
  // Recognized text
}

آبجکتیو-سی

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

۴. استخراج نوشتار از بلوک‌های نوشتار شناسایی‌شده

اگر عملیات تشخیص نوشتار موفقیت‌آمیز باشد، شیء Text را برمی‌گرداند. شیء Text حاوی نوشتار کامل شناسایی‌شده در تصویر و صفر یا چند شیء TextBlock است.

هر TextBlock نشان‌دهنده یک بلوک مستطیلی از نوشتار است که شامل صفر یا چند شیء TextLine است. هر TextLine شیء حاوی صفر یا چند شیء TextElement است که نشان‌دهنده کلمات و نهادهای کلمه‌مانند مثل تاریخ‌ها و اعداد است.

برای هر شیء TextBlock، TextLine، و TextElement، می‌توانید نوشتار تشخیص‌داده‌شده در منطقه و مختصات محدودکننده منطقه را دریافت کنید.

برای مثال:

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

آبجکتیو-سی

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

دستورالعمل‌های تصویر ورودی

  • برای اینکه ML Kit بتواند نوشتار را به‌دقت تشخیص دهد، تصاویر ورودی باید حاوی نوشتاری باشد که با داده‌های پیکسل کافی نمایش داده شده باشد. در حالت ایده‌آل، هر نویسه باید حداقل ۱۶x۱۶ پیکسل باشد. به‌طورکلی، بزرگ‌تر بودن نویسه‌ها از ۲۴x۲۴ پیکسل باعث بهبود دقت نمی‌شود.

    بنابراین، برای مثال، تصویر ۶۴۰x۴۸۰ ممکن است برای اسکن کارت ویزیت که تمام عرض تصویر را اشغال می‌کند خوب کار کند. برای اسکن کردن سند چاپ‌شده روی کاغذ اندازه نامه، ممکن است تصویر ۷۲۰x۱۲۸۰ پیکسل لازم باشد.

  • فوکوس ضعیف تصویر می‌تواند بر دقت تشخیص نوشتار تأثیر بگذارد. اگر نتایج قابل‌قبول نیست، از کاربر بخواهید تصویر را دوباره بگیرد.

  • اگر درحال تشخیص دادن نوشتار در یک برنامه هم‌زمان هستید، باید ابعاد کلی تصاویر ورودی را درنظر بگیرید. تصاویر کوچک‌تر سریع‌تر پردازش می‌شوند. برای کاهش تأخیر، مطمئن شوید که نوشتار تا حد امکان بخش بزرگی از تصویر را اشغال کند و تصاویر را با وضوح پایین‌تر ضبط کنید (با درنظر گرفتن الزامات دقت که در بالا ذکر شد). برای اطلاعات بیشتر، نکته‌هایی برای بهبود عملکرد را ببینید.

نکته‌هایی برای بهبود عملکرد

  • برای پردازش قاب‌های ویدیو، از results(in:) میانای برنامه‌سازی کاربردی هم‌زمان آشکارساز استفاده کنید. این روش را از تابع AVCaptureVideoDataOutputSampleBufferDelegate captureOutput(_, didOutput:from:) فراخوانی کنید تا نتایج را به‌صورت هم‌زمان از قاب ویدیو داده‌شده دریافت کنید. AVCaptureVideoDataOutput alwaysDiscardsLateVideoFrames را به‌عنوان true نگه دارید تا تماس‌های برقرارشده با آشکارساز را محدود کنید. اگر قاب ویدیو جدیدی درحین اجرای آشکارساز دردسترس قرار گیرد، حذف خواهد شد.
  • اگر از خروجی آشکارساز برای هم‌پوشانی گرافیک روی تصویر ورودی استفاده می‌کنید، ابتدا نتیجه را از ML Kit دریافت کنید، سپس تصویر و هم‌پوشانی را در یک مرحله رندر کنید. با انجام این کار، برای هر قاب ورودی پردازش‌شده، فقط یک‌بار به سطح نمایشگر رندر می‌کنید. برای نمونه، updatePreviewOverlayViewWithLastFrame را در نمونه راه‌اندازی سریع ML Kit ببینید.
  • تصاویر را با وضوح پایین‌تری ضبط کنید. بااین‌حال، الزامات ابعاد تصویر این API را نیز درنظر داشته باشید.
  • برای جلوگیری از افت عملکرد احتمالی، چندین نمونه TextRecognizer را با گزینه‌های مختلف هم‌زمان اجرا نکنید.