iOS के लिए जेस्चर पहचानने की गाइड

MediaPipe जेस्चर रेकग्निज़र टास्क की मदद से, रीयल टाइम में हाथ के जेस्चर की पहचान की जा सकती है. साथ ही, इससे हाथ के जेस्चर की पहचान के नतीजे और हाथ के पहचाने गए हिस्सों की जानकारी मिलती है. ये निर्देश आपको iOS ऐप्लिकेशन के साथ जेस्चर पहचानकर्ता को इस्तेमाल करने का तरीका दिखाते हैं.

वेब डिमो देखकर, इस टास्क को काम करते हुए देखा जा सकता है. इस टास्क की सुविधाओं, मॉडल, और कॉन्फ़िगरेशन के विकल्पों के बारे में ज़्यादा जानने के लिए, खास जानकारी देखें.

कोड का उदाहरण

MediaPipe Tasks उदाहरण कोड, 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 Tasks का इस्तेमाल करने के लिए, डेवलपमेंट एनवायरमेंट सेट अप करने के बारे में सामान्य जानकारी पाने के लिए, iOS के लिए सेटअप गाइड देखें. इसमें, प्लैटफ़ॉर्म के वर्शन से जुड़ी ज़रूरी शर्तें भी शामिल हैं.

डिपेंडेंसी

जेस्चर रिकॉगनाइज़र, MediaPipeTasksVision लाइब्रेरी का इस्तेमाल करता है. इसे CocoaPods का इस्तेमाल करके इंस्टॉल करना ज़रूरी है. यह लाइब्रेरी Swift और Objective-C, दोनों ऐप्लिकेशन के साथ काम करती है. इसके लिए, अलग से किसी खास भाषा के सेटअप की ज़रूरत नहीं होती.

macOS पर CocoaPods इंस्टॉल करने के निर्देशों के लिए, CocoaPods को इंस्टॉल करने की गाइड देखें. अपने ऐप्लिकेशन के लिए ज़रूरी पॉड के साथ Podfile बनाने का तरीका जानने के लिए, CocoaPods का इस्तेमाल करना देखें.

नीचे दिए गए कोड का इस्तेमाल करके, Podfile में MediaPipeTasksVision पॉड जोड़ें:

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

अगर आपके ऐप्लिकेशन में यूनिट टेस्ट टारगेट शामिल हैं, तो Podfile को सेट अप करने के बारे में ज़्यादा जानकारी के लिए, iOS के लिए सेट अप करने की गाइड देखें.

मॉडल

MediaPipe जेस्चर पहचानने वाले टास्क के लिए, ऐसा मॉडल ज़रूरी है जिसे इस टास्क के लिए ट्रेन किया गया हो. जेस्चर पहचानने वाले टूल के लिए, पहले से ट्रेन किए गए मॉडल के बारे में ज़्यादा जानने के लिए, टास्क की खास जानकारी वाला मॉडल सेक्शन देखें.

कोई मॉडल चुनें और डाउनलोड करें. इसके बाद, Xcode का इस्तेमाल करके उसे अपनी प्रोजेक्ट डायरेक्ट्री में जोड़ें. Xcode प्रोजेक्ट में फ़ाइलें जोड़ने का तरीका जानने के लिए, अपने Xcode प्रोजेक्ट में फ़ाइलों और फ़ोल्डर को मैनेज करना लेख पढ़ें.

अपने ऐप्लिकेशन बंडल में मॉडल का पाथ बताने के लिए, BaseOptions.modelAssetPath प्रॉपर्टी का इस्तेमाल करें. कोड का उदाहरण देखने के लिए, अगला सेक्शन देखें.

टास्क बनाना

जेस्चर पहचानने वाले टूल का कोई एक इनिशलाइज़र कॉल करके, जेस्चर पहचानने वाला टास्क बनाया जा सकता है. GestureRecognizer(options:) शुरू करने वाला, कॉन्फ़िगरेशन विकल्पों के लिए वैल्यू स्वीकार करता है.

अगर आपको कस्टमाइज़ किए गए कॉन्फ़िगरेशन के विकल्पों के साथ शुरू किए गए जेस्चर रेकग्निज़र की ज़रूरत नहीं है, तो डिफ़ॉल्ट विकल्पों के साथ जेस्चर रेकग्निज़र बनाने के लिए, GestureRecognizer(modelPath:) initializer का इस्तेमाल किया जा सकता है. कॉन्फ़िगरेशन के विकल्पों के बारे में ज़्यादा जानने के लिए, कॉन्फ़िगरेशन की खास जानकारी देखें.

जेस्चर पहचानने वाले टैस्क में, इनपुट डेटा के तीन टाइप इस्तेमाल किए जा सकते हैं: स्टिल इमेज, वीडियो फ़ाइलें, और लाइव वीडियो स्ट्रीम. डिफ़ॉल्ट रूप से, 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: एक इमेज इनपुट के लिए मोड.

वीडियो: किसी वीडियो के डिकोड किए गए फ़्रेम के लिए मोड.

LIVE_STREAM: कैमरे से मिले इनपुट डेटा की लाइव स्ट्रीम के लिए मोड. इस मोड में, नतीजे असींक्रोनस तरीके से पाने के लिए, एक listener सेट अप करने के लिए, resultListener को कॉल करना होगा. इस मोड में, gestureRecognizerLiveStreamDelegate को किसी ऐसी क्लास के इंस्टेंस पर सेट किया जाना चाहिए जो जेस्चर की पहचान करने की सुविधा को असींक्रोनस तरीके से लागू करता है. ऐसा करने पर, 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, UIImage, CVPixelBuffer, और CMSampleBuffer iOS इमेज फ़ॉर्मैट स्वीकार करता है.

    UIImage

    UIImage फ़ॉर्मैट, इन रनिंग मोड के लिए सबसे सही है:

    • इमेज: ऐप्लिकेशन बंडल, उपयोगकर्ता की गैलरी या फ़ाइल सिस्टम में मौजूद इमेज को MPImage ऑब्जेक्ट में बदला जा सकता है. हालांकि, इसके लिए ज़रूरी है कि इमेज को UIImage फ़ॉर्मैट में फ़ॉर्मैट किया गया हो.

    • वीडियो: वीडियो फ़्रेम को CGImage फ़ॉर्मैट में निकालने के लिए, AVAssetImageGenerator का इस्तेमाल करें. इसके बाद, उन्हें 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 Developer के दस्तावेज़ देखें.

    CVPixelBuffer

    CVPixelBuffer फ़ॉर्मैट, फ़्रेम जनरेट करने और प्रोसेसिंग के लिए iOS CoreImage फ़्रेमवर्क का इस्तेमाल करने वाले ऐप्लिकेशन के लिए सही है.

    CVPixelBuffer फ़ॉर्मैट, इन रनिंग मोड के लिए सबसे सही है:

    • इमेज: iOS के CoreImage फ़्रेमवर्क का इस्तेमाल करके, कुछ प्रोसेसिंग के बाद CVPixelBuffer इमेज जनरेट करने वाले ऐप्लिकेशन, इमेज रनिंग मोड में जेस्चर रिकॉगनाइज़र को भेजे जा सकते हैं.

    • वीडियो: वीडियो फ़्रेम प्रोसेस करने के लिए, उन्हें 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 Developer दस्तावेज़ देखें.

    CMSampleBuffer

    CMSampleBuffer फ़ॉर्मैट, एक जैसे मीडिया टाइप के मीडिया सैंपल को सेव करता है. साथ ही, यह लाइव स्ट्रीम के रनिंग मोड के लिए सबसे सही है. iOS कैमरों से मिले लाइव फ़्रेम, iOS AVCaptureVideoDataOutput की मदद से, CMSampleBuffer फ़ॉर्मैट में अलग-अलग डिलीवर किए जाते हैं.

    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 से बना होता है. यह मीटर में, असल दुनिया के 3D कोऑर्डिनेट दिखाता है. इसमें हाथ के ज्यामितीय केंद्र को ऑरिजिन माना जाता है.

    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)
    

    नीचे दी गई इमेज में, टास्क के आउटपुट को विज़ुअलाइज़ किया गया है: