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

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

Text Recognition v2 API
الوصفالتعرّف على النصوص في الصور أو الفيديوهات، واستخدام النصوص اللاتينية والصينية والدفنغارية واليابانية والكورية ومجموعة كبيرة من اللغات
أسماء حِزم تطوير البرامج (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', '7.0.0'
    # To recognize Chinese script
    pod 'GoogleMLKit/TextRecognitionChinese', '7.0.0'
    # To recognize Devanagari script
    pod 'GoogleMLKit/TextRecognitionDevanagari', '7.0.0'
    # To recognize Japanese script
    pod 'GoogleMLKit/TextRecognitionJapanese', '7.0.0'
    # To recognize Korean script
    pod 'GoogleMLKit/TextRecognitionKorean', '7.0.0'
    
  2. بعد تثبيت حِزم Pods في مشروعك أو تعديلها، افتح مشروع Xcode باستخدام .xcworkspace. تتوفّر حزمة ML Kit في الإصدار 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;
    }
  }
}

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

  • لكي تتمكّن حزمة ML Kit من التعرّف على النص بدقة، يجب أن تحتوي صور الإدخال على نص يمثّله بيانات بكسل كافية. من الأفضل أن يكون حجم كل حرف 16×16 بكسل على الأقل. لا يُحسِّن بشكل عام حجم الأحرف الأكبر من 24×24 بكسل من دقتها.

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

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

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

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

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