मुद्रा के वर्गीकरण के विकल्प

एमएल किट पोज़ डिटेक्शन एपीआई की मदद से, शरीर के अलग-अलग हिस्सों की पोज़िशन देखकर, शरीर के अलग-अलग पोज़ को आसानी से समझा जा सकता है. इस पेज पर कुछ उदाहरण बताए गए हैं.

k-NN एल्गोरिदम की मदद से, पोज़ क्लासिफ़िकेशन और दोहराव की गिनती

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

इस सेक्शन में हमने बताया है कि हमने MediaPipe Colab का इस्तेमाल करके, कस्टम पोज़ वाली कैटगरी कैसे बनाई है. साथ ही, हमने अपने ML Kit सैंपल ऐप्लिकेशन में, काम करने वाले क्लासिफ़ायर के बारे में जानकारी दी है.

अगर आपको Google Colaboratory के बारे में कुछ नहीं पता है, तो कृपया परिचय गाइड देखें.

आस-पास की मुद्राओं की पहचान करने के लिए, हम k-सबसे पास वाले पड़ोसी एल्गोरिदम (k-NN) का इस्तेमाल करते हैं, क्योंकि यह इस्तेमाल में आसान है. एल्गोरिदम, ट्रेनिंग सेट में सबसे नज़दीकी सैंपल के आधार पर ऑब्जेक्ट की क्लास तय करता है.

आइडेंटिफ़ायर बनाने और उसे ट्रेनिंग देने के लिए, यह तरीका अपनाएं:

1. इमेज के सैंपल इकट्ठा करें

हमने अलग-अलग सोर्स से, टारगेट एक्सरसाइज़ के इमेज सैंपल इकट्ठा किए हैं. हमने हर कसरत के लिए कुछ सौ इमेज चुनी हैं, जैसे कि पुश-अप के लिए "ऊपर" और "नीचे" स्थितियां. ऐसे नमूने इकट्ठा करना ज़रूरी है जो अलग-अलग कैमरा ऐंगल, वातावरण की स्थितियों, शरीर के आकार, और कसरत के उतार-चढ़ाव को कवर करते हों.

पहली इमेज. अप और डाउन पुशअप पोज़ की पोज़िशन

2. सैंपल इमेज पर पोज़ डिटेक्शन की सुविधा चलाएं

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

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

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

3. मॉडल को ट्रेनिंग दें और दोहराव की गिनती करें

हमने क्लासिफ़ायर के लिए कोड को ऐक्सेस करने और मॉडल को ट्रेनिंग देने के लिए MediaPipe Colab का इस्तेमाल किया.

दोहरावों की गिनती करने के लिए, हमने दूसरे Colab एल्गोरिदम का इस्तेमाल किया है. उदाहरण के लिए:

  • जब "डाउन" पोज़ क्लास की संभावना पहली बार दी गई थ्रेशोल्ड से पास हो जाती है, तब एल्गोरिदम यह मार्क करता है कि "डाउन" पोज़ क्लास डाली गई है.
  • जब प्रॉबबिलिटी थ्रेशोल्ड से कम हो जाती है, तब एल्गोरिदम यह मार्क करता है कि "डाउन" पोज़ क्लास से बाहर हो गया है और यह काउंटर को बढ़ा देता है.
दूसरी इमेज. दोहराव की गिनती का उदाहरण

4. ML Kit क्विकस्टार्ट ऐप्लिकेशन के साथ इंटिग्रेट करना

ऊपर दिया गया Colab एक CSV फ़ाइल बनाता है, जिसे आपके पोज़ के सभी सैंपल के साथ अपने-आप भरा जा सकता है. इस सेक्शन में, रीयल टाइम में कस्टम पोज़ कैटगरी देखने के लिए, CSV फ़ाइल को ML Kit Android क्विकस्टार्ट ऐप्लिकेशन के साथ इंटिग्रेट करने का तरीका बताया गया है.

क्विकस्टार्ट ऐप्लिकेशन में बंडल किए गए नमूनों के साथ पोज़ क्लासिफ़िकेशन आज़माएं

  • Github से ML Kit Android क्विकस्टार्ट ऐप्लिकेशन प्रोजेक्ट पाएं और पक्का करें कि यह ठीक से काम करता है और काम करता है.
  • LivePreviewActivity पर जाएं और 'सेटिंग' पेज पर जाकर, पोज़ डिटेक्शन Run classification चालू करें. अब आपके पास पुशअप और स्क्वॉट की कैटगरी तय करने का विकल्प है.

अपनी CSV फ़ाइल जोड़ें

  • ऐप्लिकेशन के एसेट फ़ोल्डर में अपनी CSV फ़ाइल जोड़ें.
  • PoseClassifierProcessor में, POSE_SAMPLES_FILE और POSE_CLASSES वैरिएबल को अपडेट करें, ताकि वे आपकी CSV फ़ाइल और पोज़ के नमूनों से मेल खा सकें.
  • ऐप्लिकेशन बनाएं और चलाएं.

ध्यान दें कि पर्याप्त नमूने न होने पर, हो सकता है कि क्लासिफ़िकेशन सही तरीके से काम न करे. आम तौर पर, हर पोज़ क्लास के लिए आपको करीब 100 सैंपल की ज़रूरत होती है.

ज़्यादा जानने और इसे खुद आज़माने के लिए, MediaPipe Colab और MediaPipe की कैटगरी तय करने वाली गाइड देखें.

लैंडमार्क की दूरी की गणना करके आसान जेस्चर की पहचान करना

जब दो या दो से ज़्यादा लैंडमार्क एक-दूसरे के पास हों, तब उनका इस्तेमाल हाथ के जेस्चर की पहचान करने के लिए किया जा सकता है. उदाहरण के लिए, जब हाथ की एक या उससे ज़्यादा उंगलियों का लैंडमार्क, नाक के लैंडमार्क के पास होना चाहिए, तो यह अनुमान लगाया जा सकता है कि उपयोगकर्ता के चेहरे को छूने की संभावना ज़्यादा है.

तीसरी इमेज. पोज़ को समझना

योग के खास पोज़ की पहचान, ऐंगल के हिसाब से की जा रही है

अलग-अलग जोड़ों के कोणों की गणना करके, योग के एक आसन को पहचाना जा सकता है. उदाहरण के लिए, नीचे दी गई दूसरी इमेज में वॉरिअर II के योग को दिखाया गया है. इस पोज़ की पहचान करने वाले अनुमानित कोण इस तरह लिखे गए हैं:

चौथी इमेज. पोज़ को कोणों में तोड़ना

इस पोज़ को शरीर के अलग-अलग हिस्सों के अनुमानित हिस्सों के इस कॉम्बिनेशन से दिखाया जा सकता है:

  • दोनों कंधों पर 90 डिग्री का कोण
  • दोनों कोहनी पर 180 डिग्री
  • आगे वाले पैर और कमर का 90 डिग्री का कोण
  • घुटने के पिछले हिस्से का 180 डिग्री कोण
  • कमर का 135 डिग्री कोण

इन कोणों का पता लगाने के लिए, पोज़ के लैंडमार्क का इस्तेमाल करें. उदाहरण के लिए, सामने के दाहिने पैर और कमर का ऐंगल, दाएँ कंधे से दाएँ कूल्हे और दाएँ कूल्हे से दाएँ घुटने तक की लाइन के बीच का ऐंगल होता है.

पोज़ की पहचान करने के लिए सभी ज़रूरी ऐंगल का पता लगाने के बाद, देखें कि क्या कोई मिलता-जुलता है या नहीं और किस स्थिति में आपने पोज़ की पहचान कर ली है.

नीचे दिया गया कोड स्निपेट दिखाता है कि शरीर के दो हिस्सों के बीच के कोण का पता लगाने के लिए, X और Y निर्देशांकों का इस्तेमाल कैसे करें. कैटगरी तय करने के इस तरीके की कुछ सीमाएं हैं. सिर्फ़ X और Y की जांच करने से, ऑब्जेक्ट और कैमरे के कोण के हिसाब से आपके दिए गए कोण अलग-अलग होते हैं. सीधे आगे की ओर, हेड-ऑन इमेज के साथ आपको सबसे अच्छे नतीजे मिलेंगे. इस एल्गोरिदम को बढ़ाने के लिए, Z कोऑर्डिनेट का इस्तेमाल भी किया जा सकता है. साथ ही, देखें कि यह आपकी ज़रूरत के हिसाब से बेहतर परफ़ॉर्म करता है या नहीं.

Android पर लैंडमार्क के कोणों का पता लगाना

नीचे दिया गया तरीका, किसी भी तीन लैंडमार्क के बीच के कोण का पता लगाता है. यह पक्का करता है कि लौटाया गया कोण 0 से 180 डिग्री के बीच है.

Kotlin

fun getAngle(firstPoint: PoseLandmark, midPoint: PoseLandmark, lastPoint: PoseLandmark): Double {
        var result = Math.toDegrees(atan2(lastPoint.getPosition().y - midPoint.getPosition().y,
                lastPoint.getPosition().x - midPoint.getPosition().x)
                - atan2(firstPoint.getPosition().y - midPoint.getPosition().y,
                firstPoint.getPosition().x - midPoint.getPosition().x))
        result = Math.abs(result) // Angle should never be negative
        if (result > 180) {
            result = 360.0 - result // Always get the acute representation of the angle
        }
        return result
    }

Java

static double getAngle(PoseLandmark firstPoint, PoseLandmark midPoint, PoseLandmark lastPoint) {
  double result =
        Math.toDegrees(
            atan2(lastPoint.getPosition().y - midPoint.getPosition().y,
                      lastPoint.getPosition().x - midPoint.getPosition().x)
                - atan2(firstPoint.getPosition().y - midPoint.getPosition().y,
                      firstPoint.getPosition().x - midPoint.getPosition().x));
  result = Math.abs(result); // Angle should never be negative
  if (result > 180) {
      result = (360.0 - result); // Always get the acute representation of the angle
  }
  return result;
}

दाएँ कूल्हे के कोण का पता लगाने का तरीका यहां बताया गया है:

Kotlin

val rightHipAngle = getAngle(
                pose.getPoseLandmark(PoseLandmark.Type.RIGHT_SHOULDER),
                pose.getPoseLandmark(PoseLandmark.Type.RIGHT_HIP),
                pose.getPoseLandmark(PoseLandmark.Type.RIGHT_KNEE))

Java

double rightHipAngle = getAngle(
                pose.getPoseLandmark(PoseLandmark.Type.RIGHT_SHOULDER),
                pose.getPoseLandmark(PoseLandmark.Type.RIGHT_HIP),
                pose.getPoseLandmark(PoseLandmark.Type.RIGHT_KNEE));

iOS पर लैंडमार्क ऐंगल की गिनती करना

नीचे दिया गया तरीका, किसी भी तीन लैंडमार्क के बीच के कोण का पता लगाता है. यह पक्का करता है कि लौटाया गया कोण 0 से 180 डिग्री के बीच है.

Swift

func angle(
      firstLandmark: PoseLandmark,
      midLandmark: PoseLandmark,
      lastLandmark: PoseLandmark
  ) -> CGFloat {
      let radians: CGFloat =
          atan2(lastLandmark.position.y - midLandmark.position.y,
                    lastLandmark.position.x - midLandmark.position.x) -
            atan2(firstLandmark.position.y - midLandmark.position.y,
                    firstLandmark.position.x - midLandmark.position.x)
      var degrees = radians * 180.0 / .pi
      degrees = abs(degrees) // Angle should never be negative
      if degrees > 180.0 {
          degrees = 360.0 - degrees // Always get the acute representation of the angle
      }
      return degrees
  }

Objective-C

(CGFloat)angleFromFirstLandmark:(MLKPoseLandmark *)firstLandmark
                      midLandmark:(MLKPoseLandmark *)midLandmark
                     lastLandmark:(MLKPoseLandmark *)lastLandmark {
    CGFloat radians = atan2(lastLandmark.position.y - midLandmark.position.y,
                            lastLandmark.position.x - midLandmark.position.x) -
                      atan2(firstLandmark.position.y - midLandmark.position.y,
                            firstLandmark.position.x - midLandmark.position.x);
    CGFloat degrees = radians * 180.0 / M_PI;
    degrees = fabs(degrees); // Angle should never be negative
    if (degrees > 180.0) {
        degrees = 360.0 - degrees; // Always get the acute representation of the angle
    }
    return degrees;
}

दाएँ कूल्हे के कोण का पता लगाने का तरीका यहां बताया गया है:

Swift

let rightHipAngle = angle(
      firstLandmark: pose.landmark(ofType: .rightShoulder),
      midLandmark: pose.landmark(ofType: .rightHip),
      lastLandmark: pose.landmark(ofType: .rightKnee))

Objective-C

CGFloat rightHipAngle =
    [self angleFromFirstLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightShoulder]
                     midLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightHip]
                    lastLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightKnee]];