Catch up on everthing we announced at this year's Firebase Summit. Learn more

Android पर ML किट के साथ छवियाँ लेबल करें

आप किसी ऑन-डिवाइस मॉडल या क्लाउड मॉडल का उपयोग करके छवि में पहचाने गए ऑब्जेक्ट को लेबल करने के लिए एमएल किट का उपयोग कर सकते हैं। देखें सिंहावलोकन प्रत्येक दृष्टिकोण के लाभों के बारे में जानने के लिए।

शुरू करने से पहले

  1. आप पहले से ही नहीं है, तो अपने Android परियोजना के लिए Firebase जोड़ने
  2. एमएल किट एंड्रॉयड पुस्तकालयों के लिए निर्भरता अपने मॉड्यूल (एप्लिकेशन-स्तरीय) Gradle फ़ाइल (आमतौर पर में जोड़े app/build.gradle :)
    apply plugin: 'com.android.application'
    apply plugin: 'com.google.gms.google-services'
    
    dependencies {
      // ...
    
      implementation 'com.google.firebase:firebase-ml-vision:24.0.3'
      implementation 'com.google.firebase:firebase-ml-vision-image-label-model:20.0.1'
    }
    
  3. वैकल्पिक लेकिन अनुशंसित: अपने ऐप प्ले स्टोर से स्थापित किया गया है के बाद स्वत: डिवाइस के लिए एमएल मॉडल डाउनलोड करने के लिए आप डिवाइस पर मौजूद एपीआई का उपयोग करते हैं, तो अपने अनुप्रयोग कॉन्फ़िगर करें।

    ऐसा करने के लिए, अपने ऐप के लिए निम्न घोषणा जोड़ने AndroidManifest.xml फ़ाइल:

    <application ...>
      ...
      <meta-data
          android:name="com.google.firebase.ml.vision.DEPENDENCIES"
          android:value="label" />
      <!-- To use multiple models: android:value="label,model2,model3" -->
    </application>
    
    आप स्थापित समय मॉडल डाउनलोड सक्षम नहीं है, तो मॉडल पहली बार जब आप डिवाइस पर मौजूद डिटेक्टर चलाने डाउनलोड किया जाएगा। डाउनलोड पूरा होने से पहले आपके द्वारा किए गए अनुरोध कोई परिणाम नहीं देंगे।
  4. यदि आप क्लाउड-आधारित मॉडल का उपयोग करना चाहते हैं, और आपने पहले से ही अपने प्रोजेक्ट के लिए क्लाउड-आधारित API को सक्षम नहीं किया है, तो अभी करें:

    1. खोलें एमएल किट एपीआई पेज Firebase सांत्वना की।
    2. आप पहले से ही एक ब्लेज़ मूल्य निर्धारण योजना पर अपनी परियोजना अपग्रेड नहीं किए हैं, ऐसा करने के लिए अपग्रेड क्लिक करें। (आपको केवल तभी अपग्रेड करने के लिए कहा जाएगा जब आपका प्रोजेक्ट ब्लेज़ प्लान पर न हो।)

      केवल ब्लेज़-स्तरीय प्रोजेक्ट ही क्लाउड-आधारित API का उपयोग कर सकते हैं।

    3. क्लाउड-आधारित एपीआई पहले से सक्षम नहीं रहे हैं, तो क्लिक करें क्लाउड-आधारित API सक्षम करें।

    यदि आप केवल ऑन-डिवाइस मॉडल का उपयोग करना चाहते हैं, तो आप इस चरण को छोड़ सकते हैं।

अब आप ऑन-डिवाइस मॉडल या क्लाउड-आधारित मॉडल का उपयोग करके छवियों को लेबल करने के लिए तैयार हैं।

1. इनपुट छवि तैयार करें

एक बनाएं FirebaseVisionImage अपनी छवि से वस्तु। चित्र लेबलर सबसे तेजी से चलाता है जब आप एक का उपयोग Bitmap या, यदि आप camera2 एपीआई, एक JPEG स्वरूपित का उपयोग media.Image है, जो जब संभव हो सिफारिश की है।

  • एक बनाने के लिए FirebaseVisionImage एक से वस्तु media.Image जैसे जब कोई डिवाइस के कैमरे से एक छवि पर कब्जा करने के रूप में वस्तु,, पारित media.Image वस्तु और करने के लिए छवि के रोटेशन FirebaseVisionImage.fromMediaImage()

    आप का उपयोग करते हैं CameraX पुस्तकालय, OnImageCapturedListener और ImageAnalysis.Analyzer कक्षाएं, आप के लिए रोटेशन मूल्य की गणना, ताकि आप केवल एमएल है किट से एक के लिए रोटेशन बदलने की आवश्यकता ROTATION_ कॉल करने से पहले स्थिरांक FirebaseVisionImage.fromMediaImage() :

    जावा

    private class YourAnalyzer implements ImageAnalysis.Analyzer {
    
        private int degreesToFirebaseRotation(int degrees) {
            switch (degrees) {
                case 0:
                    return FirebaseVisionImageMetadata.ROTATION_0;
                case 90:
                    return FirebaseVisionImageMetadata.ROTATION_90;
                case 180:
                    return FirebaseVisionImageMetadata.ROTATION_180;
                case 270:
                    return FirebaseVisionImageMetadata.ROTATION_270;
                default:
                    throw new IllegalArgumentException(
                            "Rotation must be 0, 90, 180, or 270.");
            }
        }
    
        @Override
        public void analyze(ImageProxy imageProxy, int degrees) {
            if (imageProxy == null || imageProxy.getImage() == null) {
                return;
            }
            Image mediaImage = imageProxy.getImage();
            int rotation = degreesToFirebaseRotation(degrees);
            FirebaseVisionImage image =
                    FirebaseVisionImage.fromMediaImage(mediaImage, rotation);
            // Pass image to an ML Kit Vision API
            // ...
        }
    }
    

    कोटलिन + केटीएक्स

    private class YourImageAnalyzer : ImageAnalysis.Analyzer {
        private fun degreesToFirebaseRotation(degrees: Int): Int = when(degrees) {
            0 -> FirebaseVisionImageMetadata.ROTATION_0
            90 -> FirebaseVisionImageMetadata.ROTATION_90
            180 -> FirebaseVisionImageMetadata.ROTATION_180
            270 -> FirebaseVisionImageMetadata.ROTATION_270
            else -> throw Exception("Rotation must be 0, 90, 180, or 270.")
        }
    
        override fun analyze(imageProxy: ImageProxy?, degrees: Int) {
            val mediaImage = imageProxy?.image
            val imageRotation = degreesToFirebaseRotation(degrees)
            if (mediaImage != null) {
                val image = FirebaseVisionImage.fromMediaImage(mediaImage, imageRotation)
                // Pass image to an ML Kit Vision API
                // ...
            }
        }
    }
    

    यदि आप एक कैमरा लाइब्रेरी का उपयोग नहीं करते हैं जो आपको छवि का रोटेशन देता है, तो आप डिवाइस के रोटेशन और डिवाइस में कैमरा सेंसर के उन्मुखीकरण से इसकी गणना कर सकते हैं:

    जावा

    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
    static {
        ORIENTATIONS.append(Surface.ROTATION_0, 90);
        ORIENTATIONS.append(Surface.ROTATION_90, 0);
        ORIENTATIONS.append(Surface.ROTATION_180, 270);
        ORIENTATIONS.append(Surface.ROTATION_270, 180);
    }
    
    /**
     * Get the angle by which an image must be rotated given the device's current
     * orientation.
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private int getRotationCompensation(String cameraId, Activity activity, Context context)
            throws CameraAccessException {
        // Get the device's current rotation relative to its "native" orientation.
        // Then, from the ORIENTATIONS table, look up the angle the image must be
        // rotated to compensate for the device's rotation.
        int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        int rotationCompensation = ORIENTATIONS.get(deviceRotation);
    
        // On most devices, the sensor orientation is 90 degrees, but for some
        // devices it is 270 degrees. For devices with a sensor orientation of
        // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees.
        CameraManager cameraManager = (CameraManager) context.getSystemService(CAMERA_SERVICE);
        int sensorOrientation = cameraManager
                .getCameraCharacteristics(cameraId)
                .get(CameraCharacteristics.SENSOR_ORIENTATION);
        rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360;
    
        // Return the corresponding FirebaseVisionImageMetadata rotation value.
        int result;
        switch (rotationCompensation) {
            case 0:
                result = FirebaseVisionImageMetadata.ROTATION_0;
                break;
            case 90:
                result = FirebaseVisionImageMetadata.ROTATION_90;
                break;
            case 180:
                result = FirebaseVisionImageMetadata.ROTATION_180;
                break;
            case 270:
                result = FirebaseVisionImageMetadata.ROTATION_270;
                break;
            default:
                result = FirebaseVisionImageMetadata.ROTATION_0;
                Log.e(TAG, "Bad rotation value: " + rotationCompensation);
        }
        return result;
    }

    कोटलिन + केटीएक्स

    private val ORIENTATIONS = SparseIntArray()
    
    init {
        ORIENTATIONS.append(Surface.ROTATION_0, 90)
        ORIENTATIONS.append(Surface.ROTATION_90, 0)
        ORIENTATIONS.append(Surface.ROTATION_180, 270)
        ORIENTATIONS.append(Surface.ROTATION_270, 180)
    }
    /**
     * Get the angle by which an image must be rotated given the device's current
     * orientation.
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Throws(CameraAccessException::class)
    private fun getRotationCompensation(cameraId: String, activity: Activity, context: Context): Int {
        // Get the device's current rotation relative to its "native" orientation.
        // Then, from the ORIENTATIONS table, look up the angle the image must be
        // rotated to compensate for the device's rotation.
        val deviceRotation = activity.windowManager.defaultDisplay.rotation
        var rotationCompensation = ORIENTATIONS.get(deviceRotation)
    
        // On most devices, the sensor orientation is 90 degrees, but for some
        // devices it is 270 degrees. For devices with a sensor orientation of
        // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees.
        val cameraManager = context.getSystemService(CAMERA_SERVICE) as CameraManager
        val sensorOrientation = cameraManager
                .getCameraCharacteristics(cameraId)
                .get(CameraCharacteristics.SENSOR_ORIENTATION)!!
        rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360
    
        // Return the corresponding FirebaseVisionImageMetadata rotation value.
        val result: Int
        when (rotationCompensation) {
            0 -> result = FirebaseVisionImageMetadata.ROTATION_0
            90 -> result = FirebaseVisionImageMetadata.ROTATION_90
            180 -> result = FirebaseVisionImageMetadata.ROTATION_180
            270 -> result = FirebaseVisionImageMetadata.ROTATION_270
            else -> {
                result = FirebaseVisionImageMetadata.ROTATION_0
                Log.e(TAG, "Bad rotation value: $rotationCompensation")
            }
        }
        return result
    }

    फिर, पारित media.Image वस्तु और करने के लिए रोटेशन मूल्य FirebaseVisionImage.fromMediaImage() :

    जावा

    FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);

    कोटलिन + केटीएक्स

    val image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation)
  • एक बनाने के लिए FirebaseVisionImage एक फ़ाइल URI से वस्तु, एप्लिकेशन संदर्भ और फ़ाइल यूआरआई के पास FirebaseVisionImage.fromFilePath() । यह उपयोगी है जब आप एक का उपयोग है ACTION_GET_CONTENT उनके गैलरी app से एक चित्र का चयन करने के लिए संकेत के इरादे।

    जावा

    FirebaseVisionImage image;
    try {
        image = FirebaseVisionImage.fromFilePath(context, uri);
    } catch (IOException e) {
        e.printStackTrace();
    }

    कोटलिन + केटीएक्स

    val image: FirebaseVisionImage
    try {
        image = FirebaseVisionImage.fromFilePath(context, uri)
    } catch (e: IOException) {
        e.printStackTrace()
    }
  • एक बनाने के लिए FirebaseVisionImage एक से वस्तु ByteBuffer या एक बाइट सरणी, पहले के रूप में के लिए ऊपर वर्णित छवि रोटेशन की गणना media.Image इनपुट।

    फिर, एक बनाने FirebaseVisionImageMetadata उद्देश्य यह है कि छवि के ऊंचाई, चौड़ाई होता है, रंग एन्कोडिंग प्रारूप, और रोटेशन:

    जावा

    FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
            .setWidth(480)   // 480x360 is typically sufficient for
            .setHeight(360)  // image recognition
            .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
            .setRotation(rotation)
            .build();

    कोटलिन + केटीएक्स

    val metadata = FirebaseVisionImageMetadata.Builder()
            .setWidth(480) // 480x360 is typically sufficient for
            .setHeight(360) // image recognition
            .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
            .setRotation(rotation)
            .build()

    एक बनाने के लिए बफर या सरणी, और मेटाडाटा वस्तु का प्रयोग करें, FirebaseVisionImage वस्तु:

    जावा

    FirebaseVisionImage image = FirebaseVisionImage.fromByteBuffer(buffer, metadata);
    // Or: FirebaseVisionImage image = FirebaseVisionImage.fromByteArray(byteArray, metadata);

    कोटलिन + केटीएक्स

    val image = FirebaseVisionImage.fromByteBuffer(buffer, metadata)
    // Or: val image = FirebaseVisionImage.fromByteArray(byteArray, metadata)
  • एक बनाने के लिए FirebaseVisionImage एक से वस्तु Bitmap वस्तु:

    जावा

    FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);

    कोटलिन + केटीएक्स

    val image = FirebaseVisionImage.fromBitmap(bitmap)
    छवि का प्रतिनिधित्व करती Bitmap वस्तु, ईमानदार होना चाहिए कोई अतिरिक्त आवश्यकता रोटेशन के साथ।

2. इमेज लेबलर को कॉन्फ़िगर और रन करें

लेबल एक छवि में वस्तुओं के लिए, पारित FirebaseVisionImage करने के लिए वस्तु FirebaseVisionImageLabeler के processImage विधि।

  1. सबसे पहले, का एक उदाहरण मिल FirebaseVisionImageLabeler

    यदि आप ऑन-डिवाइस छवि लेबलर का उपयोग करना चाहते हैं:

    जावा

    FirebaseVisionImageLabeler labeler = FirebaseVision.getInstance()
        .getOnDeviceImageLabeler();
    
    // Or, to set the minimum confidence required:
    // FirebaseVisionOnDeviceImageLabelerOptions options =
    //     new FirebaseVisionOnDeviceImageLabelerOptions.Builder()
    //         .setConfidenceThreshold(0.7f)
    //         .build();
    // FirebaseVisionImageLabeler labeler = FirebaseVision.getInstance()
    //     .getOnDeviceImageLabeler(options);
    

    कोटलिन + केटीएक्स

    val labeler = FirebaseVision.getInstance().getOnDeviceImageLabeler()
    
    // Or, to set the minimum confidence required:
    // val options = FirebaseVisionOnDeviceImageLabelerOptions.Builder()
    //     .setConfidenceThreshold(0.7f)
    //     .build()
    // val labeler = FirebaseVision.getInstance().getOnDeviceImageLabeler(options)
    

    यदि आप क्लाउड इमेज लेबलर का उपयोग करना चाहते हैं:

    जावा

    FirebaseVisionImageLabeler labeler = FirebaseVision.getInstance()
        .getCloudImageLabeler();
    
    // Or, to set the minimum confidence required:
    // FirebaseVisionCloudImageLabelerOptions options =
    //     new FirebaseVisionCloudImageLabelerOptions.Builder()
    //         .setConfidenceThreshold(0.7f)
    //         .build();
    // FirebaseVisionImageLabeler labeler = FirebaseVision.getInstance()
    //     .getCloudImageLabeler(options);
    

    कोटलिन + केटीएक्स

    val labeler = FirebaseVision.getInstance().getCloudImageLabeler()
    
    // Or, to set the minimum confidence required:
    // val options = FirebaseVisionCloudImageLabelerOptions.Builder()
    //     .setConfidenceThreshold(0.7f)
    //     .build()
    // val labeler = FirebaseVision.getInstance().getCloudImageLabeler(options)
    

  2. फिर, करने के लिए छवि से पारित processImage() विधि:

    जावा

    labeler.processImage(image)
        .addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionImageLabel>>() {
          @Override
          public void onSuccess(List<FirebaseVisionImageLabel> labels) {
            // Task completed successfully
            // ...
          }
        })
        .addOnFailureListener(new OnFailureListener() {
          @Override
          public void onFailure(@NonNull Exception e) {
            // Task failed with an exception
            // ...
          }
        });
    

    कोटलिन + केटीएक्स

    labeler.processImage(image)
        .addOnSuccessListener { labels ->
          // Task completed successfully
          // ...
        }
        .addOnFailureListener { e ->
          // Task failed with an exception
          // ...
        }
    

3. लेबल की गई वस्तुओं के बारे में जानकारी प्राप्त करें

छवि लेबलिंग आपरेशन सफल होती है, की एक सूची FirebaseVisionImageLabel वस्तुओं सफलता श्रोता को पारित हो जाएगा। प्रत्येक FirebaseVisionImageLabel वस्तु कुछ है कि छवि में चिह्नित किया गया प्रतिनिधित्व करता है। प्रत्येक लेबल के लिए, आप लेबल की पाठ वर्णन, अपने प्राप्त कर सकते हैं ज्ञान का ग्राफ़ इकाई आईडी (यदि उपलब्ध हो), और मैच का विश्वास स्कोर। उदाहरण के लिए:

जावा

for (FirebaseVisionImageLabel label: labels) {
  String text = label.getText();
  String entityId = label.getEntityId();
  float confidence = label.getConfidence();
}

कोटलिन + केटीएक्स

for (label in labels) {
  val text = label.text
  val entityId = label.entityId
  val confidence = label.confidence
}

रीयल-टाइम प्रदर्शन को बेहतर बनाने के लिए टिप्स

यदि आप रीयल-टाइम एप्लिकेशन में छवियों को लेबल करना चाहते हैं, तो सर्वोत्तम फ़्रैमरेट प्राप्त करने के लिए इन दिशानिर्देशों का पालन करें:

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

    आप में बड़े कैमरा एपीआई, कब्जा छवियों का उपयोग करते हैं ImageFormat.NV21 प्रारूप।

अगला कदम