رصد العناصر وتتبّعها باستخدام ML Kit على نظام التشغيل iOS

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.

يمكنك استخدام مجموعة أدوات تعلّم الآلة لرصد الكائنات وتتبُّعها في إطارات الفيديو المتتالية.

عند تمرير صورة إلى مجموعة أدوات تعلّم الآلة، يتم رصد ما يصل إلى خمسة كائنات في الصورة بالإضافة إلى موضع كل عنصر في الصورة. عند اكتشاف عناصر في مجموعات بث الفيديو، يكون لكل كائن معرّف فريد يمكنك استخدامه لتتبع الكائن من إطار إلى آخر. ويمكنك اختياريًا تفعيل تصنيف الكائنات بشكل خشن، والذي يصنِّف الكائنات باستخدام أوصاف فئات واسعة.

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

قبل البدء

  1. أدرِج لوحات ML Kit التالية في Podfile:
    pod 'GoogleMLKit/ObjectDetection', '3.2.0'
    
  2. بعد تثبيت لوحات إصدار المشروع أو تعديلها، افتح مشروع Xcode باستخدام .xcworkspace. يتم دعم ML Kit في Xcode الإصدار 12.4 أو أعلى.

1- ضبط أداة رصد الكائنات

لاكتشاف الكائنات وتتبعها، أنشئ أولاً مثيلاً لـ ObjectDetector وحدد اختياريًا أي إعدادات أداة رصد تريد تغييرها من الإعداد التلقائي.

  1. اضبط أداة رصد الكائنات في حالة الاستخدام باستخدام كائن ObjectDetectorOptions. يمكنك تغيير الإعدادات التالية:

    إعدادات أداة كشف الكائنات
    وضع الاكتشاف .stream (تلقائي) | .singleImage

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

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

    اكتشاف كائنات متعددة وتتبعها false (تلقائي) | true

    يمكنك رصد ما يصل إلى خمسة كائنات أو تتبّعها أو رصد الكائن الأبرز فقط (الإعداد التلقائي).

    تصنيف العناصر false (تلقائي) | true

    لتحديد ما إذا كان سيتم تصنيف الكائنات المكتشفة ضمن فئات تقريبية. عند تفعيل أداة رصد الكائنات، تصنّف العناصر ضمن الفئات التالية: سلع الأزياء والطعام والسلع المنزلية والنباتات والنباتات.

    تم تحسين واجهة برمجة التطبيقات لاكتشاف العناصر وتتبع واجهة برمجة التطبيقات لهاتين حالتي الاستخدام الأساسية:

    • الاكتشاف المباشر وتتبع أكثر الكائنات البارزة في عدسة الكاميرا.
    • اكتشاف كائنات متعددة في صورة ثابتة.

    لتهيئة واجهة برمجة التطبيقات لحالات الاستخدام هذه:

Swift

// Live detection and tracking
let options = ObjectDetectorOptions()
options.shouldEnableClassification = true

// Multiple object detection in static images
let options = ObjectDetectorOptions()
options.detectorMode = .singleImage
options.shouldEnableMultipleObjects = true
options.shouldEnableClassification = true

Objective-C

// Live detection and tracking
MLKObjectDetectorOptions *options = [[MLKObjectDetectorOptions alloc] init];
options.shouldEnableClassification = YES;

// Multiple object detection in static images
MLKObjectDetectorOptions *options = [[MLKOptions alloc] init];
options.detectorMode = MLKObjectDetectorModeSingleImage;
options.shouldEnableMultipleObjects = YES;
options.shouldEnableClassification = YES;
  1. الحصول على مثال ObjectDetector:

Swift

let objectDetector = ObjectDetector.objectDetector()

// Or, to change the default settings:
let objectDetector = ObjectDetector.objectDetector(options: options)

Objective-C

MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetector];

// Or, to change the default settings:
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];

2. إعداد صورة الإدخال

لاكتشاف الكائنات وتتبعها، عليك إجراء ما يلي لكل صورة أو إطار فيديو. في حال تفعيل وضع البث، يجب إنشاء VisionImage عنصر من CMSampleBuffer.

يمكنك إنشاء كائن 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- معالجة الصورة

مرِّر VisionImage إلى إحدى طرق معالجة الصور في أداة رصد الكائنات. يمكنك إما استخدام طريقة process(image:) غير المتزامنة أو طريقة results() المتزامنة.

لاكتشاف الكائنات بشكل غير متزامن:

Swift

objectDetector.process(image) { objects, error in
  guard error == nil else {
    // Error.
    return
  }
  guard !objects.isEmpty else {
    // No objects detected.
    return
  }

  // Success. Get object info here.
  // ...
}

Objective-C

[objectDetector processImage:image
                  completion:^(NSArray * _Nullable objects,
                               NSError * _Nullable error) {
                    if (error == nil) {
                      return;
                    }
                    if (objects.count == 0) {
                      // No objects detected.
                      return;
                    }

                    // Success. Get object info here.
                  }];

لاكتشاف الكائنات بشكل متزامن:

Swift

var objects: [Object]
do {
  objects = try objectDetector.results(in: image)
} catch let error {
  print("Failed to detect object with error: \(error.localizedDescription).")
  return
}
guard !objects.isEmpty else {
  print("Object detector returned no results.")
  return
}

// Success. Get object info here.

Objective-C

NSError *error;
NSArray *objects = [objectDetector resultsInImage:image error:&error];
if (error == nil) {
  return;
}
if (objects.count == 0) {
  // No objects detected.
  return;
}

// Success. Get object info here.

4. الحصول على معلومات حول الكائنات التي تم رصدها

إذا تم استدعاء معالج الصور بنجاح، سيمرر قائمة من Object إلى معالج الإكمال أو يعرض القائمة، بناءً على ما إذا تم استدعاء الطريقة غير المتزامنة أو المتزامنة.

يحتوي كل Object على الخصائص التالية:

frame تمثل هذه الخاصية CGRect موضع الكائن في الصورة.
trackingID عدد صحيح يعرّف الكائن عبر الصور، أو "nil" في وضع صورة واحدة.
labels مصفوفة من العلامات تصف الكائن الذي تعرضه أداة الكشف. وتكون الخاصية فارغة في حال ضبط خيار أداة الرصد shouldEnableClassification على false.

Swift

// objects contains one item if multiple object detection wasn't enabled.
for object in objects {
  let frame = object.frame
  let trackingID = object.trackingID

  // If classification was enabled:
  let description = object.labels.enumerated().map { (index, label) in
    "Label \(index): \(label.text), \(label.confidence)"
    }.joined(separator:"\n")

}

Objective-C

// The list of detected objects contains one item if multiple
// object detection wasn't enabled.
for (MLKObject *object in objects) {
  CGRect frame = object.frame;
  NSNumber *trackingID = object.trackingID;
  for (MLKObjectLabel *label in object.labels) {
    NSString *labelString = [NSString stringWithFormat: @"%@, %f, %lu",
      label.text, label.confidence, (unsigned long)label.index];
    ...
  }
}

تحسين سهولة الاستخدام والأداء

للحصول على أفضل تجربة للمستخدم، اتبع الإرشادات التالية في تطبيقك:

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

وتحقق أيضًا من مجموعة أنماط التصميم متعدد الأبعاد للميزات التي تعتمد على التعلم الآلي.

عند استخدام وضع البث في تطبيق في الوقت الفعلي، اتبع الإرشادات التالية للحصول على أفضل معدلات عرض إطارات:

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