MediaPipe जेस्चर रेकग्निज़र टास्क की मदद से, रीयल टाइम में हाथ के जेस्चर की पहचान की जा सकती है. साथ ही, इससे हाथ के जेस्चर की पहचान के नतीजे और हाथ के पहचाने गए हिस्सों की जानकारी मिलती है. ये निर्देश आपको iOS ऐप्लिकेशन के साथ जेस्चर पहचानकर्ता को इस्तेमाल करने का तरीका दिखाते हैं.
वेब डिमो देखकर, इस टास्क को काम करते हुए देखा जा सकता है. इस टास्क की सुविधाओं, मॉडल, और कॉन्फ़िगरेशन के विकल्पों के बारे में ज़्यादा जानने के लिए, खास जानकारी देखें.
कोड का उदाहरण
MediaPipe Tasks उदाहरण कोड, iOS के लिए जेस्चर आइडेंटिफ़ायर ऐप्लिकेशन का बेसिक लागू करने का तरीका है. इस उदाहरण में, हाथ के जेस्चर का लगातार पता लगाने के लिए, iOS डिवाइस के कैमरे का इस्तेमाल किया गया है. साथ ही, जेस्चर का स्टैटिक तरीके से पता लगाने के लिए, डिवाइस की गैलरी में मौजूद इमेज और वीडियो का भी इस्तेमाल किया जा सकता है.
इस ऐप्लिकेशन का इस्तेमाल, अपने iOS ऐप्लिकेशन के लिए शुरुआती बिंदु के तौर पर किया जा सकता है. इसके अलावा, किसी मौजूदा ऐप्लिकेशन में बदलाव करते समय भी इसका इस्तेमाल किया जा सकता है. जेस्चर रेकग्निज़र के उदाहरण का कोड, GitHub पर होस्ट किया गया है.
कोड डाउनलोड करना
नीचे दिए गए निर्देशों में, git कमांड-लाइन टूल का इस्तेमाल करके, उदाहरण के कोड की लोकल कॉपी बनाने का तरीका बताया गया है.
उदाहरण के तौर पर दिया गया कोड डाउनलोड करने के लिए:
नीचे दिए गए निर्देश का इस्तेमाल करके git रिपॉज़िटरी का क्लोन बनाएं:
git clone https://github.com/google-ai-edge/mediapipe-samples
इसके अलावा, अपने 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"] हैं |
|
|
|
custom_gestures_classifier_options |
कस्टम जेस्चर की कैटगरी तय करने वाले व्यवहार को कॉन्फ़िगर करने के विकल्प. |
|
|
|
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)
नीचे दी गई इमेज में, टास्क के आउटपुट को विज़ुअलाइज़ किया गया है: