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

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

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

कोड का उदाहरण

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

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

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

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

उदाहरण कोड डाउनलोड करने के लिए:

  1. नीचे दिए गए कमांड का इस्तेमाल करके git रिपॉज़िटरी का क्लोन बनाएं:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. इसके अलावा, स्पार्स चेकआउट का इस्तेमाल करने के लिए अपना git इंस्टेंस कॉन्फ़िगर करें, इसलिए आपके पास सिर्फ़ Hand लैंडमार्कer के उदाहरण वाले ऐप्लिकेशन की फ़ाइलें होती हैं:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/hand_landmarker/android
    

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

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

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

  • HandLandmarkerHelper.kt - हैंड लैंडमार्क डिटेक्टर को शुरू करता है और मॉडल और डेलिगेट को हैंडल करता है चुनें.
  • MainActivity.kt - ऐप्लिकेशन लागू करता है, जिसमें HandLandmarkerHelper को कॉल करना भी शामिल है.

सेटअप

इस सेक्शन में, आपके डेवलपमेंट एनवायरमेंट को सेट अप करने और कोड प्रोजेक्ट को खास तौर पर, हैंड लैंडमार्कर का इस्तेमाल करने के लिए बनाया जाता है. इस पर सामान्य जानकारी के लिए MediaPipe के टास्क इस्तेमाल करने के लिए डेवलपमेंट एनवायरमेंट सेट अप करना. इसमें ये भी शामिल हैं प्लैटफ़ॉर्म वर्शन की ज़रूरी शर्तें पूरी करते हैं. इसके बारे में ज़्यादा जानने के लिए, Android के लिए सेटअप गाइड.

डिपेंडेंसी

हैंड लैंडमार्कर टास्क, com.google.mediapipe:tasks-vision का इस्तेमाल करता है लाइब्रेरी. इस डिपेंडेंसी को अपने Android ऐप्लिकेशन की build.gradle फ़ाइल में जोड़ें:

dependencies {
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

मॉडल

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

मॉडल चुनें और डाउनलोड करें, और इसे अपनी प्रोजेक्ट डायरेक्ट्री में सेव करें:

<dev-project-root>/src/main/assets

ModelAssetPath पैरामीटर में मॉडल का पाथ तय करें. इस उदाहरण के लिए कोड, मॉडल की जानकारी HandLandmarkerHelper.kt में दी गई है फ़ाइल:

baseOptionBuilder.setModelAssetPath(MP_HAND_LANDMARKER_TASK)

टास्क बनाएं

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

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

इमेज

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_HAND_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

वीडियो

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_HAND_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

लाइव स्ट्रीम

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_HAND_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

हैंड लैंडमार्कर के उदाहरण वाले कोड को लागू करने पर, उपयोगकर्ता अलग-अलग कोड के बीच स्विच कर सकता है प्रोसेस मोड. इस तरीके से टास्क बनाने का कोड ज़्यादा मुश्किल हो जाता है और आपके इस्तेमाल के उदाहरण के लिए सही नहीं हो सकती है. आप इस कोड को यहां देख सकते हैं: setupHandLandmarker() फ़ंक्शन HandLandmarkerHelper.kt फ़ाइल से लिए जाते हैं.

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

इस टास्क में Android ऐप्लिकेशन के लिए, नीचे दिए गए कॉन्फ़िगरेशन के विकल्प मौजूद हैं:

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

अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है इमेज: सिंगल इमेज इनपुट का मोड.
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है वीडियो: किसी वीडियो के डिकोड किए गए फ़्रेम के लिए मोड.
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है LIVE_STREAM: इनपुट की लाइवस्ट्रीम करने का मोड जैसी निजी जानकारी को किसी भी समय रिकॉर्ड कर सकते हैं. इस मोड में, resultListener होना चाहिए नतीजे पाने के लिए, लिसनर सेट अप करने के लिए कॉल किया गया एसिंक्रोनस रूप से.
{IMAGE, VIDEO, LIVE_STREAM} 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
resultListener खोज के नतीजे पाने के लिए, रिज़ल्ट लिसनर को सेट करता है जब हैंड लैंडमार्कर लाइव स्ट्रीम मोड में हो, तो यह सुविधा एसिंक्रोनस रूप से उपलब्ध होती है. यह सिर्फ़ तब लागू होगा, जब रनिंग मोड को LIVE_STREAM पर सेट किया गया हो लागू नहीं लागू नहीं
errorListener गड़बड़ी की जानकारी देने वाला वैकल्पिक लिसनर सेट करता है. लागू नहीं लागू नहीं

डेटा तैयार करें

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

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

इमेज

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(image).build()
    

वीडियो

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

val argb8888Frame =
    if (frame.config == Bitmap.Config.ARGB_8888) frame
    else frame.copy(Bitmap.Config.ARGB_8888, false)

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(argb8888Frame).build()
    

लाइव स्ट्रीम

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(rotatedBitmap).build()
    

इस हैंड लैंडमार्कर का उदाहरण कोड, डेटा तैयार करने का काम HandLandmarkerHelper.kt फ़ाइल से लिए जाते हैं.

टास्क को पूरा करें

जिस डेटा के साथ काम किया जा रहा है उसके आधार पर, HandLandmarker.detect...() तरीका इस्तेमाल किया जा सकता है. इस्तेमाल की जाने वाली चीज़ें अलग-अलग इमेज के लिए detect(), वीडियो फ़ाइलों में फ़्रेम के लिए detectForVideo(), और वीडियो स्ट्रीम के लिए detectAsync(). जब किसी डिवाइस पर गतिविधि की पहचान की जाती है वीडियो स्ट्रीम है, तो पक्का करें कि आपने डिटेक्शन को एक अलग थ्रेड पर चलाया हो, ताकि आप यूज़र इंटरफ़ेस थ्रेड को ब्लॉक करती है.

नीचे दिए गए कोड सैंपल में, हैंड लैंडमार्कर चलाने के आसान उदाहरण दिए गए हैं इन अलग-अलग डेटा मोड में:

इमेज

val result = handLandmarker?.detect(mpImage)
    

वीडियो

val timestampMs = i * inferenceIntervalMs

handLandmarker?.detectForVideo(mpImage, timestampMs)
    ?.let { detectionResult ->
        resultList.add(detectionResult)
    }
    

लाइव स्ट्रीम

val mpImage = BitmapImageBuilder(rotatedBitmap).build()
val frameTime = SystemClock.uptimeMillis()

handLandmarker?.detectAsync(mpImage, frameTime)
    

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

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

इस हैंड लैंडमार्कर के उदाहरण कोड, detect, detectForVideo, और detectAsync फ़ंक्शन इसमें परिभाषित किए गए हैं: HandLandmarkerHelper.kt फ़ाइल से लिए जाते हैं.

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

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

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

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)

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

हैंड लैंडमार्कर के उदाहरण कोड से, मैप में दिखने वाले डिसप्ले के बारे में पता चलता है टास्क के नतीजे वापस मिले हैं, तो OverlayView क्लास देखें.