دليل التعرّف على الإيماءات لنظام التشغيل iOS

تتيح لك مهمة MediaPipe Gesture Recognizer (معرّف إيماءات MediaPipe) التعرّف على إيماءات اليد في الوقت الفعلي، وprovides the recognized hand gesture results and hand landmarks of the detected hands (توفّر نتائج إيماءات اليد التي تم التعرّف عليها ومواقع اليد المميّزة لليدين التي تم رصدها). توضح لك هذه التعليمات كيفية استخدام أداة التعرف على الإيماءة مع تطبيقات iOS.

يمكنك الاطّلاع على هذه المهمة أثناء تنفيذها من خلال مشاهدة العرض التمهيدي للويب. للحصول على مزيد من المعلومات عن الإمكانات والنماذج وخيارات الضبط الخاصة بهذه المهمة، اطّلِع على نظرة عامة.

مثال على الرمز البرمجي

رمز مثال "مهام MediaPipe" هو تنفيذ أساسي لتطبيق "التعرّف على الإيماءة" لنظام التشغيل iOS. يستخدم المثال الكاميرا على جهاز iOS مادي لرصد إيماءات اليد باستمرار، ويمكنه أيضًا استخدام الصور والفيديوهات من معرض الجهاز لرصد الإيماءات بشكل ثابت.

يمكنك استخدام التطبيق كنقطة بداية لتطبيقك الخاص على نظام التشغيل iOS، أو الرجوع إليه عند تعديل تطبيق حالي. يتم استضافة مثال الرمز البرمجي لـ "معرّف الإيماءات" على GitHub.

تنزيل الرمز

توضّح لك التعليمات التالية كيفية إنشاء نسخة محلية من مثال الرمز البرمجي باستخدام أداة سطر الأوامر git.

لتنزيل نموذج الرمز:

  1. استنسِخ مستودع git باستخدام الأمر التالي:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. يمكنك اختياريًا ضبط مثيل git لاستخدام ميزة "الفحص الخفيف"، بحيث تتوفّر لديك فقط ملفات مثال تطبيق "معرّف الإيماءات":

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/gesture_recognizer/ios/
    

بعد إنشاء نسخة محلية من نموذج الرمز البرمجي، يمكنك تثبيت مكتبة مهام MediaPipe وفتح المشروع باستخدام Xcode وتشغيل التطبيق. للاطّلاع على التعليمات، راجِع دليل الإعداد لنظام التشغيل iOS.

المكونات الرئيسية

تحتوي الملفات التالية على الرمز البرمجي المهم لمثال تطبيق "معرّف الإيماءات":

  • GestureRecognizerService.swift: لإعداد معرّف الإيماءات، ومعالجة اختيار النموذج، وتنفيذ الاستنتاج على بيانات الإدخال
  • CameraViewController.swift: تُنفِّذ واجهة المستخدم لخلاصة الكاميرا المباشرة وضع الإدخال وتُظهر النتائج بشكل مرئي.
  • MediaLibraryViewController.swift: تُنفِّذ واجهة المستخدم لوضع إدخال ملفَي الصور الثابتة والفيديو، كما تعرض النتائج بشكل مرئي.

ضبط إعدادات الجهاز

يصف هذا القسم الخطوات الرئيسية لإعداد بيئة التطوير و مشاريع الرموز البرمجية لاستخدام "أداة التعرّف على الإيماءات". للحصول على معلومات عامة عن إعداد بيئة التطوير لاستخدام مهام MediaPipe، بما في ذلك متطلبات إصدار النظام الأساسي، يُرجى الاطّلاع على دليل الإعداد لنظام التشغيل iOS.

التبعيات

يستخدم معرّف الإيماءات مكتبة MediaPipeTasksVision التي يجب تثبيتها باستخدام CocoaPods. تتوافق المكتبة مع تطبيقات Swift وObjective-C ولا تتطلّب أي إعدادات إضافية خاصة باللغة.

للحصول على تعليمات لتثبيت CocoaPods على نظام التشغيل macOS، يُرجى الرجوع إلى دليل تثبيت CocoaPods . للحصول على تعليمات حول كيفية إنشاء Podfile باستخدام الحِزم اللازمة لتطبيقك، يُرجى الرجوع إلى مقالة استخدام CocoaPods.

أضِف مجموعة MediaPipeTasksVision في Podfile باستخدام الرمز التالي:

target 'MyGestureRecognizerApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

إذا كان تطبيقك يتضمّن أهداف اختبار الوحدات، يمكنك الرجوع إلى دليل الإعداد لنظام التشغيل iOS للحصول على معلومات إضافية عن إعداد Podfile.

الطراز

تتطلب مهمة التعرّف على الإيماءة MediaPipe نموذجًا مدرّبًا ومتوافقًا مع هذه المهمة. لمزيد من المعلومات عن النماذج المدربة المتاحة لميزة "مُعرِّف الإيماءات"، اطّلِع على قسم نماذج ضمن النظرة العامة على المهمة.

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

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

إنشاء المهمة

يمكنك إنشاء مهمة "معرّف الإيماءات" من خلال استدعاء أحد مُنشئِيها. يقبل مُنشئ GestureRecognizer(options:) قيمًا لخيارات الضبط .

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

تتوافق مهمة "التعرّف على الإيماءات" مع 3 أنواع من بيانات الإدخال: الصور الثابتة وملفات الفيديو وأحداث بث الفيديو المباشر. بشكلٍ تلقائي، يُنشئ GestureRecognizer(modelPath:) مهمة للصور الثابتة. إذا كنت تريد بدء مهمتك لمعالجة ملفات الفيديو أو أحداث بث الفيديو المباشر، استخدِم GestureRecognizer(options:) لتحديد وضع تشغيل الفيديو أو البث المباشر. يتطلب وضع البث المباشر أيضًا استخدام خيار الإعداد الإضافي gestureRecognizerLiveStreamDelegate الذي يتيح لـ "معرّف الإيماءات" إرسال نتائج التعرّف على الإيماءات إلى المفوَّض بشكل غير متزامن.

اختَر علامة التبويب المناسبة لوضع التشغيل لمعرفة كيفية إنشاء المهمة وتنفيذ الاستنتاج.

Swift

صورة

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "gesture_recognizer",
                                      ofType: "task")

let options = GestureRecognizerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

let gestureRecognizer = try GestureRecognizer(options: options)
    

فيديو

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "gesture_recognizer",
                                      ofType: "task")

let options = GestureRecognizerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

let gestureRecognizer = try GestureRecognizer(options: options)
    

بث مباشر

import MediaPipeTasksVision

// Class that conforms to the `GestureRecognizerLiveStreamDelegate` protocol and
// implements the method that the gesture recognizer calls once it finishes
// performing recognizing hand gestures in each input frame.
class GestureRecognizerResultProcessor: NSObject, GestureRecognizerLiveStreamDelegate {

  func gestureRecognizer(
    _ gestureRecognizer: GestureRecognizer,
    didFinishRecognition result: GestureRecognizerResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the gesture recognizer result or errors here.

  }
}

let modelPath = Bundle.main.path(
  forResource: "gesture_recognizer",
  ofType: "task")

let options = GestureRecognizerOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

// Assign an object of the class to the `gestureRecognizerLiveStreamDelegate`
// property.
let processor = GestureRecognizerResultProcessor()
options.gestureRecognizerLiveStreamDelegate = processor

let gestureRecognizer = try GestureRecognizer(options: options)
    

Objective-C

صورة

@import MediaPipeTasksVision;

NSString *modelPath =
  [[NSBundle mainBundle] pathForResource:@"gesture_recognizer"
                                  ofType:@"task"];

MPPGestureRecognizerOptions *options =
  [[MPPGestureRecognizerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

MPPGestureRecognizer *gestureRecognizer =
      [[MPPGestureRecognizer alloc] initWithOptions:options error:nil];
    

فيديو

@import MediaPipeTasksVision;

NSString *modelPath =
  [[NSBundle mainBundle] pathForResource:@"gesture_recognizer"
                                  ofType:@"task"];

MPPGestureRecognizerOptions *options =
  [[MPPGestureRecognizerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

MPPGestureRecognizer *gestureRecognizer =
      [[MPPGestureRecognizer alloc] initWithOptions:options error:nil];
    

بث مباشر

@import MediaPipeTasksVision;

// Class that conforms to the `MPPGestureRecognizerLiveStreamDelegate` protocol
// and implements the method that the gesture recognizer calls once it finishes
// performing gesture recognition on each input frame.

@interface APPGestureRecognizerResultProcessor : NSObject 

@end

@implementation APPGestureRecognizerResultProcessor

-   (void)gestureRecognizer:(MPPGestureRecognizer *)gestureRecognizer
    didFinishRecognitionWithResult:(MPPGestureRecognizerResult *)gestureRecognizerResult
           timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                             error:(NSError *)error {

    // Process the gesture recognizer result or errors here.

}

@end

NSString *modelPath =
  [[NSBundle mainBundle] pathForResource:@"gesture_recognizer"
                                  ofType:@"task"];

MPPGestureRecognizerOptions *options =
  [[MPPGestureRecognizerOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;
options.minHandDetectionConfidence = minHandDetectionConfidence
options.minHandPresenceConfidence = minHandPresenceConfidence
options.minTrackingConfidence = minHandTrackingConfidence
options.numHands = numHands

// Assign an object of the class to the `gestureRecognizerLiveStreamDelegate`
// property.
APPGestureRecognizerResultProcessor *processor =
  [APPGestureRecognizerResultProcessor new];
options.gestureRecognizerLiveStreamDelegate = processor;

MPPGestureRecognizer *gestureRecognizer =
      [[MPPGestureRecognizer alloc] initWithOptions:options error:nil];
    

خيارات الإعداد

تتضمّن هذه المهمة خيارات الضبط التالية لتطبيقات iOS:

اسم الخيار الوصف نطاق القيمة القيمة التلقائية
runningMode لضبط وضع التشغيل للمهمة هناك ثلاثة أوضاع:

IMAGE: وضع الإدخالات المكوّنة من صورة واحدة.

‫VIDEO: وضع الإطارات التي تم فك ترميزها في الفيديو

LIVE_STREAM: وضع البث المباشر لبيانات المعالجة التي يتم إدخالها، مثل البيانات الواردة من كاميرا في هذا الوضع، يجب استدعاء resultsListener لإعداد أداة استماع لتلقّي النتائج بشكل غير متزامن. في هذا الوضع، يجب ضبط gestureRecognizerLiveStreamDelegate على مثيل لفئة تنفِّذ GestureRecognizerLiveStreamDelegate لتلقّي نتائج تنفيذ ميزة التعرّف على الإيماءات بشكل غير متزامن.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
num_hands يمكن رصد الحد الأقصى لعدد الأيدي باستخدام الGestureRecognizer. Any integer > 0 1
min_hand_detection_confidence يشير ذلك إلى الحد الأدنى لنتيجة الثقة لرصد اليد نجاحًا في نموذج رصد راحة اليد. 0.0 - 1.0 0.5
min_hand_presence_confidence الحد الأدنى لنتيجة الثقة في نتيجة توفّر اليد في نموذج رصد معالم اليد في وضع "الفيديو" ووضع "البث المباشر" لميزة "التعرّف على الإيماءات"، إذا كانت نتيجة الثقة في توفّر اليد من نموذج معالم اليد أقل من هذا الحدّ الأدنى، يتم تفعيل نموذج رصد راحة اليد. بخلاف ذلك، يتم استخدام خوارزمية تتبُّع اليد خفيفة الوزن لتحديد موقع اليدين من أجل رصد المعالم اللاحقة. 0.0 - 1.0 0.5
min_tracking_confidence تمثّل هذه السمة الحد الأدنى لنتيجة الثقة ليتم اعتبار تتبُّع اليد بنجاح. هذا هو الحدّ الأدنى لمقياس IoU للحدود المربّعة بين اليدين في الإطار الحالي والإطار الأخير. في وضعَي "الفيديو" و"البث" في ميزة "التعرّف على الإيماءات"، إذا تعذّر التتبّع، تبدأ ميزة "التعرّف على الإيماءات" في رصد اليد. وبخلاف ذلك، يتم تخطي اكتشاف اليد. 0.0 - 1.0 0.5
canned_gestures_classifier_options خيارات تهيئة سلوك مصنف الإيماءات الجاهزة. الإيماءات المُعدّة مسبقًا هي ["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"]
  • لغة الأسماء المعروضة: اللغة المستخدَمة للأسماء المعروضة المحدّدة من خلال البيانات الوصفية لنموذج TFLite، إن توفّرت.
  • الحد الأقصى للنتائج: الحد الأقصى لعدد نتائج التصنيف الأعلى تقييمًا المطلوب عرضها. إذا كان الرقم أقل من 0، سيتم عرض جميع النتائج المتاحة.
  • الحدّ الأدنى للنتيجة: النتيجة التي رُفضت النتائج التي تكون في حال انخفاضها. في حال ضبطه على 0، سيتم عرض جميع النتائج المتاحة.
  • القائمة المسموح بها للفئات: القائمة المسموح بها لأسماء الفئات إذا لم تكن فارغة، ستتم فلترة نتائج التصنيف التي لا تندرج فئتها ضمن هذه المجموعة. يكون هذا الخيار متناقضًا مع قائمة المواقع الإلكترونية المرفوضة.
  • قائمة حظر الفئات: قائمة حظر أسماء الفئات إذا لم تكن فارغة، ستتم فلترة نتائج التصنيف التي تكون فئتها في هذه المجموعة. هذه القائمة متعارضة مع القائمة المسموح بها.
    • لغة عرض الأسماء: any string
    • الحد الأقصى للنتائج: any integer
    • الحدّ الأدنى للنتيجة: 0.0-1.0
    • قائمة الفئات المسموح بها: vector of strings
    • قائمة حظر الفئات: vector of strings
    • لغة عرض الأسماء: "en"
    • الحد الأقصى للنتائج: -1
    • الحدّ الأدنى للنتيجة: 0
    • القائمة المسموح بها للفئات: فارغة
    • قائمة حظر الفئات: فارغة
    custom_gestures_classifier_options خيارات ضبط سلوك مصنِّف الإيماءات المخصّصة
  • لغة الأسماء المعروضة: اللغة المستخدَمة للأسماء المعروضة المحدّدة من خلال البيانات الوصفية لنموذج TFLite، إن توفّرت.
  • الحد الأقصى للنتائج: الحد الأقصى لعدد نتائج التصنيف الأعلى تقييمًا المطلوب عرضها. إذا كان الرقم أقل من 0، سيتم عرض جميع النتائج المتاحة.
  • الحدّ الأدنى للنتيجة: النتيجة التي رُفضت النتائج التي تكون في حال انخفاضها. في حال ضبطه على 0، سيتم عرض جميع النتائج المتاحة.
  • القائمة المسموح بها للفئات: القائمة المسموح بها لأسماء الفئات إذا لم تكن فارغة، ستتم فلترة نتائج التصنيف التي لا تندرج فئتها ضمن هذه المجموعة. يكون هذا الخيار متناقضًا مع قائمة المواقع الإلكترونية المرفوضة.
  • قائمة حظر الفئات: قائمة حظر أسماء الفئات إذا لم تكن فارغة، ستتم فلترة نتائج التصنيف التي تكون فئتها في هذه المجموعة. هذه القائمة متعارضة مع القائمة المسموح بها.
    • لغة عرض الأسماء: any string
    • الحد الأقصى للنتائج: any integer
    • الحدّ الأدنى للنتيجة: 0.0-1.0
    • قائمة الفئات المسموح بها: vector of strings
    • قائمة حظر الفئات: vector of strings
    • لغة عرض الأسماء: "en"
    • الحد الأقصى للنتائج: -1
    • الحدّ الأدنى للنتيجة: 0
    • القائمة المسموح بها للفئات: فارغة
    • قائمة حظر الفئات: فارغة
    result_listener ضبط مستمع النتائج لتلقّي نتائج التصنيف بشكل غير متزامن عندما يكون معرّف الإيماءات في وضع البث المباشر لا يمكن استخدامها إلا عند ضبط وضع التشغيل على LIVE_STREAM ResultListener لا ينطبق لا ينطبق

    عند ضبط وضع التشغيل على "البث المباشر"، يتطلب "معرّف الإيماءات" استخدام خيار الضبط gestureRecognizerLiveStreamDelegate الإضافي، والذي بدوره يمكّن "معرّف الإيماءات" من تقديم نتائج التعرّف على الإيماءات بشكل غير متزامن. على المفوَّض تنفيذ الطريقة gestureRecognizer(_:didFinishRecognition:timestampInMilliseconds:error:) التي تستدعيها ميزة "التعرّف على الإيماءة" بعد معالجة نتائج إجراء التعرّف على الإيماءة على كل إطار.

    اسم الخيار الوصف نطاق القيمة القيمة التلقائية
    gestureRecognizerLiveStreamDelegate يتيح هذا الخيار لميزة "التعرّف على الإيماءات" تلقّي نتائج التعرّف على الإيماءات بشكل غير متزامن في وضع البث المباشر. يجب أن تنفّذ الفئة التي تم ضبط مثيلها على هذه السمة الأسلوب gestureRecognizer(_:didFinishRecognition:timestampInMilliseconds:error:) . لا تنطبق لم يتم ضبط الوضع

    تجهيز البيانات

    يجب تحويل الصورة أو الإطار المُدخلَين إلى عنصر MPImage قبل إرسالهما إلى "معرّف الإيماءات". يتيح MPImage أنواعًا مختلفة من تنسيقات الصور في نظام التشغيل iOS، ويمكنه استخدامها في أي وضع تشغيل للاستنتاج. لمزيد من المعلومات عن MPImage، يُرجى الرجوع إلى MPImage API.

    اختَر تنسيق صورة iOS استنادًا إلى حالة الاستخدام ووضع التشغيل الذي يتطلبه تطبيقك. يقبلMPImage تنسيقات صور iOS UIImage وCVPixelBuffer و CMSampleBuffer.

    UIImage

    التنسيق UIImage مناسب تمامًا لأوضاع التشغيل التالية:

    • الصور: يمكن تحويل الصور من حِزمة تطبيق أو معرض مستخدم أو نظام ملفات بتنسيق UIImage إلى كائن MPImage.

    • الفيديوهات: استخدِم AVAssetImageGenerator لاستخراج لقطات الفيديو بتنسيق CGImage ، ثم حوِّلها إلى صور UIImage.

    Swift

    // Load an image on the user's device as an iOS `UIImage` object.
    
    // Convert the `UIImage` object to a MediaPipe's Image object having the default
    // orientation `UIImage.Orientation.up`.
    let image = try MPImage(uiImage: image)
        

    Objective-C

    // Load an image on the user's device as an iOS `UIImage` object.
    
    // Convert the `UIImage` object to a MediaPipe's Image object having the default
    // orientation `UIImageOrientationUp`.
    MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
        

    يُنشئ المثال MPImage بالاتجاه التلقائي UIImage.Orientation.Up . يمكنك إعداد MPImage باستخدام أي من قيم UIImage.Orientation المسموح بها. لا تتوافق ميزة "التعرّف على الإيماءات" مع الاتجاهات المقلّدة مثل .upMirrored و.downMirrored و.leftMirrored و.rightMirrored.

    لمزيد من المعلومات حول UIImage، يمكنك الرجوع إلى وثائق مطوّري برامج UIImage من Apple.

    CVPixelBuffer

    تنسيق CVPixelBuffer مناسب تمامًا للتطبيقات التي تُنشئ إطارات وتستخدِم إطار عمل CoreImage في iOS للمعالجة.

    التنسيق CVPixelBuffer مناسب تمامًا لأوضاع التشغيل التالية:

    • الصور: يمكن إرسال التطبيقات التي تنشئ صورًا بتنسيق CVPixelBuffer بعد إجراء بعض المعالجة باستخدام إطار عمل CoreImage في نظام التشغيل iOS إلى "أداة التعرّف على الإيماءات" في وضع تشغيل الصور.

    • الفيديوهات: يمكن تحويل إطارات الفيديو إلى تنسيق CVPixelBuffer لمعالجتها، ثم إرسالها إلى "أداة التعرّف على الإيماءات" في وضع الفيديو.

    • البث المباشر: إنّ التطبيقات التي تستخدم كاميرا iOS لإنشاء الإطارات قد يتم تحويلها إلى تنسيق CVPixelBuffer لمعالجتها قبل إرسالها إلى "أداة التعرّف على الإيماءة" في وضع البث المباشر.

    Swift

    // Obtain a CVPixelBuffer.
    
    // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default
    // orientation `UIImage.Orientation.up`.
    let image = try MPImage(pixelBuffer: pixelBuffer)
        

    Objective-C

    // Obtain a CVPixelBuffer.
    
    // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the
    // default orientation `UIImageOrientationUp`.
    MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
        

    لمزيد من المعلومات عن CVPixelBuffer، يُرجى الرجوع إلى مستندات "مطوّرو تطبيقات Apple" المتعلقين بـ CVPixelBuffer.

    CMSampleBuffer

    يخزّن تنسيق CMSampleBuffer عيّنات وسائط من نوع وسائط موحّد، وهو مناسب لوضع تشغيل البث المباشر. يتم إرسال اللقطات المباشرة من كاميرات iOS بشكل غير متزامن بتنسيق CMSampleBuffer من خلال iOS AVCaptureVideoDataOutput.

    Swift

    // Obtain a CMSampleBuffer.
    
    // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default
    // orientation `UIImage.Orientation.up`.
    let image = try MPImage(sampleBuffer: sampleBuffer)
        

    Objective-C

    // Obtain a `CMSampleBuffer`.
    
    // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the
    // default orientation `UIImageOrientationUp`.
    MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
        

    لمزيد من المعلومات حول CMSampleBuffer، يُرجى الرجوع إلى مستندات مطوّري CMSampleBuffer Apple .

    تنفيذ المهمة

    لتشغيل معرّف الإيماءات، استخدِم طريقة recognize() الخاصة بالوضع الذي تم تحديده:

    • صورة ثابتة: recognize(image:)
    • الفيديو: recognize(videoFrame:timestampInMilliseconds:)
    • بث مباشر: recognizeAsync(image:timestampInMilliseconds:)

    تعرض عيّنات الرموز البرمجية التالية أمثلة أساسية على كيفية تشغيل "معرّف الإيماءات" في أوضاع التشغيل المختلفة التالية:

    Swift

    صورة

    let result = try gestureRecognizer.recognize(image: image)
        

    فيديو

    let result = try gestureRecognizer.recognize(
      videoFrame: image,
      timestampInMilliseconds: timestamp)
        

    بث مباشر

    try gestureRecognizer.recognizeAsync(
      image: image,
      timestampInMilliseconds: timestamp)
        

    Objective-C

    صورة

      MPPGestureRecognizerResult *result =
        [gestureRecognizer recognizeImage:mppImage
                                    error:nil];
        

    فيديو

    MPPGestureRecognizerResult *result =
      [gestureRecognizer recognizeVideoFrame:image
                     timestampInMilliseconds:timestamp
                                       error:nil];
        

    بث مباشر

    BOOL success =
      [gestureRecognizer recognizeAsyncImage:image
                     timestampInMilliseconds:timestamp
                                       error:nil];
        

    يسمح رمز المثال للمستخدم بالتبديل بين أوضاع المعالجة التي قد لا تكون مطلوبة في حالة الاستخدام.

    يُرجى ملاحظة ما يلي:

    • عند تشغيل وضع الفيديو في وضع الفيديو أو وضع البث المباشر، يجب أيضًا توفير الطابع الزمني لإطار الإدخال لمهمة "أداة التعرّف على الإيماءة".

    • عند التشغيل في وضع الصورة أو الفيديو، تحظر مهمة "معرّف الإيماءات" السلسلة المتزامنة الحالية إلى أن تنتهي من معالجة الصورة أو الإطار المُدخل. لتجنُّب حظر سلسلة المحادثات الحالية، نفِّذ المعالجة في سلسلة محادثات خلفية باستخدام إطارَي عمل iOS Dispatch أو NSOperation.

    • عند التشغيل في وضع البث المباشر، تعود مهمة "أداة التعرّف على الإيماءات" على الفور ولا تحظر سلسلة المحادثات الحالية. ويُستخدَم الإجراء gestureRecognizer(_:didFinishRecognition:timestampInMilliseconds:error:) مع نتيجة التعرّف على الإيماءات بعد معالجة كل ملف إطار إدخال. تستدعي ميزة "التعرّف على الإيماءة" هذه الطريقة بشكل غير متزامن على قائمة انتظار إرسال تسلسلية مخصّصة. لعرض النتائج على واجهة المستخدم، أرسِل النتائج إلى "قائمة الانتظار الرئيسية" بعد معالجتها. إذا تم استدعاء الدالة recognizeAsync عندما تكون مهمة "معرّف الإيماءات" مشغولة في معالجة إطار آخر، يتجاهل "معرّف الإيماءات" إطار الإدخال الجديد.

    معالجة النتائج وعرضها

    عند تشغيل الاستنتاج، تعرض مهمة "أداة التعرّف على الإيماءة" GestureRecognizerResult الذي يتضمّن معالم اليد في إحداثيات الصورة، ومعالم اليد في الإحداثيات العالمية، وفئات الإيماءات(اليد اليسرى أو اليمنى) والإيماءات التي يتم رصدها لليد.

    في ما يلي مثال على بيانات الإخراج من هذه المهمة:

    يحتوي GestureRecognizerResult الناتج على أربعة مكوّنات، وكل مكوّن هو صفيف، حيث يحتوي كل عنصر على النتيجة التي تم رصدها ليد واحدة تم رصدها.

    • استخدام إحدى اليدين

      يشير مقياس اليد المفضّلة إلى ما إذا كانت الأيدي التي تم رصدها هي اليد اليمنى أو اليسرى.

    • الإيماءات

      فئات الإيماءات التي يتم التعرّف عليها للأيدي المرصودة.

    • المعالم

      هناك 21 معلمًا يخصّ اليد، يتكون كلّ منها من إحداثيات x وy وz. يتم توحيد إحداثيات x وy لتكون [0.0, 1.0] حسب عرض الصورة وارتفاعها على التوالي. ويمثّل الإحداثي z عمق المَعلم، مع أنّ العمق في المعصم هو المصدر. وكلما كانت القيمة أصغر، كان المَعلم أقرب إلى الكاميرا. يستخدم حجم z المقياس نفسه تقريبًا الذي يستخدمه x.

    • معالم عالمية

      يتم أيضًا عرض 21 معلمًا يدويًا بالإحداثيات العالمية. ويتألّف كل معلَم من x وy وz، ما يمثّل إحداثيات ثلاثية الأبعاد حقيقية بالمتر مع أصولها في مركز اليد الهندسي.

    GestureRecognizerResult:
      Handedness:
        Categories #0:
          index        : 0
          score        : 0.98396
          categoryName : Left
      Gestures:
        Categories #0:
          score        : 0.76893
          categoryName : Thumb_Up
      Landmarks:
        Landmark #0:
          x            : 0.638852
          y            : 0.671197
          z            : -3.41E-7
        Landmark #1:
          x            : 0.634599
          y            : 0.536441
          z            : -0.06984
        ... (21 landmarks for a hand)
      WorldLandmarks:
        Landmark #0:
          x            : 0.067485
          y            : 0.031084
          z            : 0.055223
        Landmark #1:
          x            : 0.063209
          y            : -0.00382
          z            : 0.020920
        ... (21 world landmarks for a hand)
    

    تُظهر الصور التالية تصورًا لنتج المهمة: