تشخیص متن در تصاویر با کیت ML در iOS

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

Text Recognition API
شرح متن لاتین را در تصاویر یا ویدیوها تشخیص دهید.
نام SDK GoogleMLKit/TextRecognition (version 2.2.0)
پیاده سازی دارایی ها به صورت ایستا به برنامه شما در زمان ساخت مرتبط می شوند.
تاثیر اندازه برنامه حدود 20 مگابایت
کارایی زمان واقعی در اکثر دستگاه ها.

آن را امتحان کنید

قبل از اینکه شروع کنی

  1. غلاف‌های کیت ML زیر را در فایل پادفایل خود قرار دهید:
    pod 'GoogleMLKit/TextRecognition','2.2.0'
    
  2. پس از نصب یا به روز رسانی Pods پروژه خود، پروژه Xcode خود را با استفاده از .xcworkspace . آن باز کنید. کیت ML در Xcode نسخه 12.4 یا بالاتر پشتیبانی می شود.

1. یک نمونه از TextRecognizer

با فراخوانی +textRecognizer یک نمونه از TextRecognizer ایجاد کنید:

سریع

let textRecognizer = TextRecognizer.textRecognizer()
      

هدف-C

MLKTextRecognizer *textRecognizer = [MLKTextRecognizer textRecognizer];
      

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

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

با استفاده از UIImage یا CMSampleBuffer VisionImage .

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

  • با VisionImage یک شی UIImage کنید. مطمئن شوید که جهت .orientation را مشخص کرده اید.

    سریع

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

    هدف-C

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

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

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

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

    سریع

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

    هدف-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;
      }
    }
          
  • یک شی VisionImage با استفاده از شی CMSampleBuffer و جهت گیری ایجاد کنید:

    سریع

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

    هدف-C

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

3. تصویر را پردازش کنید

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

سریع

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

هدف-C

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

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

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

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

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

مثلا:

سریع

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

هدف-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;
    }
  }
}

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

  • برای اینکه کیت ML بتواند متن را به طور دقیق تشخیص دهد، تصاویر ورودی باید حاوی متنی باشند که با داده پیکسلی کافی نشان داده شود. در حالت ایده آل، هر کاراکتر باید حداقل 16x16 پیکسل باشد. به طور کلی هیچ مزیت دقت برای کاراکترهای بزرگتر از 24x24 پیکسل وجود ندارد.

    بنابراین، برای مثال، یک تصویر 640x480 ممکن است برای اسکن کارت ویزیتی که تمام عرض تصویر را اشغال می کند، به خوبی کار کند. برای اسکن یک سند چاپ شده روی کاغذ با اندازه حرف، ممکن است به یک تصویر 720x1280 پیکسل نیاز باشد.

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

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

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

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