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

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

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

للتجربة:

قبل البدء

  1. أدرِج مجموعات الإعلانات المتسلسلة التالية من "حزمة تعلّم الآلة" في ملف 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. تتوفّر "حزمة تعلّم الآلة" في الإصدار 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 مناسبة لمسح بطاقة أعمال تشغل عرض الصورة بالكامل. لمسح مستند مطبوع على ورق بحجم Letter ضوئيًا، قد تكون هناك حاجة إلى صورة بدقة 720×1280 بكسل.

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

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

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

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