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

توفّر "حزمة تعلّم الآلة" حزمتَي SDK محسّنتَين لرصد وضعية الجسم.

اسم حزمة SDKPoseDetectionPoseDetectionAccurate
التنفيذيتم ربط مواد العرض الخاصة بأداة الرصد الأساسية بتطبيقك بشكل ثابت في وقت الإنشاء.يتم ربط مواد العرض الخاصة بأداة الرصد الدقيقة بتطبيقك بشكل ثابت في وقت الإنشاء.
حجم التطبيقما يصل إلى 29.6 ميغابايتما يصل إلى 33.2 ميغابايت
الأداء‫iPhone X: ‏~45 لقطة في الثانية‫iPhone X: ‏~29 لقطة في الثانية

للتجربة:

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

قبل البدء

  1. أدرِج مجموعات الإعلانات المتسلسلة التالية من "حزمة تعلّم الآلة" في ملف Podfile:

    # If you want to use the base implementation:
    pod 'GoogleMLKit/PoseDetection', '8.0.0'
    
    # If you want to use the accurate implementation:
    pod 'GoogleMLKit/PoseDetectionAccurate', '8.0.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 من 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

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 Detection إما مصفوفة من عناصر 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 بكسل على الأقل.
  • إذا كنت ترصد وضعية الجسم في تطبيق في الوقت الفعلي، قد تحتاج أيضًا إلى مراعاة الأبعاد الإجمالية للصور المُدخلة. يمكن معالجة الصور الأصغر حجمًا بشكل أسرع، لذا لتقليل وقت الاستجابة، يمكنك التقاط الصور بدقة أقل، ولكن مع مراعاة متطلبات الدقة المذكورة أعلاه والتأكّد من أنّ الموضوع يشغل أكبر قدر ممكن من الصورة.
  • ويمكن أن يؤثر التركيز الضعيف للصورة أيضًا في الدقة. إذا لم تحصل على نتائج مقبولة، اطلب من المستخدم إعادة التقاط الصورة.

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

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

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