Android डिवाइसों के लिए, इमेज क्लासिफ़िकेशन गाइड

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

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

कोड का उदाहरण

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

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

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

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

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

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

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

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

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

  • ImageClassifierHelper.kt - इमेज की कैटगरी तय करने वाली प्रोसेस को शुरू करता है. साथ ही, मॉडल और चुनने का काम मैनेज करता है.
  • MainActivity.kt - ऐप्लिकेशन को लागू करता है. इसमें ImageClassificationHelper और ClassificationResultsAdapter को कॉल करना भी शामिल है.
  • ClassificationResultsAdapter.kt - नतीजों को हैंडल और फ़ॉर्मैट करता है.

सेटअप

इस सेक्शन में इमेज क्लासिफ़ायर इस्तेमाल करने के लिए, डेवलपमेंट एनवायरमेंट सेट अप करने और कोड प्रोजेक्ट सेट करने के मुख्य चरण बताए गए हैं. MediaPipe Tasks का इस्तेमाल करने और प्लैटफ़ॉर्म के वर्शन की ज़रूरी शर्तों के साथ-साथ अपना डेवलपमेंट एनवायरमेंट सेट अप करने से जुड़ी सामान्य जानकारी के लिए, 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

मॉडल के इस्तेमाल किए गए पाथ के बारे में बताने के लिए BaseOptions.Builder.setModelAssetPath() तरीके का इस्तेमाल करें. इस तरीके की जानकारी अगले सेक्शन में दिए गए कोड उदाहरण में दी गई है.

इमेज क्लासिफ़ायर उदाहरण कोड में, मॉडल की जानकारी ImageClassifierHelper.kt फ़ाइल में दी गई है.

टास्क बनाएं

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

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

Image

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.IMAGE)
    .setMaxResults(5)
    .build();
imageClassifier = ImageClassifier.createFromOptions(context, options);
    

वीडियो

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.VIDEO)
    .setMaxResults(5)
    .build();
imageClassifier = ImageClassifier.createFromOptions(context, options);
    

लाइव स्ट्रीम

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setMaxResults(5)
    .setResultListener((result, inputImage) -> {
         // Process the classification result here.
    })
    .setErrorListener((result, inputImage) -> {
         // Process the classification errors here.
    })
    .build()
imageClassifier = ImageClassifier.createFromOptions(context, options)
    

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

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

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

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

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

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

LIVE_STREAM: इनपुट डेटा की लाइव स्ट्रीम का मोड, जैसे कि कैमरे से स्ट्रीम किया जाने वाला मोड. इस मोड में, रिज़ल्ट पहचानकर्ता को लिसनर को सेट अप करने के लिए कॉल किया जाना चाहिए, ताकि वह एसिंक्रोनस तरीके से नतीजे पा सके.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
displayNamesLocale अगर यह उपलब्ध हो, तो टास्क के मॉडल के मेटाडेटा में दिए गए डिसप्ले नेम के लिए, लेबल की भाषा सेट करता है. अंग्रेज़ी के लिए डिफ़ॉल्ट रूप से en है. TensorFlow Lite Metadata Writer API का इस्तेमाल करके, कस्टम मॉडल के मेटाडेटा में स्थानीय भाषा के हिसाब से लेबल जोड़े जा सकते हैं स्थान-भाषा का कोड en
maxResults यह विकल्प, टॉप-स्कोर किए गए क्लासिफ़िकेशन के नतीजों की ज़्यादा से ज़्यादा संख्या को सेट करता है, ताकि नतीजे दिखाए जा सकें. अगर < 0 है, तो सभी उपलब्ध नतीजे दिखाए जाएंगे. कोई भी पॉज़िटिव नंबर -1
scoreThreshold अनुमान के स्कोर का थ्रेशोल्ड सेट करता है, जो मॉडल मेटाडेटा (अगर कोई है) में दिए गए स्कोर को बदलता है. इस वैल्यू से कम के नतीजे अस्वीकार कर दिए गए हैं. कोई भी फ़्लोट सेट नहीं किया गया है
categoryAllowlist अनुमति वाली कैटगरी के नामों की वैकल्पिक सूची सेट करता है. अगर यह खाली नहीं है, तो कैटगरी के जिन नतीजों की कैटगरी का नाम इस सेट में नहीं होगा उन्हें फ़िल्टर कर दिया जाएगा. श्रेणी के डुप्लीकेट या अज्ञात नामों पर ध्यान नहीं दिया जाता है. यह विकल्प categoryDenylist के साथ म्यूचुअली एक्सक्लूसिव है और दोनों नतीजों का इस्तेमाल करने में गड़बड़ी है. कोई भी स्ट्रिंग सेट नहीं किया गया है
categoryDenylist उन कैटगरी के नामों की वैकल्पिक सूची सेट करता है जिनकी अनुमति नहीं है. अगर यह फ़ील्ड खाली नहीं है, तो कैटगरी के जिन नतीजों की कैटगरी का नाम इस सेट में होगा उन्हें फ़िल्टर करके बाहर कर दिया जाएगा. श्रेणी के डुप्लीकेट या अज्ञात नामों पर ध्यान नहीं दिया जाता है. यह विकल्प categoryAllowlist के साथ म्यूचुअली एक्सक्लूसिव है और इसका इस्तेमाल करने पर दोनों में गड़बड़ी होगी. कोई भी स्ट्रिंग सेट नहीं किया गया है
resultListener जब इमेज क्लासिफ़ायर, लाइव स्ट्रीम मोड में होता है, तो इससे नतीजे के लिसनर को क्लासिफ़िकेशन के नतीजों को एसिंक्रोनस तरीके से पाने के लिए सेट किया जाता है. सिर्फ़ तब इस्तेमाल किया जा सकता है, जब रनिंग मोड LIVE_STREAM पर सेट हो लागू नहीं सेट नहीं किया गया है
errorListener गड़बड़ी की जानकारी देने वाला वैकल्पिक लिसनर सेट करता है. लागू नहीं सेट नहीं किया गया है

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

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

इमेज क्लासिफ़ायर को पास करने से पहले, आपको इनपुट इमेज या फ़्रेम को com.google.mediapipe.framework.image.MPImage ऑब्जेक्ट में बदलना होगा.

Image

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

// Load an image on the user’s device as a Bitmap object using BitmapFactory.

// Convert an Android’s Bitmap object to a MediaPipe’s Image object.
Image mpImage = new BitmapImageBuilder(bitmap).build();
    

वीडियो

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

// Load a video file on the user's device using MediaMetadataRetriever

// From the video’s metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT value. You’ll need them
// to calculate the timestamp of each frame later.

// Loop through the video and load each frame as a Bitmap object.

// Convert the Android’s Bitmap object to a MediaPipe’s Image object.
Image mpImage = new BitmapImageBuilder(frame).build();
    

लाइव स्ट्रीम

import com.google.mediapipe.framework.image.MediaImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Create a CameraX’s ImageAnalysis to continuously receive frames 
// from the device’s camera. Configure it to output frames in RGBA_8888
// format to match with what is required by the model.

// For each Android’s ImageProxy object received from the ImageAnalysis, 
// extract the encapsulated Android’s Image object and convert it to 
// a MediaPipe’s Image object.
android.media.Image mediaImage = imageProxy.getImage()
Image mpImage = new MediaImageBuilder(mediaImage).build();
    

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

टास्क चलाएं

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

Image

ImageClassifierResult classifierResult = imageClassifier.classify(image);
    

वीडियो

// Calculate the timestamp in milliseconds of the current frame.
long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count;

// Run inference on the frame.
ImageClassifierResult classifierResult =
    imageClassifier.classifyForVideo(image, frameTimestampMs);
    

लाइव स्ट्रीम


// Run inference on the frame. The classifications results will be available 
// via the `resultListener` provided in the `ImageClassifierOptions` when 
// the image classifier was created.
imageClassifier.classifyAsync(image, frameTimestampMs);
    

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

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

इमेज क्लासिफ़ायर के उदाहरण कोड में, classify फ़ंक्शन के बारे में ImageClassifierHelper.kt फ़ाइल में बताया गया है.

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

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

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

ImageClassifierResult:
 Classifications #0 (single classification head):
  head index: 0
  category #0:
   category name: "/m/01bwb9"
   display name: "Passer domesticus"
   score: 0.91406
   index: 671
  category #1:
   category name: "/m/01bwbt"
   display name: "Passer montanus"
   score: 0.00391
   index: 670

यह नतीजा, Bird Classifier को इन डिवाइस पर चलाकर हासिल किया गया है:

इमेज क्लासिफ़ायर के उदाहरण कोड में, ClassificationResultsAdapter.kt फ़ाइल में मौजूद ClassificationResultsAdapter क्लास नतीजों को हैंडल करती है:

fun updateResults(imageClassifierResult: ImageClassifierResult? = null) {
    categories = MutableList(adapterSize) { null }
    if (imageClassifierResult != null) {
        val sortedCategories = imageClassifierResult.classificationResult()
            .classifications()[0].categories().sortedBy { it.index() }
        val min = kotlin.math.min(sortedCategories.size, categories.size)
        for (i in 0 until min) {
            categories[i] = sortedCategories[i]
        }
    }
}