iOS के लिए, हैंड लैंडमार्क की पहचान करने वाली गाइड

MediaPipe के 'हाथ के लैंडमार्क' टास्क की मदद से, किसी इमेज में हाथ के लैंडमार्क का पता लगाया जा सकता है. इन निर्देशों में, iOS ऐप्लिकेशन के साथ हैंड लैंडमार्कर का इस्तेमाल करने का तरीका बताया गया है. इन निर्देशों में बताया गया कोड सैंपल, GitHub पर उपलब्ध है.

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

कोड का उदाहरण

MediaPipe Tasks का उदाहरण कोड, iOS के लिए हाथ के हिस्सों की पहचान करने वाले ऐप्लिकेशन को लागू करने का बुनियादी तरीका है. इस उदाहरण में, लगातार चल रही वीडियो स्ट्रीम में हाथ के लैंडमार्क का पता लगाने के लिए, किसी iOS डिवाइस के कैमरे का इस्तेमाल किया गया है. यह ऐप्लिकेशन, डिवाइस की गैलरी में मौजूद इमेज और वीडियो में हाथ के लैंडमार्क का पता लगा सकता है.

अपने iOS ऐप्लिकेशन को बनाने के लिए, इस ऐप्लिकेशन का इस्तेमाल एक शुरुआती पॉइंट के तौर पर किया जा सकता है. इसके अलावा, किसी मौजूदा ऐप्लिकेशन में बदलाव करते समय भी इसे इस्तेमाल किया जा सकता है. हैंड लैंडमार्कर के उदाहरण का कोड, GitHub पर होस्ट किया जाता है.

कोड डाउनलोड करें

नीचे दिए गए निर्देशों में, git कमांड-लाइन टूल का इस्तेमाल करके, उदाहरण के कोड की लोकल कॉपी बनाने का तरीका बताया गया है.

उदाहरण के तौर पर दिया गया कोड डाउनलोड करने के लिए:

  1. यहां दिए गए कमांड का इस्तेमाल करके, Git डेटा स्टोर करने की जगह को क्लोन करें:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. इसके अलावा, अपने git इंस्टेंस को स्पैर्स चेकआउट का इस्तेमाल करने के लिए कॉन्फ़िगर करें, ताकि आपके पास सिर्फ़ Hand Landmarker के उदाहरण वाले ऐप्लिकेशन की फ़ाइलें हों:

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

उदाहरण के तौर पर दिए गए कोड का लोकल वर्शन बनाने के बाद, MediaPipe टास्क लाइब्रेरी इंस्टॉल की जा सकती है. इसके बाद, Xcode का इस्तेमाल करके प्रोजेक्ट खोलें और ऐप्लिकेशन चलाएं. निर्देशों के लिए, iOS के लिए सेटअप गाइड देखें.

मुख्य कॉम्पोनेंट

नीचे दी गई फ़ाइलों में, हाथ के लैंडमार्क के उदाहरण वाले ऐप्लिकेशन के लिए ज़रूरी कोड शामिल है:

  • HandLandmarkerService.swift: हैंड लैंडमार्कर को शुरू करता है, मॉडल चुनने को हैंडल करता है और इनपुट डेटा के अनुमान को चलाता है.
  • CameraViewController.swift: यह लाइव कैमरा फ़ीड इनपुट मोड के लिए यूज़र इंटरफ़ेस (यूआई) लागू करता है और नतीजों को विज़ुअलाइज़ करता है.
  • MediaLibraryViewController.swift: इसमें स्टिल इमेज और वीडियो फ़ाइल के इनपुट मोड के लिए यूज़र इंटरफ़ेस (यूआई) लागू किया जाता है. साथ ही, नतीजों को विज़ुअलाइज़ किया जाता है.

सेटअप

इस सेक्शन में, डेवलपमेंट एनवायरमेंट और कोड प्रोजेक्ट सेट अप करने के मुख्य चरणों के बारे में बताया गया है, ताकि हाथ के लैंडमार्क का इस्तेमाल किया जा सके. MediaPipe टास्क के लिए डेवलपमेंट एनवायरमेंट को सेट अप करने की सामान्य जानकारी के साथ-साथ प्लैटफ़ॉर्म वर्शन की ज़रूरी शर्तें जानने के लिए, iOS के लिए सेटअप गाइड देखें.

डिपेंडेंसी

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

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

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

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

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

मॉडल

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

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

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

टास्क बनाएं

Hand Landmarker टास्क बनाने के लिए, उसके किसी एक इनिशलाइज़र को कॉल करें. HandLandmarker(options:) initializer, कॉन्फ़िगरेशन के विकल्पों के लिए वैल्यू स्वीकार करता है.

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

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

टास्क बनाने और अनुमान लगाने का तरीका देखने के लिए, अपने रनिंग मोड से जुड़ा टैब चुनें.

Swift

इमेज

import MediaPipeTasksVision

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

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

let handLandmarker = try HandLandmarker(options: options)
    

वीडियो

import MediaPipeTasksVision

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

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

let handLandmarker = try HandLandmarker(options: options)
    

लाइवस्ट्रीम

import MediaPipeTasksVision

// Class that conforms to the `HandLandmarkerLiveStreamDelegate` protocol and
// implements the method that the hand landmarker calls once it finishes
// performing landmarks detection in each input frame.
class HandLandmarkerResultProcessor: NSObject, HandLandmarkerLiveStreamDelegate {

  func handLandmarker(
    _ handLandmarker: HandLandmarker,
    didFinishDetection result: HandLandmarkerResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the hand landmarker result or errors here.

  }
}

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

let options = HandLandmarkerOptions()
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 `handLandmarkerLiveStreamDelegate`
// property.
let processor = HandLandmarkerResultProcessor()
options.handLandmarkerLiveStreamDelegate = processor

let handLandmarker = try HandLandmarker(options: options)
    

Objective-C

इमेज

@import MediaPipeTasksVision;

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

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

MPPHandLandmarker *handLandmarker =
  [[MPPHandLandmarker alloc] initWithOptions:options error:nil];
    

वीडियो

@import MediaPipeTasksVision;

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

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

MPPHandLandmarker *handLandmarker =
  [[MPPHandLandmarker alloc] initWithOptions:options error:nil];
    

लाइवस्ट्रीम

@import MediaPipeTasksVision;

// Class that conforms to the `MPPHandLandmarkerLiveStreamDelegate` protocol
// and implements the method that the hand landmarker calls once it finishes
// performing landmarks detection in each input frame.

@interface APPHandLandmarkerResultProcessor : NSObject 

@end

@implementation APPHandLandmarkerResultProcessor

-   (void)handLandmarker:(MPPHandLandmarker *)handLandmarker
    didFinishDetectionWithResult:(MPPHandLandmarkerResult *)handLandmarkerResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the hand landmarker result or errors here.

}

@end

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

MPPHandLandmarkerOptions *options = [[MPPHandLandmarkerOptions 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 `handLandmarkerLiveStreamDelegate`
// property.
APPHandLandmarkerResultProcessor *processor =
  [APPHandLandmarkerResultProcessor new];
options.handLandmarkerLiveStreamDelegate = processor;

MPPHandLandmarker *handLandmarker =
  [[MPPHandLandmarker alloc] initWithOptions:options error:nil];
    

कॉन्फ़िगरेशन विकल्प

इस टास्क में, iOS ऐप्लिकेशन के लिए ये कॉन्फ़िगरेशन विकल्प हैं:

विकल्प का नाम ब्यौरा मान की सीमा डिफ़ॉल्ट मान
running_mode टास्क के लिए रनिंग मोड सेट करता है. तीन मोड होते हैं:

इमेज: एक इमेज के इनपुट का मोड.

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

LIVE_STREAM: कैमरे से मिले इनपुट डेटा की लाइव स्ट्रीम के लिए मोड. इस मोड में, नतीजे असींक्रोनस तरीके से पाने के लिए, एक listener सेट अप करने के लिए, resultListener को कॉल करना होगा. इस मोड में, handLandmarkerLiveStreamDelegate को किसी ऐसी क्लास के इंस्टेंस पर सेट करना होगा जो HandLandmarkerLiveStreamDelegate को लागू करती है, ताकि हाथ के लैंडमार्क का पता लगाने के नतीजे असींक्रोनस तरीके से मिल सकें.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
numHands हाथ के लैंडमार्क डिटेक्टर की मदद से, ज़्यादा से ज़्यादा कितने हाथों की पहचान की जा सकती है. Any integer > 0 1
minHandDetectionConfidence हाथ की पहचान करने के लिए, कम से कम इतना कॉन्फ़िडेंस स्कोर होना चाहिए, ताकि उसे हथेली की पहचान करने वाले मॉडल में सफल माना जा सके. 0.0 - 1.0 0.5
minHandPresenceConfidence हैंड लैंडमार्क डिटेक्शन मॉडल में, हाथ की मौजूदगी का पता लगाने के स्कोर के लिए कम से कम कॉन्फ़िडेंस स्कोर. वीडियो मोड और लाइव स्ट्रीम मोड में, अगर हाथ के लैंडमार्क मॉडल से हाथ की मौजूदगी का कॉन्फ़िडेंस स्कोर इस थ्रेशोल्ड से कम है, तो हाथ के लैंडमार्क की पहचान करने वाला मॉडल, हथेली की पहचान करने वाले मॉडल को ट्रिगर करता है. अगर ऐसा नहीं होता है, तो लैंडमार्क का पता लगाने के लिए, हाथ को ट्रैक करने वाला एक आसान एल्गोरिदम, हाथ की जगह का पता लगाता है. 0.0 - 1.0 0.5
minTrackingConfidence हाथ की ट्रैकिंग को कामयाब माना जा सके, इसके लिए कम से कम कॉन्फ़िडेंस स्कोर. यह मौजूदा फ़्रेम और आखिरी फ़्रेम में, हाथों के बीच के बॉउंडिंग बॉक्स का IoU थ्रेशोल्ड है. अगर हाथ के लैंडमार्क की सुविधा के वीडियो मोड और स्ट्रीम मोड में ट्रैकिंग नहीं हो पाती है, तो हाथ के लैंडमार्क की सुविधा, हाथ का पता लगाने की सुविधा को ट्रिगर करती है. ऐसा न करने पर, हाथ की पहचान की सुविधा काम नहीं करती. 0.0 - 1.0 0.5
result_listener जब हाथ का लैंडमार्कर लाइव स्ट्रीम मोड में हो, तो पहचान के नतीजे पाने के लिए रिज़ल्ट लिसनर को असाइन करता है. यह सिर्फ़ तब लागू होता है, जब रनिंग मोड को LIVE_STREAM पर सेट किया गया हो लागू नहीं लागू नहीं

जब रनिंग मोड को लाइव स्ट्रीम पर सेट किया जाता है, तो हैंड लैंडमार्कर के लिए handLandmarkerLiveStreamDelegate कॉन्फ़िगरेशन के अतिरिक्त विकल्प की ज़रूरत होती है. इससे हैंड लैंडमार्कर, हाथ के लैंडमार्क का पता लगाने के नतीजे, अलग-अलग समय पर डिलीवर कर पाता है. डेलिगेट को handLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) तरीका लागू करना होगा. हर फ़्रेम के लिए, हाथ के लैंडमार्क का पता लगाने के नतीजों को प्रोसेस करने के बाद, Hand Landmarker इस तरीके को कॉल करता है.

विकल्प का नाम ब्यौरा मान की सीमा डिफ़ॉल्ट मान
handLandmarkerLiveStreamDelegate इससे, लाइव स्ट्रीम मोड में, हाथ के लेंडमार्क का पता लगाने के नतीजे, एसिंक्रोनस तरीके से मिलते हैं. जिस क्लास का इंस्टेंस इस प्रॉपर्टी पर सेट है उसे handLandmarker(_:didFinishDetection: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];
    

इस उदाहरण में, डिफ़ॉल्ट UIImage.Orientation.Up ओरिएंटेशन के साथ MPImage को शुरू किया गया है. 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 कैमरे से लाइव फ़्रेम 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 के डेवलपर के दस्तावेज़ देखें.

टास्क चलाना

हैंड लैंडमार्कर को चलाने के लिए, असाइन किए गए रनिंग मोड के हिसाब से detect() तरीके का इस्तेमाल करें:

  • फ़ोटो: detect(image:)
  • वीडियो: detect(videoFrame:timestampInMilliseconds:)
  • लाइवस्ट्रीम: detectAsync(image:timestampInMilliseconds:)

Swift

इमेज

let result = try handLandmarker.detect(image: image)
    

वीडियो

let result = try handLandmarker.detect(
    videoFrame: image,
    timestampInMilliseconds: timestamp)
    

लाइवस्ट्रीम

try handLandmarker.detectAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objective-C

इमेज

MPPHandLandmarkerResult *result =
  [handLandmarker detectInImage:image error:nil];
    

वीडियो

MPPHandLandmarkerResult *result =
  [handLandmarker detectInVideoFrame:image
             timestampInMilliseconds:timestamp
                               error:nil];
    

लाइवस्ट्रीम

BOOL success =
  [handLandmarker detectAsyncInImage:image
             timestampInMilliseconds:timestamp
                               error:nil];
    

हाथ के लैंडमार्क कोड के उदाहरण में, इनमें से हर मोड को लागू करने के बारे में ज़्यादा जानकारी दी गई है. उदाहरण के तौर पर दिए गए कोड की मदद से, उपयोगकर्ता एक से दूसरे तरीके से प्रोसेसिंग मोड में स्विच कर सकता है, जो शायद आपके इस्तेमाल के उदाहरण के लिए ज़रूरी न हो.

निम्न पर ध्यान दें:

  • वीडियो मोड या लाइव स्ट्रीम मोड में चलाने पर, आपको हाथ के लैंडमार्क करने वाले टास्क के लिए, इनपुट फ़्रेम का टाइमस्टैंप भी देना होगा.

  • इमेज या वीडियो मोड में चलने पर, हाथ के लैंडमार्क का पता लगाने वाला टास्क, मौजूदा थ्रेड को तब तक ब्लॉक करता है, जब तक वह इनपुट इमेज या फ़्रेम को प्रोसेस नहीं कर लेता. मौजूदा थ्रेड को ब्लॉक करने से बचने के लिए, iOS Dispatch या NSOperation फ़्रेमवर्क का इस्तेमाल करके, बैकग्राउंड थ्रेड में प्रोसेसिंग को एक्ज़ीक्यूट करें.

  • लाइव स्ट्रीम मोड में इस्तेमाल करते समय, हैंड लैंडमार्कर टास्क तुरंत वापस आ जाता है. साथ ही, यह मौजूदा थ्रेड को ब्लॉक नहीं करता. यह हर इनपुट फ़्रेम को प्रोसेस करने के बाद, हाथ के लैंडमार्कर के नतीजे के साथ handLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) तरीके को लागू करता है. 'हैंड लैंडमार्क', खास सीरियल डिस्पैच सूची में इस तरीके को एसिंक्रोनस रूप से इस्तेमाल करता है. यूज़र इंटरफ़ेस पर नतीजे दिखाने के लिए, उन्हें प्रोसेस करने के बाद नतीजों को मुख्य सूची में भेजें. अगर हैंड लैंडमार्कर टास्क किसी दूसरे फ़्रेम को प्रोसेस करने में व्यस्त हो और detectAsync फ़ंक्शन को कॉल किया जाता है, तो हैंड लैंडमार्कर नए इनपुट फ़्रेम को अनदेखा कर देता है.

नतीजों को हैंडल करना और दिखाना

दौड़ने के अनुमान पर, हैंड लैंडमार्कर टास्क एक HandLandmarkerResult दिखाता है. इसमें इमेज के निर्देशांकों में हाथ के लैंडमार्क, दुनिया के निर्देशांकों में हाथ के लैंडमार्क, और जिन हाथों का पता लगाया गया है(बाएं/दाएं हाथ) दिखाए जाते हैं.

यहां इस टास्क के आउटपुट डेटा का उदाहरण दिया गया है:

HandLandmarkerResult आउटपुट में तीन कॉम्पोनेंट होते हैं. हर कॉम्पोनेंट एक कलेक्शन होता है. इसमें हर एलिमेंट में, पहचाने गए एक हाथ के लिए ये नतीजे होते हैं:

  • किसी खास हाथ का इस्तेमाल

    किसी हाथ के काम से पता चलता है कि जिस हाथ की पहचान की गई है वह बाएं हाथ है या दाएं.

  • लैंडमार्क

    हाथ के 21 लैंडमार्क हैं. हर लैंडमार्क में x, y, और z कोऑर्डिनेट होते हैं. x और y निर्देशांक को इमेज की चौड़ाई और ऊंचाई के हिसाब से, [0.0, 1.0] पर नॉर्मलाइज़ किया जाता है. z निर्देशांक, लैंडमार्क की गहराई दिखाता है. इसमें कलाई की गहराई को ऑरिजिन माना जाता है. वैल्यू जितनी कम होती है, लैंडमार्क कैमरे के नज़दीक होता है. z के मैग्नीट्यूड के लिए, x के स्केल का इस्तेमाल किया जाता है.

  • विश्व भू-स्थल

    21 हाथ के लैंडमार्क को भी दुनिया के निर्देशांकों में दिखाया गया है. हर लैंडमार्क, x, y, और z से बना होता है. यह मीटर में, असल दुनिया के 3D कोऑर्डिनेट दिखाता है. इसमें हाथ के ज्यामितीय केंद्र को ऑरिजिन माना जाता है.

HandLandmarkerResult:
  Handedness:
    Categories #0:
      index        : 0
      score        : 0.98396
      categoryName : Left
  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)

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