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

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

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

التجربة الآن

قبل البدء

  1. تضمين مجموعات ML Kit التالية في 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 بكسل على الأقل. ولا تفيد الدقة بشكل عام في أن يزيد حجم الأحرف عن 24×24 بكسل.

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

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

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

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

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