التعرّف على النص في الصور باستخدام حزمة تعلّم الآلة على نظام التشغيل iOS

يمكنك استخدام أدوات تعلّم الآلة للتعرّف على النص في الصور أو الفيديوهات، مثل نص لافتة الشارع. السمات الرئيسية لهذه الميزة هي:

واجهة برمجة التطبيقات Text Recognition v2 API
الوصفتتيح لك هذه الميزة التعرّف على النص في الصور أو الفيديوهات، كما تتيح لك استخدام النصوص اللاتينية والصينية والديفاناغارية واليابانية والكورية ومجموعة واسعة من اللغات.
أسماء حزم تطوير البرامج (SDK)GoogleMLKit/TextRecognition
GoogleMLKit/TextRecognitionChinese
GoogleMLKit/TextRecognitionDevanagari
GoogleMLKit/TextRecognitionJapanese
GoogleMLKit/TextRecognitionKorean
التنفيذترتبط مواد العرض بشكلٍ ثابت بتطبيقك في وقت الإصدار.
تأثير حجم التطبيقحوالي 38 ميغابايت لكل حزمة SDK لنص برمجي
عروض أداءفي الوقت الفعلي على معظم الأجهزة لحزمة تطوير البرامج (SDK) للنصوص اللاتينية، يكون هذا أبطأ على الأجهزة الأخرى.

تجربة السمات والبيانات

قبل البدء

  1. أدرِج مجموعات تعلّم الآلة التالية في ملف Podfile:
    # 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. بعد تثبيت مجموعات المشروع أو تحديثها، افتح مشروع Xcode باستخدام .xcworkspace. تتوفّر هذه الأدوات في الإصدار 12.4 من Xcode أو الإصدارات الأحدث.

1- إنشاء مثيل TextRecognizer

يمكنك إنشاء مثيل TextRecognizer من خلال استدعاء +textRecognizer(options:)، مع تمرير الخيارات المتعلقة بحزمة تطوير البرامج (SDK) التي أشرت إليها باعتبارها اعتمادًا على أعلاه:

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. تجهيز صورة الإدخال

اضبط الصورة كـ UIImage أو CMSampleBufferRef إلى طريقة process(_:completion:) في TextRecognizer:

أنشِئ كائن VisionImage باستخدام UIImage أو CMSampleBuffer.

إذا كنت تستخدم UIImage، يُرجى اتّباع الخطوات التالية:

  • أنشِئ كائن VisionImage باستخدام UIImage. تأكَّد من تحديد سمة .orientation الصحيحة.

    Swift

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

    Objective-C

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

    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;
      }
    }
          
  • يمكنك إنشاء كائن VisionImage باستخدام كائن 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. معالجة الصورة

بعد ذلك، مرِّر الصورة إلى طريقة 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. استخراج النص من مجموعات من النصوص التي تم التعرّف عليها

إذا نجحت عملية التعرّف على النص، سيتم عرض الكائن 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
        }
    }
}

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

إرشادات إدخال صورة

  • لكي تتعرّف أدوات تعلّم الآلة على النص بدقة، يجب أن تتضمّن صور الإدخال نصًا يتم تمثيله ببيانات بكسل كافية. ويُفضَّل أن يكون حجم كل حرف 16×16 بكسل على الأقل. بشكل عام، لا فائدة من الدقة إذا كان حجم الأحرف أكبر من 24x24 بكسل.

    على سبيل المثال، قد تكون صورة بحجم 640×480 مناسبة لمسح بطاقة نشاط تجاري بالعرض الكامل للصورة ضوئيًا. لمسح مستند مطبوع على ورق بحجم الحرف، قد يلزم توفير صورة بحجم 720×1280 بكسل.

  • يمكن أن يؤثر ضعف التركيز على الصورة في دقة التعرّف على النص. وإذا لم تحصل على نتائج مقبولة، حاوِل أن تطلب من المستخدم إعادة استعراض الصورة.

  • إذا كنت تتعرّف على نص في تطبيق في الوقت الفعلي، عليك مراعاة الأبعاد العامة للصور التي يتم إدخالها. ويمكن معالجة الصور الأصغر حجمًا بشكل أسرع. لتقليل وقت الاستجابة، تأكَّد من أنّ النص يشغل أكبر قدر ممكن من الصورة، والتقِط الصور بدرجات دقة أقل (مع مراعاة متطلبات الدقة المذكورة أعلاه). للحصول على مزيد من المعلومات، يُرجى الاطّلاع على نصائح لتحسين الأداء.

نصائح لتحسين الأداء

  • لمعالجة إطارات الفيديو، استخدِم واجهة برمجة التطبيقات results(in:) المتزامنة لأداة الرصد. وعليك استدعاء هذه الطريقة من دالة captureOutput(_, didOutput:from:) في AVCaptureVideoDataOutputSampleBufferDelegate للحصول على النتائج بشكل متزامن من إطار الفيديو المعنيّ. يجب إبقاء alwaysDiscardsLateVideoFrames على جهاز AVCaptureVideoDataOutput كقيمة "true" للتحكّم في المكالمات الواردة إلى أداة الرصد. في حال توفّر إطار فيديو جديد أثناء تشغيل أداة الرصد، سيتم تجاهله.
  • إذا كنت تستخدم إخراج أداة الكشف لتركيب الرسومات على صورة الإدخال، احصل أولاً على النتيجة من أدوات تعلّم الآلة، ثم يمكنك عرض الصورة والتراكب في خطوة واحدة. وبذلك، ستعرض على سطح الشاشة مرة واحدة فقط لكل إطار إدخال تمت معالجته. للاطّلاع على مثال، يمكنك الاطّلاع على updatePreviewOverlayViewWithLastFrame في نموذج البدء السريع في حزمة ML Kit.
  • ننصحك بالتقاط الصور بدقة أقل. وعليك أيضًا مراعاة متطلبات أبعاد الصورة في واجهة برمجة التطبيقات هذه.
  • لتجنُّب أي تدهور محتمل في الأداء، يُرجى عدم تشغيل نُسخ TextRecognizer متعددة تتضمّن خيارات نصوص برمجية مختلفة في الوقت نفسه.