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

تتيح لك مهمة أداة التعرّف على إيماءة MediaPipe التعرّف على إيماءات اليد في الوقت الفعلي، وتوفّر نتائج إيماءات اليد المتعرّف عليها ومعالم اليد لليد التي تم التعرّف عليها. توضّح لك هذه التعليمات كيفية استخدام أداة التعرّف على الإيماءات مع تطبيقات 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:)" لإنشاء هذه الميزة باستخدام الخيارات التلقائية. لمزيد من المعلومات حول خيارات الضبط، يُرجى الاطّلاع على نظرة عامة على الإعدادات.

تتوافق مهمة "أداة التعرّف على الإيماءات" مع ثلاثة أنواع من بيانات الإدخال، وهي الصور الثابتة وملفات الفيديو وأحداث بث الفيديو المباشر. ينشئ 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: وضع إدخالات الصورة الفردية.

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

البث المباشر: وضع بث مباشر لبيانات الإدخال، مثل الكاميرا. في هذا الوضع، يجب استدعاء 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 تمثّل هذه السمة الحد الأدنى لدرجة الثقة ليتم اعتبار تتبُّع اليد ناجحًا. هذا هو الحدّ الأدنى لوحدات وحدات القياس بين الأيدي في الإطار الحالي والإطار الأخير. في وضع الفيديو ووضع البث في "أداة التعرّف على الإيماءات"، إذا تعذّر تتبُّع الإيماءات، ستعمل هذه الميزة على تفعيل ميزة رصد اليد. وبخلاف ذلك، يتم تخطي رصد اليدين. 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" تنسيقات الصور UIImage وCVPixelBuffer وCMSampleBuffer على iOS.

    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، يُرجى الاطّلاع على مستندات مطوّري برامج CVPixelBuffer Apple.

    CMSampleBuffer

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

    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، يُرجى الاطّلاع على مستندات مطوّري البرامج الخاصة بـ CMعيّنBuffer من 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];
        

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

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

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

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

    • عند تشغيل الميزة في وضع البث المباشر، تظهر مهمة "أداة التعرّف على الإيماءات" على الفور بدون حظر سلسلة المحادثات الحالية. يستدعي الطريقة 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)
    

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