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

توفّر هذه الأدوات حزمة تطوير برامج (SDK) محسَّنة لميزة رصد الوضعية.

اسم حزمة تطوير البرامج (SDK)PoseDetectionPoseDetectionAccurate
التنفيذوتكون مواد العرض لأداة الرصد الأساسية مرتبطة بشكل ثابت بتطبيقك في وقت الإصدار.وتكون مواد العرض لأداة الرصد الدقيقة مرتبطة بشكل ثابت بتطبيقك في وقت الإصدار.
حجم التطبيقالحد الأقصى لحجم الملف هو 29.6 ميغابايت.حتى 33.2 ميغابايت
عروض أداءiPhone X: 45 لقطة في الثانية تقريبًاهاتف iPhone X: حوالى 29 لقطة في الثانية

التجربة الآن

  • جرّب نموذج التطبيق للاطّلاع على مثال لاستخدام واجهة برمجة التطبيقات هذه.

قبل البدء

  1. أدرِج مجموعات أدوات تعلُّم الآلة التالية في ملف Podfile:

    # If you want to use the base implementation:
    pod 'GoogleMLKit/PoseDetection', '3.2.0'
    
    # If you want to use the accurate implementation:
    pod 'GoogleMLKit/PoseDetectionAccurate', '3.2.0'
    
  2. بعد تثبيت مجموعات مشروعك أو تحديثها، افتح مشروع Xcode باستخدام xcworkspace. تتوفّر أدوات تعلّم الآلة في الإصدار 13.2.1 أو الإصدارات الأحدث من Xcode.

1- إنشاء مثيل لـ PoseDetector

لاكتشاف وضع في صورة، عليك أولاً إنشاء مثيل PoseDetector وتحديد إعدادات أداة الرصد اختياريًا.

PoseDetector خيار

وضع الرصد

يعمل "PoseDetector" في وضعَين للرصد. تأكد من اختيار الأداة التي تتطابق مع حالة استخدامك.

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

حدِّد خيارات أداة رصد الوضعية:

Swift

// Base pose detector with streaming, when depending on the PoseDetection SDK
let options = PoseDetectorOptions()
options.detectorMode = .stream

// Accurate pose detector on static images, when depending on the
// PoseDetectionAccurate SDK
let options = AccuratePoseDetectorOptions()
options.detectorMode = .singleImage

Objective-C

// Base pose detector with streaming, when depending on the PoseDetection SDK
MLKPoseDetectorOptions *options = [[MLKPoseDetectorOptions alloc] init];
options.detectorMode = MLKPoseDetectorModeStream;

// Accurate pose detector on static images, when depending on the
// PoseDetectionAccurate SDK
MLKAccuratePoseDetectorOptions *options =
    [[MLKAccuratePoseDetectorOptions alloc] init];
options.detectorMode = MLKPoseDetectorModeSingleImage;

أخيرًا، احصل على مثيل لـ PoseDetector. مرر الخيارات التي حددتها:

Swift

let poseDetector = PoseDetector.poseDetector(options: options)

Objective-C

MLKPoseDetector *poseDetector =
    [MLKPoseDetector poseDetectorWithOptions:options];

2- تجهيز صورة الإدخال

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

أنشئ كائن 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

var results: [Pose]
do {
  results = try poseDetector.results(in: image)
} catch let error {
  print("Failed to detect pose with error: \(error.localizedDescription).")
  return
}
guard let detectedPoses = results, !detectedPoses.isEmpty else {
  print("Pose detector returned no results.")
  return
}

// Success. Get pose landmarks here.

Objective-C

NSError *error;
NSArray *poses = [poseDetector resultsInImage:image error:&error];
if (error != nil) {
  // Error.
  return;
}
if (poses.count == 0) {
  // No pose detected.
  return;
}

// Success. Get pose landmarks here.

لرصد العناصر بشكل غير متزامن:

Swift

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

  // Success. Get pose landmarks here.
}

Objective-C

[poseDetector processImage:image
                completion:^(NSArray * _Nullable poses,
                             NSError * _Nullable error) {
                    if (error != nil) {
                      // Error.
                      return;
                    }
                    if (poses.count == 0) {
                      // No pose detected.
                      return;
                    }

                    // Success. Get pose landmarks here.
                  }];

4. الحصول على معلومات حول الوضع الذي تم رصده

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

إذا لم يكن الشخص داخل الصورة بالكامل، فإن النموذج يعين إحداثيات المعالم المفقودة خارج الإطار ويمنحه قيم InFrameConfidence منخفضة.

في حال عدم رصد أي شخص، تكون المصفوفة فارغة.

Swift

for pose in detectedPoses {
  let leftAnkleLandmark = pose.landmark(ofType: .leftAnkle)
  if leftAnkleLandmark.inFrameLikelihood > 0.5 {
    let position = leftAnkleLandmark.position
  }
}

Objective-C

for (MLKPose *pose in detectedPoses) {
  MLKPoseLandmark *leftAnkleLandmark =
      [pose landmarkOfType:MLKPoseLandmarkTypeLeftAnkle];
  if (leftAnkleLandmark.inFrameLikelihood > 0.5) {
    MLKVision3DPoint *position = leftAnkleLandmark.position;
  }
}

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

تعتمد جودة النتائج على جودة الصورة التي يتم إدخالها:

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

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

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

الخطوات التالية