Android के लिए फ़ेस लैंडमार्क की पहचान करने वाली गाइड

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

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

कोड का उदाहरण

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

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

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

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

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

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

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

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

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

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

सेटअप

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

डिपेंडेंसी

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

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

मॉडल

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

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

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

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

baseOptionsBuilder.setModelAssetPath(MP_FACE_LANDMARKER_TASK)

टास्क बनाना

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

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

इमेज

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

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setRunningMode(RunningMode.IMAGE)

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

वीडियो

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

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setRunningMode(RunningMode.VIDEO)

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

लाइव स्ट्रीम

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

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

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

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

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

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

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

IMAGE: यह मोड, एक इमेज वाले इनपुट के लिए होता है.

VIDEO: यह वीडियो के डिकोड किए गए फ़्रेम का मोड है.

LIVE_STREAM: यह इनपुट डेटा की लाइव स्ट्रीम करने का मोड है. जैसे, कैमरे से लाइव स्ट्रीम करना. इस मोड में, एसिंक्रोनस तरीके से नतीजे पाने के लिए, resultListener को कॉल करना ज़रूरी है, ताकि नतीजे पाने के लिए लिसनर सेट अप किया जा सके.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
numFaces FaceLandmarker की मदद से, ज़्यादा से ज़्यादा चेहरों का पता लगाया जा सकता है. स्मूदिंग की सुविधा सिर्फ़ तब लागू होती है, जब num_faces को 1 पर सेट किया जाता है. Integer > 0 1
minFaceDetectionConfidence चेहरे का पता लगाने की प्रोसेस को सफल मानने के लिए, कम से कम कॉन्फ़िडेंस स्कोर. Float [0.0,1.0] 0.5
minFacePresenceConfidence चेहरे की पहचान करने की सुविधा में, चेहरे की मौजूदगी के स्कोर की कम से कम निजता सीमा. Float [0.0,1.0] 0.5
minTrackingConfidence चेहरे को ट्रैक करने की सुविधा के लिए, कम से कम कॉन्फ़िडेंस स्कोर. इससे यह तय होता है कि चेहरे को ट्रैक करने की सुविधा सही तरीके से काम कर रही है या नहीं. Float [0.0,1.0] 0.5
outputFaceBlendshapes इससे पता चलता है कि फ़ेस लैंडमार्कर, फ़ेस ब्लेंडशेप आउटपुट करता है या नहीं. चेहरे के 3D मॉडल को रेंडर करने के लिए, चेहरे के ब्लेंडशेप का इस्तेमाल किया जाता है. Boolean False
outputFacialTransformationMatrixes FaceLandmarker, चेहरे के ट्रांसफ़ॉर्मेशन मैट्रिक्स को आउटपुट करता है या नहीं. FaceLandmarker, मैट्रिक्स का इस्तेमाल करके चेहरे के लैंडमार्क को कैननिकल फ़ेस मॉडल से पहचाने गए चेहरे में बदलता है. इससे उपयोगकर्ता, पहचाने गए लैंडमार्क पर इफ़ेक्ट लागू कर पाते हैं. Boolean False
resultListener यह फ़ंक्शन, नतीजे सुनने वाले को सेट करता है, ताकि जब FaceLandmarker लाइव स्ट्रीम मोड में हो, तब उसे लैंडमार्क के नतीजे एसिंक्रोनस तरीके से मिल सकें. इस सेटिंग का इस्तेमाल सिर्फ़ तब किया जा सकता है, जब रनिंग मोड को 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()
    

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

टास्क को रन करना

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

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

इमेज

val result = FaceLandmarker.detect(mpImage)
    

वीडियो

val timestampMs = i * inferenceIntervalMs

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

लाइव स्ट्रीम

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

FaceLandmarker.detectAsync(mpImage, frameTime)
    

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

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

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

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

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

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

FaceLandmarkerResult:
  face_landmarks:
    NormalizedLandmark #0:
      x: 0.5971359014511108
      y: 0.485361784696579
      z: -0.038440968841314316
    NormalizedLandmark #1:
      x: 0.3302789330482483
      y: 0.29289937019348145
      z: -0.09489090740680695
    ... (478 landmarks for each face)
  face_blendshapes:
    browDownLeft: 0.8296722769737244
    browDownRight: 0.8096957206726074
    browInnerUp: 0.00035583582939580083
    browOuterUpLeft: 0.00035752105759456754
    ... (52 blendshapes for each face)
  facial_transformation_matrixes:
    [9.99158978e-01, -1.23036895e-02, 3.91213447e-02, -3.70770246e-01]
    [1.66496094e-02,  9.93480563e-01, -1.12779640e-01, 2.27719707e+01]
    ...

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

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

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