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

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

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

جرّبه الآن

قبل البدء

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

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

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

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

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

تحقق أيضًا من أداة Material Design مجموعة أنماط الميزات المستنِدة إلى تعلُّم الآلة:

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

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