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

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

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

कोड का उदाहरण

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

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

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

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

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

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

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

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

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

  • PoseLandmarkerHelper.kt - पोज़ लैंडमार्कर को शुरू करता है और मॉडल और प्रतिनिधि चुनने की प्रोसेस को मैनेज करता है.
  • CameraFragment.kt - यह डिवाइस के कैमरे को मैनेज करता है और इमेज और वीडियो इनपुट डेटा को प्रोसेस करता है.
  • GalleryFragment.kt - आउटपुट इमेज या वीडियो दिखाने के लिए, OverlayView के साथ इंटरैक्ट करता है.
  • OverlayView.kt - यह पहचाने गए पोज़ के लिए डिसप्ले लागू करता है.

सेटअप

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

डिपेंडेंसी

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

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

मॉडल

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

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

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

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

val modelName = "pose_landmarker_lite.task"
baseOptionsBuilder.setModelAssetPath(modelName)

टास्क बनाना

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

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

इमेज

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

val optionsBuilder = 
    poseLandmarker.poseLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinPoseDetectionConfidence(minPoseDetectionConfidence)
        .setMinTrackingConfidence(minPoseTrackingConfidence)
        .setMinPosePresenceConfidence(minposePresenceConfidence)
        .setNumPoses(maxNumPoses)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()
poseLandmarker = poseLandmarker.createFromOptions(context, options)
    

वीडियो

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

val optionsBuilder = 
    poseLandmarker.poseLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinPoseDetectionConfidence(minPoseDetectionConfidence)
        .setMinTrackingConfidence(minPoseTrackingConfidence)
        .setMinPosePresenceConfidence(minposePresenceConfidence)
        .setNumPoses(maxNumPoses)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()
poseLandmarker = poseLandmarker.createFromOptions(context, options)
    

लाइव स्ट्रीम

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

val optionsBuilder = 
    poseLandmarker.poseLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinPoseDetectionConfidence(minPoseDetectionConfidence)
        .setMinTrackingConfidence(minPoseTrackingConfidence)
        .setMinPosePresenceConfidence(minposePresenceConfidence)
        .setNumPoses(maxNumPoses)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()
poseLandmarker = poseLandmarker.createFromOptions(context, options)
    

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

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

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

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

IMAGE: एक इमेज इनपुट के लिए मोड.

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

LIVE_STREAM: कैमरे से मिले इनपुट डेटा की लाइव स्ट्रीम के लिए मोड. इस मोड में, नतीजे असींक्रोनस तरीके से पाने के लिए, एक listener सेट अप करने के लिए, resultListener को कॉल करना होगा.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
numposes पोज़ लैंडमार्कर की मदद से, ज़्यादा से ज़्यादा कितने पोज़ का पता लगाया जा सकता है. Integer > 0 1
minPoseDetectionConfidence पोज़ का पता लगाने के लिए, कम से कम इतना कॉन्फ़िडेंस स्कोर होना चाहिए. Float [0.0,1.0] 0.5
minPosePresenceConfidence पोज़ लैंडमार्क की पहचान करने की सुविधा में, पोज़ की मौजूदगी के कम से कम कॉन्फ़िडेंस स्कोर का मतलब है. Float [0.0,1.0] 0.5
minTrackingConfidence पोज़ ट्रैकिंग के लिए कम से कम कॉन्फ़िडेंस स्कोर, जिसे सफल माना जाता है. Float [0.0,1.0] 0.5
outputSegmentationMasks पोज़ लैंडमार्कर, पहचाने गए पोज़ के लिए सेगमेंटेशन मास्क दिखाता है या नहीं. Boolean False
resultListener जब पोज़ लैंडमार्कर लाइव स्ट्रीम मोड में हो, तब लैंडमार्कर के नतीजे पाने के लिए रिज़ल्ट लिसनर को असिंक्रोनस तरीके से सेट करता है. इसका इस्तेमाल सिर्फ़ तब किया जा सकता है, जब रनिंग मोड को LIVE_STREAM पर सेट किया गया हो ResultListener N/A
errorListener गड़बड़ी सुनने वाले को सेट करता है. हालांकि, ऐसा करना ज़रूरी नहीं है. ErrorListener N/A

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

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

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

इमेज

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()
    

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

टास्क चलाना

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

यहां दिए गए कोड सैंपल में, अलग-अलग डेटा मोड में पोज़ लैंडमार्कर को चलाने का आसान तरीका बताया गया है:

इमेज

val result = poseLandmarker.detect(mpImage)
    

वीडियो

val timestampMs = i * inferenceIntervalMs

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

लाइव स्ट्रीम

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

poseLandmarker.detectAsync(mpImage, frameTime)
    

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

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

पोज़ लैंडमार्कर के उदाहरण वाले कोड में, detect, detectForVideo, और detectAsync फ़ंक्शन को PoseLandmarkerHelper.kt फ़ाइल में तय किया गया है.

नतीजों को मैनेज और दिखाना

पोज़ लैंडमार्कर, हर बार पहचान करने के लिए poseLandmarkerResult ऑब्जेक्ट दिखाता है. नतीजे के ऑब्जेक्ट में, हर पोज़ के लैंडमार्क के लिए निर्देशांक होते हैं.

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

PoseLandmarkerResult:
  Landmarks:
    Landmark #0:
      x            : 0.638852
      y            : 0.671197
      z            : 0.129959
      visibility   : 0.9999997615814209
      presence     : 0.9999984502792358
    Landmark #1:
      x            : 0.634599
      y            : 0.536441
      z            : -0.06984
      visibility   : 0.999909
      presence     : 0.999958
    ... (33 landmarks per pose)
  WorldLandmarks:
    Landmark #0:
      x            : 0.067485
      y            : 0.031084
      z            : 0.055223
      visibility   : 0.9999997615814209
      presence     : 0.9999984502792358
    Landmark #1:
      x            : 0.063209
      y            : -0.00382
      z            : 0.020920
      visibility   : 0.999976
      presence     : 0.999998
    ... (33 world landmarks per pose)
  SegmentationMasks:
    ... (pictured below)

आउटपुट में, हर लैंडमार्क के लिए सामान्य काेऑर्डिनेट (Landmarks) और वर्ल्ड काेऑर्डिनेट (WorldLandmarks), दोनों शामिल होते हैं.

आउटपुट में, सामान्य किए गए ये निर्देशांक (Landmarks) शामिल होते हैं:

  • x और y: इमेज की चौड़ाई (x) और ऊंचाई (y) के हिसाब से, लैंडमार्क के निर्देशांक को 0.0 से 1.0 के बीच नॉर्मलाइज़ किया गया है.

  • z: लैंडमार्क की गहराई, जिसमें कूल्हों के बीच की जगह को ऑरिजिन के तौर पर लिया गया है. वैल्यू जितनी कम होगी, लैंडमार्क कैमरे के उतना ही करीब होगा. z के मैग्नीट्यूड के लिए, x के स्केल का इस्तेमाल किया जाता है.

  • visibility: इमेज में लैंडमार्क दिखने की संभावना.

आउटपुट में, दुनिया के ये निर्देशांक (WorldLandmarks) शामिल होते हैं:

  • x, y, और z: असल ज़िंदगी के 3-डाइमेंशनल निर्देशांक, मीटर में. इनमें कूल्हों के बीच के बिंदु को ऑरिजिन माना जाता है.

  • visibility: इमेज में लैंडमार्क दिखने की संभावना.

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

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

वैकल्पिक सेगमेंटेशन मास्क से पता चलता है कि हर पिक्सल, पहचाने गए व्यक्ति से जुड़ा है या नहीं. नीचे दी गई इमेज, टास्क के आउटपुट का सेगमेंटेशन मास्क है:

पिछली इमेज का सेगमेंटेशन मास्क, जिसमें महिला के आकार की जानकारी दी गई है

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