MediaPipe Gestures पहचानकर्ता टास्क की मदद से आपको रीयल टाइम में हाथ के जेस्चर पहचानने में मदद मिलती है. साथ ही, इनसे पहचाने गए हाथों के 'हाथ के जेस्चर (हाव-भाव)' के नतीजे और 'हाथ के लैंडमार्क' भी मिलते हैं. ये निर्देश आपको बताते हैं कि Android ऐप्लिकेशन के साथ जेस्चर आइडेंटिफ़ायर का इस्तेमाल कैसे किया जाता है. इन निर्देशों में बताया गया कोड सैंपल, GitHub पर उपलब्ध है.
वेब डेमो पर जाकर, इस टास्क को देखा जा सकता है. इस टास्क की क्षमताओं, मॉडल, और कॉन्फ़िगरेशन विकल्पों के बारे में ज़्यादा जानकारी के लिए, खास जानकारी देखें.
कोड का उदाहरण
MediaPipe Tasks का उदाहरण कोड, Android के लिए जेस्चर आइडेंटिफ़ायर ऐप्लिकेशन को आसानी से लागू करने का एक आसान तरीका है. इस उदाहरण में हाथ के जेस्चर का लगातार पता लगाने के लिए, फ़िज़िकल Android डिवाइस के कैमरे का इस्तेमाल किया गया है. साथ ही, हाथ के जेस्चर का स्थिर रूप से पता लगाने के लिए, डिवाइस की गैलरी से इमेज और वीडियो का भी इस्तेमाल किया जा सकता है.
अपने Android ऐप्लिकेशन के लिए, शुरुआत करने की जगह के तौर पर इस ऐप्लिकेशन का इस्तेमाल किया जा सकता है या किसी मौजूदा ऐप्लिकेशन में बदलाव करते समय इसे देखा जा सकता है. जेस्चर आइडेंटिफ़ायर का उदाहरण कोड GitHub पर होस्ट किया जाता है.
कोड डाउनलोड करें
नीचे दिए गए निर्देशों में 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/android
उदाहरण कोड का स्थानीय वर्शन बनाने के बाद, प्रोजेक्ट को Android Studio में इंपोर्ट किया जा सकता है. इसके बाद, ऐप्लिकेशन को चलाया जा सकता है. निर्देशों के लिए, Android के लिए सेटअप गाइड देखें.
मुख्य कॉम्पोनेंट
इन फ़ाइलों में, हाथ के जेस्चर (हाव-भाव) की पहचान करने वाले इस ऐप्लिकेशन के लिए, ज़रूरी कोड मौजूद है:
- GestureRecognizerHelper.kt - यह जेस्चर पहचानने वाले टूल को शुरू करता है. साथ ही, मॉडल और प्रतिनिधि को चुनने की प्रोसेस को भी हैंडल करता है.
- MainActivity.kt -
ऐप्लिकेशन को लागू करता है. इसमें
GestureRecognizerHelper
औरGestureRecognizerResultsAdapter
को कॉल करना भी शामिल है. - GestureRecognizerResultsAdapter.kt - नतीजों को हैंडल और फ़ॉर्मैट करता है.
सेटअप
इस सेक्शन में अपने डेवलपमेंट एनवायरमेंट को सेट अप करने के मुख्य चरणों के बारे में बताया गया है. साथ ही, यह भी बताया गया है कि खास तौर पर 'जेस्चर आइडेंटिफ़ायर' का इस्तेमाल करने के लिए, कोड प्रोजेक्ट कैसे सेट अप करें. MediaPipe Tasks का इस्तेमाल करने और प्लैटफ़ॉर्म के वर्शन की ज़रूरी शर्तों के साथ-साथ अपना डेवलपमेंट एनवायरमेंट सेट अप करने से जुड़ी सामान्य जानकारी के लिए, Android के लिए सेटअप गाइड देखें.
डिपेंडेंसी
जेस्चर आइडेंटिफ़ायर टास्क com.google.mediapipe:tasks-vision
लाइब्रेरी का इस्तेमाल करता है. अपने Android ऐप्लिकेशन की build.gradle
फ़ाइल में यह डिपेंडेंसी जोड़ें:
dependencies {
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
मॉडल
MediaPipe Gestures पहचानकर्ता टास्क के लिए एक ऐसा प्रशिक्षित मॉडल बंडल होना ज़रूरी है जो इस टास्क के साथ काम कर सके. जेस्चर आइडेंटिफ़ायर के लिए उपलब्ध प्रशिक्षित मॉडल के बारे में ज़्यादा जानकारी के लिए, टास्क की खास जानकारी वाला मॉडल सेक्शन देखें.
मॉडल चुनें और डाउनलोड करें और इसे अपनी प्रोजेक्ट डायरेक्ट्री में स्टोर करें:
<dev-project-root>/src/main/assets
ModelAssetPath
पैरामीटर में मॉडल का पाथ बताएं. उदाहरण कोड में, मॉडल की जानकारी GestureRecognizerHelper.kt
फ़ाइल में दी गई है:
baseOptionBuilder.setModelAssetPath(MP_RECOGNIZER_TASK)
टास्क बनाएं
MediaPipe Gestures पहचानकर्ता टास्क, टास्क सेट अप करने के लिए createFromOptions()
फ़ंक्शन का इस्तेमाल करता है. createFromOptions()
फ़ंक्शन, कॉन्फ़िगरेशन के विकल्पों की वैल्यू स्वीकार करता है. कॉन्फ़िगरेशन के विकल्पों के बारे में ज़्यादा जानकारी के लिए,
कॉन्फ़िगरेशन के विकल्प देखें.
जेस्चर आइडेंटिफ़ायर तीन तरह के इनपुट डेटा के साथ काम करता है: स्टिल इमेज, वीडियो फ़ाइलें, और लाइव वीडियो स्ट्रीम. टास्क बनाते समय, आपको अपने इनपुट डेटा टाइप के हिसाब से 'रनिंग मोड' तय करना होगा. अपने इनपुट डेटा टाइप के हिसाब से टैब चुनें, ताकि आपको टास्क बनाने और अनुमान लगाने का तरीका पता चल सके.
Image
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_RECOGNIZER_TASK) val baseOptions = baseOptionBuilder.build() val optionsBuilder = GestureRecognizer.GestureRecognizerOptions.builder() .setBaseOptions(baseOptions) .setMinHandDetectionConfidence(minHandDetectionConfidence) .setMinTrackingConfidence(minHandTrackingConfidence) .setMinHandPresenceConfidence(minHandPresenceConfidence) .setRunningMode(RunningMode.IMAGE) val options = optionsBuilder.build() gestureRecognizer = GestureRecognizer.createFromOptions(context, options)
वीडियो
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_RECOGNIZER_TASK) val baseOptions = baseOptionBuilder.build() val optionsBuilder = GestureRecognizer.GestureRecognizerOptions.builder() .setBaseOptions(baseOptions) .setMinHandDetectionConfidence(minHandDetectionConfidence) .setMinTrackingConfidence(minHandTrackingConfidence) .setMinHandPresenceConfidence(minHandPresenceConfidence) .setRunningMode(RunningMode.VIDEO) val options = optionsBuilder.build() gestureRecognizer = GestureRecognizer.createFromOptions(context, options)
लाइव स्ट्रीम
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_RECOGNIZER_TASK) val baseOptions = baseOptionBuilder.build() val optionsBuilder = GestureRecognizer.GestureRecognizerOptions.builder() .setBaseOptions(baseOptions) .setMinHandDetectionConfidence(minHandDetectionConfidence) .setMinTrackingConfidence(minHandTrackingConfidence) .setMinHandPresenceConfidence(minHandPresenceConfidence) .setResultListener(this::returnLivestreamResult) .setErrorListener(this::returnLivestreamError) .setRunningMode(RunningMode.LIVE_STREAM) val options = optionsBuilder.build() gestureRecognizer = GestureRecognizer.createFromOptions(context, options)
जेस्चर आइडेंटिफ़ायर उदाहरण कोड लागू करने से, उपयोगकर्ता एक से दूसरे प्रोसेस मोड पर स्विच कर सकता है. यह तरीका टास्क बनाने वाले कोड को ज़्यादा जटिल बना देता है.
ऐसा भी हो सकता है कि वह आपके इस्तेमाल के उदाहरण के लिए सही न हो. आपके पास इस कोड को GestureRecognizerHelper.kt
फ़ाइल में मौजूद setupGestureRecognizer()
फ़ंक्शन में देखने का विकल्प है.
कॉन्फ़िगरेशन विकल्प
इस टास्क में, Android ऐप्लिकेशन के कॉन्फ़िगरेशन के ये विकल्प मौजूद हैं:
विकल्प का नाम | ब्यौरा | वैल्यू रेंज | डिफ़ॉल्ट मान | |
---|---|---|---|---|
runningMode |
टास्क के लिए, रनिंग मोड सेट करता है. इसके तीन मोड होते हैं: इमेज: सिंगल इमेज इनपुट के लिए मोड. वीडियो: वीडियो के डिकोड किए गए फ़्रेम का मोड. LIVE_STREAM: इनपुट डेटा की लाइव स्ट्रीम का मोड, जैसे कि कैमरे से स्ट्रीम किया जाने वाला मोड. इस मोड में, रिज़ल्ट पहचानकर्ता को लिसनर को सेट अप करने के लिए कॉल किया जाना चाहिए, ताकि वह एसिंक्रोनस तरीके से नतीजे पा सके. |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
|
numHands |
GestureRecognizer , यह पता लगाता है कि
आपने ज़्यादा से ज़्यादा कितने हाथ इस्तेमाल किए हैं.
|
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 |
|
cannedGesturesClassifierOptions |
पहले से तैयार जेस्चर क्लासिफ़ायर व्यवहार को कॉन्फ़िगर करने के विकल्प. पहले से तैयार किए गए जेस्चर ["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"] हैं |
|
|
|
customGesturesClassifierOptions |
हाथ के जेस्चर की कैटगरी तय करने वाले कस्टम तरीके को कॉन्फ़िगर करने के विकल्प. |
|
|
|
resultListener |
जब जेस्चर आइडेंटिफ़ायर लाइव स्ट्रीम मोड में होता है, तब नतीजे लिसनर को क्लासिफ़िकेशन के नतीजों को एसिंक्रोनस तरीके से पाने के लिए सेट करता है.
सिर्फ़ तब इस्तेमाल किया जा सकता है, जब रनिंग मोड LIVE_STREAM पर सेट हो |
ResultListener |
लागू नहीं | लागू नहीं |
errorListener |
गड़बड़ी की जानकारी देने वाला वैकल्पिक लिसनर सेट करता है. | ErrorListener |
लागू नहीं | लागू नहीं |
डेटा तैयार करना
जेस्चर आइडेंटिफ़ायर, इमेज, वीडियो फ़ाइल, और लाइव स्ट्रीम वीडियो के साथ काम करता है. यह टास्क, डेटा इनपुट की प्री-प्रोसेसिंग को हैंडल करता है. इसमें साइज़ बदलना, घुमाना, और वैल्यू को सामान्य बनाना भी शामिल है.
इस कोड में बताया गया है कि डेटा को प्रोसेसिंग के लिए कैसे दें. यहां दिए गए सैंपल में, इमेज, वीडियो फ़ाइलों, और लाइव वीडियो स्ट्रीम के डेटा को मैनेज करने के तरीके के बारे में जानकारी शामिल है.
Image
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()
जेस्चर आइडेंटिफ़ायर के उदाहरण कोड में, डेटा तैयार करने का काम GestureRecognizerHelper.kt
फ़ाइल में किया जाता है.
टास्क चलाएं
जेस्चर आइडेंटिफ़ायर, अनुमान ट्रिगर करने के लिए recognize
, recognizeForVideo
, और recognizeAsync
फ़ंक्शन का इस्तेमाल करता है. हाथ के जेस्चर (हाव-भाव) की पहचान करने के लिए, इसमें इनपुट डेटा को पहले से प्रोसेस करना, इमेज में हाथों का पता लगाना, हाथ के लैंडमार्क का पता लगाना, और लैंडमार्क से हाथ के जेस्चर की पहचान करना शामिल है.
इस कोड में बताया गया है कि टास्क मॉडल के साथ प्रोसेसिंग को कैसे एक्ज़ीक्यूट करें. इन सैंपल में, इमेज, वीडियो फ़ाइलों, और लाइव वीडियो स्ट्रीम के डेटा को मैनेज करने के तरीके की जानकारी शामिल होती है.
Image
val result = gestureRecognizer?.recognize(mpImage)
वीडियो
val timestampMs = i * inferenceIntervalMs gestureRecognizer?.recognizeForVideo(mpImage, timestampMs) ?.let { recognizerResult -> resultList.add(recognizerResult) }
लाइव स्ट्रीम
val mpImage = BitmapImageBuilder(rotatedBitmap).build() val frameTime = SystemClock.uptimeMillis() gestureRecognizer?.recognizeAsync(mpImage, frameTime)
निम्न पर ध्यान दें:
- वीडियो मोड या लाइव स्ट्रीम मोड में चलाते समय, आपको जेस्चर आइडेंटिफ़ायर टास्क को इनपुट फ़्रेम का टाइमस्टैंप भी देना होगा.
- इमेज या वीडियो मोड में चलाते समय, जेस्चर आइडेंटिफ़ायर टास्क मौजूदा थ्रेड को तब तक ब्लॉक रखेगा, जब तक कि वह इनपुट इमेज या फ़्रेम की प्रोसेसिंग पूरी नहीं कर लेता. यूज़र इंटरफ़ेस को ब्लॉक होने से बचाने के लिए, प्रोसेसिंग को बैकग्राउंड थ्रेड में चलाएं.
- लाइव स्ट्रीम मोड में चलाते समय, जेस्चर आइडेंटिफ़ायर टास्क मौजूदा थ्रेड को ब्लॉक नहीं करता, लेकिन तुरंत वापस आ जाता है. हर बार इनपुट फ़्रेम की प्रोसेसिंग पूरी होने पर, यह पहचान के नतीजे के साथ अपने रिज़ल्ट लिसनर को शुरू करेगा. अगर 'जेस्चर आइडेंटिफ़ायर' का काम किसी दूसरे फ़्रेम को प्रोसेस करने में व्यस्त होने पर पहचान फ़ंक्शन कॉल किया जाता है, तो वह टास्क नए इनपुट फ़्रेम को अनदेखा कर देगा.
जेस्चर आइडेंटिफ़ायर के उदाहरण कोड में, recognize
, recognizeForVideo
, और recognizeAsync
फ़ंक्शन के बारे में GestureRecognizerHelper.kt
फ़ाइल में बताया गया है.
नतीजे मैनेज करें और दिखाएं
जेस्चर आइडेंटिफ़ायर हर एक रन के लिए, जेस्चर की पहचान करने वाला नतीजा ऑब्जेक्ट जनरेट करता है. नतीजे के ऑब्जेक्ट में, इमेज के निर्देशांकों में हैंड लैंडमार्क, दुनिया के निर्देशांकों में हाथ के लैंडमार्क, किसी एक हाथ का इस्तेमाल(बायां/दायां हाथ), और हाथों के जेस्चर की कैटगरी के बारे में पता चलता है.
इस टास्क के आउटपुट डेटा का एक उदाहरण यहां दिया गया है:
नतीजे के तौर पर मिले 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)
इन इमेज में, टास्क के आउटपुट का विज़ुअलाइज़ेशन दिखाया गया है:
जेस्चर आइडेंटिफ़ायर के उदाहरण कोड में, GestureRecognizerResultsAdapter.kt
फ़ाइल में मौजूद GestureRecognizerResultsAdapter
क्लास नतीजों को हैंडल करती है.