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

অ্যান্ড্রয়েডে একটি অটোমেল প্রশিক্ষিত মডেল সহ চিত্রগুলি লেবেল করুন

আপনি পরে AutoML ভিশন এজ ব্যবহার করে নিজস্ব মডেল প্রশিক্ষণ , আপনি ট্যাগ ইমেজ আপনার অ্যাপে ব্যবহার করতে পারেন।

অটোএমএল ভিশন এজ থেকে প্রশিক্ষিত মডেলগুলিকে একীভূত করার দুটি উপায় রয়েছে: আপনি মডেলটিকে আপনার অ্যাপের সম্পদ ফোল্ডারের মধ্যে রেখে বান্ডেল করতে পারেন, অথবা আপনি ফায়ারবেস থেকে গতিশীলভাবে ডাউনলোড করতে পারেন।

মডেল বান্ডিলিং বিকল্প
আপনার অ্যাপে বান্ডেল করা হয়েছে
  • মডেলটি আপনার অ্যাপের APK এর অংশ
  • অ্যান্ড্রয়েড ডিভাইস অফলাইনে থাকলেও মডেলটি অবিলম্বে পাওয়া যায়
  • ফায়ারবেস প্রকল্পের প্রয়োজন নেই
ফায়ারবেস দিয়ে হোস্ট করা হয়েছে
  • এ আপলোড করে মডেল হোস্ট Firebase মেশিন লার্নিং
  • APK সাইজ কমায়
  • চাহিদা অনুযায়ী মডেলটি ডাউনলোড করা হয়
  • আপনার অ্যাপ পুন repপ্রকাশ না করে মডেল আপডেটগুলি পুশ করুন
  • সহজ এ / বি নিয়ে পরীক্ষা Firebase রিমোট কনফিগ
  • একটি Firebase প্রকল্প প্রয়োজন

তুমি শুরু করার আগে

  1. এমএল কিট অ্যান্ড্রয়েড লাইব্রেরির জন্য নির্ভরতা আপনার মডিউল অ্যাপ্লিকেশান পর্যায়ের gradle ফাইল, যা সাধারণত হয় যোগ করুন app/build.gradle :

    আপনার অ্যাপের সাথে একটি মডেল বান্ডিল করার জন্য:

    dependencies {
      // ...
      // Image labeling feature with bundled automl model
      implementation 'com.google.mlkit:image-labeling-custom:16.3.1'
    }
    

    পরিবর্তনশীল Firebase থেকে একটি মডেল ডাউনলোড করার জন্য, যোগ করুন linkFirebase নির্ভরতা:

    dependencies {
      // ...
      // Image labeling feature with automl model downloaded
      // from firebase
      implementation 'com.google.mlkit:image-labeling-custom:16.3.1'
      implementation 'com.google.mlkit:linkfirebase:16.1.0'
    }
    
  2. আপনি একটি মডেল ডাউনলোড করতে চান, আপনি নিশ্চিত করুন আপনার অ্যান্ড্রয়েড প্রকল্পের Firebase যোগ , যদি আপনি ইতিমধ্যে এটি না করে। যখন আপনি মডেলটি বান্ডেল করেন তখন এটি প্রয়োজন হয় না।

1. মডেল লোড করুন

একটি স্থানীয় মডেল উৎস কনফিগার করুন

আপনার অ্যাপের সাথে মডেল বান্ডেল করতে:

  1. আপনি Firebase কনসোল থেকে ডাউনলোড করা জিপ আর্কাইভ থেকে মডেল এবং তার মেটাডেটা বের করুন। আমরা আপনাকে ফাইলগুলি ডাউনলোড করার সময় ব্যবহার করার পরামর্শ দিচ্ছি, পরিবর্তন ছাড়াই (ফাইলের নাম সহ)।

  2. আপনার অ্যাপ প্যাকেজে আপনার মডেল এবং এর মেটাডেটা ফাইল অন্তর্ভুক্ত করুন:

    1. আপনি আপনার প্রকল্পে ফোল্ডারের একটি সম্পদ না থাকে তাহলে, ডান-ক্লিক করে একটি তৈরি app/ ফোল্ডারের তারপরে নতুন> ফোল্ডার> সম্পদ ফোল্ডার।
    2. মডেল ফাইলগুলি ধারণ করতে সম্পদ ফোল্ডারের অধীনে একটি সাব-ফোল্ডার তৈরি করুন।
    3. কপি করা ফাইল model.tflite , dict.txt এবং manifest.json উপ-ফোল্ডারে (সমস্ত তিনটি ফাইল একই ফোল্ডারে হতে হবে)।
  3. আপনার অ্যাপ্লিকেশনের মধ্যে নিম্নলিখিত যোগ build.gradle নিশ্চিত করার যখন অ্যাপ্লিকেশন নির্মাণের Gradle মডেল ফাইল কম্প্রেস নেই ফাইল:

    android {
        // ...
        aaptOptions {
            noCompress "tflite"
        }
    }
    

    মডেল ফাইলটি অ্যাপ প্যাকেজে অন্তর্ভুক্ত করা হবে এবং কাঁচা সম্পদ হিসেবে এমএল কিটে পাওয়া যাবে।

  4. তৈরি করুন LocalModel বস্তু, মডেল ম্যানিফেস্ট ফাইল পাথ উল্লেখ:

    জাভা

    AutoMLImageLabelerLocalModel localModel =
        new AutoMLImageLabelerLocalModel.Builder()
            .setAssetFilePath("manifest.json")
            // or .setAbsoluteFilePath(absolute file path to manifest file)
            .build();
    

    কোটলিন

    val localModel = LocalModel.Builder()
        .setAssetManifestFilePath("manifest.json")
        // or .setAbsoluteManifestFilePath(absolute file path to manifest file)
        .build()
    

একটি Firebase- হোস্ট করা মডেল উৎস কনফিগার করুন

দূরবর্তী অবস্থান থেকে হোস্ট করা মডেল ব্যবহার করতে, একটি তৈরি CustomRemoteModel , বস্তুর নাম আপনার মডেলকে বরাদ্দ যখন আপনি এটি প্রকাশিত উল্লেখ:

জাভা

// Specify the name you assigned in the Firebase console.
FirebaseModelSource firebaseModelSource =
    new FirebaseModelSource.Builder("your_model_name").build();
CustomRemoteModel remoteModel =
    new CustomRemoteModel.Builder(firebaseModelSource).build();

কোটলিন

// Specify the name you assigned in the Firebase console.
val firebaseModelSource = FirebaseModelSource.Builder("your_model_name")
    .build()
val remoteModel = CustomRemoteModel.Builder(firebaseModelSource).build()

তারপরে, মডেল ডাউনলোডের কাজটি শুরু করুন, যে শর্তগুলি আপনি ডাউনলোড করার অনুমতি দিতে চান তা উল্লেখ করে। যদি মডেলটি ডিভাইসে না থাকে, অথবা যদি মডেলের একটি নতুন সংস্করণ পাওয়া যায়, তাহলে টাস্কটি অ্যাসিঙ্ক্রোনাসভাবে ফায়ারবেস থেকে মডেলটি ডাউনলোড করবে:

জাভা

DownloadConditions downloadConditions = new DownloadConditions.Builder()
        .requireWifi()
        .build();
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(@NonNull Task<Void> task) {
                // Success.
            }
        });

কোটলিন

val downloadConditions = DownloadConditions.Builder()
    .requireWifi()
    .build()
RemoteModelManager.getInstance().download(remoteModel, downloadConditions)
    .addOnSuccessListener {
        // Success.
    }

অনেক অ্যাপ তাদের প্রাথমিক কোডে ডাউনলোড টাস্ক শুরু করে, কিন্তু মডেল ব্যবহার করার আগে আপনি যেকোনো সময়ে এটি করতে পারেন।

আপনার মডেল থেকে একটি ইমেজ লেবেলার তৈরি করুন

আপনি আপনার মডেল সূত্র কনফিগার পর তৈরি ImageLabeler তাদের মধ্যে একজন থেকে অবজেক্ট।

আপনি শুধুমাত্র একটি স্থানীয়ভাবে-বান্ডেল মডেল থাকে, তাহলে শুধু একটি লেবেলার থেকে আপনার তৈরি CustomImageLabelerOptions বস্তু এবং আস্থা স্কোর থ্রেশহোল্ড আপনি প্রয়োজন (দেখুন চান কনফিগার আপনার মডেল মূল্যায়ন ):

জাভা

CustomImageLabelerOptions customImageLabelerOptions = new CustomImageLabelerOptions.Builder(localModel)
    .setConfidenceThreshold(0.0f)  // Evaluate your model in the Cloud console
                                   // to determine an appropriate value.
    .build();
ImageLabeler labeler = ImageLabeling.getClient(customImageLabelerOptions);

কোটলিন

val customImageLabelerOptions = CustomImageLabelerOptions.Builder(localModel)
    .setConfidenceThreshold(0.0f)  // Evaluate your model in the Cloud console
                                   // to determine an appropriate value.
    .build()
val labeler = ImageLabeling.getClient(customImageLabelerOptions)

আপনার যদি রিমোট-হোস্টেড মডেল থাকে, তবে আপনাকে এটি চালানোর আগে এটি ডাউনলোড করা হয়েছে কিনা তা পরীক্ষা করতে হবে। আপনার মডেলকে ম্যানেজারের ব্যবহার মডেল ডাউনলোড কাজের স্থিতি পরীক্ষা করতে isModelDownloaded() পদ্ধতি।

যদিও আপনাকে কেবল লেবেলার চালানোর আগে এটি নিশ্চিত করতে হবে, যদি আপনার দূরবর্তীভাবে হোস্ট করা মডেল এবং স্থানীয়ভাবে বান্ডেল মডেল উভয়ই থাকে, তবে ইমেজ লেবেলারটি তাত্ক্ষণিক করার সময় এই চেকটি সম্পাদন করা বোধগম্য হতে পারে: দূরবর্তী মডেল থেকে একটি লেবেলার তৈরি করুন যদি এটি ডাউনলোড করা হয়েছে, এবং স্থানীয় মডেল থেকে অন্যথায়।

জাভা

RemoteModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener(new OnSuccessListener<Boolean>() {
            @Override
            public void onSuccess(Boolean isDownloaded) {
                CustomImageLabelerOptions.Builder optionsBuilder;
                if (isDownloaded) {
                    optionsBuilder = new CustomImageLabelerOptions.Builder(remoteModel);
                } else {
                    optionsBuilder = new CustomImageLabelerOptions.Builder(localModel);
                }
                CustomImageLabelerOptions options = optionsBuilder
                        .setConfidenceThreshold(0.0f)  // Evaluate your model in the Cloud console
                                                       // to determine an appropriate threshold.
                        .build();

                ImageLabeler labeler = ImageLabeling.getClient(options);
            }
        });

কোটলিন

RemoteModelManager.getInstance().isModelDownloaded(remoteModel)
    .addOnSuccessListener { isDownloaded ->
        val optionsBuilder =
            if (isDownloaded) {
                CustomImageLabelerOptions.Builder(remoteModel)
            } else {
                CustomImageLabelerOptions.Builder(localModel)
            }
        // Evaluate your model in the Cloud console to determine an appropriate threshold.
        val options = optionsBuilder.setConfidenceThreshold(0.0f).build()
        val labeler = ImageLabeling.getClient(options)
}

যদি আপনার শুধুমাত্র দূরবর্তীভাবে হোস্ট করা মডেল থাকে, তাহলে আপনার মডেল-সম্পর্কিত কার্যকারিতা অক্ষম করা উচিত example উদাহরণস্বরূপ, গ্রে-আউট বা আপনার UI- এর কিছু অংশ লুকান — যতক্ষণ না আপনি নিশ্চিত করেছেন যে মডেলটি ডাউনলোড হয়েছে। আপনার মডেলকে ম্যানেজারের করার জন্য একটি শ্রোতা সংযোজনের করে তা করতে পারেন download() পদ্ধতি:

জাভা

RemoteModelManager.getInstance().download(remoteModel, conditions)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void v) {
              // Download complete. Depending on your app, you could enable
              // the ML feature, or switch from the local model to the remote
              // model, etc.
            }
        });

কোটলিন

RemoteModelManager.getInstance().download(remoteModel, conditions)
    .addOnSuccessListener {
        // Download complete. Depending on your app, you could enable the ML
        // feature, or switch from the local model to the remote model, etc.
    }

2. ইনপুট ইমেজ প্রস্তুত করুন

এর পরে, প্রতিটি ইমেজ আপনি ট্যাগ করতে চান তাদের জন্য, একটি তৈরি InputImage আপনার ইমেজ থেকে অবজেক্ট। ছবি লেবেলার দ্রুততম রান যখন আপনি একটি ব্যবহার Bitmap অথবা, যদি আপনি camera2 এপিআই, একটি YUV_420_888 ব্যবহার media.Image , যা যখন সম্ভব সুপারিশ করা হয়।

আপনি একটি তৈরি করতে পারেন InputImage বিভিন্ন সূত্র থেকে, প্রতিটি নিচে ব্যাখ্যা করা হয়।

একটি ব্যবহার media.Image

একটি তৈরি করতে InputImage একটি থেকে অবজেক্ট media.Image যেমন যখন আপনি, একটি ডিভাইস ক্যামেরা থেকে প্রতিচ্ছবি পাস হিসাবে বস্তু, media.Image বস্তু এবং ছবিতে আবর্তনের InputImage.fromMediaImage()

আপনি ব্যবহার করেন তাহলে CameraX গ্রন্থাগার, OnImageCapturedListener এবং ImageAnalysis.Analyzer শ্রেণীর তোমার জন্য ঘূর্ণন মান নিরূপণ।

জাভা

private class YourAnalyzer implements ImageAnalysis.Analyzer {

    @Override
    public void analyze(ImageProxy imageProxy) {
        if (imageProxy == null || imageProxy.getImage() == null) {
            return;
        }
        Image mediaImage = imageProxy.getImage();
        InputImage image =
                InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees);
        // Pass image to an ML Kit Vision API
        // ...
    }
}

কোটলিন+কেটিএক্স

private class YourImageAnalyzer : ImageAnalysis.Analyzer {
    override fun analyze(imageProxy: ImageProxy?) {
        val mediaImage = imageProxy?.image
        if (mediaImage != null) {
            val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
            // 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 বস্তু এবং করতে ঘূর্ণন ডিগ্রী মান InputImage.fromMediaImage() :

জাভা

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

কোটলিন+কেটিএক্স

val image = InputImage.fromMediaImage(mediaImage, rotation)

URI একটি ফাইল ব্যবহার করে

একটি তৈরি করতে InputImage একটি ফাইল কোনো URI থেকে অবজেক্ট, অ্যাপ্লিকেশন প্রসঙ্গ পাস এবং কোনো URI দায়ের InputImage.fromFilePath() । এটি দরকারী যখন আপনি একটি ব্যবহার করেন ACTION_GET_CONTENT তাদের গ্যালারি অ্যাপ্লিকেশান থেকে একটি চিত্র নির্বাচন করতে চাইলে ব্যবহারকারীকে অনুরোধ জানানো অভিপ্রায়।

জাভা

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

কোটলিন+কেটিএক্স

val image: InputImage
try {
    image = InputImage.fromFilePath(context, uri)
} catch (e: IOException) {
    e.printStackTrace()
}

একটি ব্যবহার ByteBuffer বা ByteArray

একটি তৈরি করতে InputImage একটি থেকে অবজেক্ট ByteBuffer বা ByteArray , প্রথম ইমেজ ঘূর্ণন ডিগ্রী হিসাবে পূর্বে জন্য বর্ণিত নিরূপণ media.Image ইনপুট। তারপরে, InputImage বাফার বা অ্যারে সঙ্গে বস্তু, একসঙ্গে চিত্রের উচ্চতা, প্রস্থ, রঙ এনকোডিং ফরম্যাট, এবং আবর্তনের ডিগ্রী অর্জন:

জাভা

InputImage image = InputImage.fromByteBuffer(byteBuffer,
        /* image width */ 480,
        /* image height */ 360,
        rotationDegrees,
        InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12
);

কোটলিন+কেটিএক্স

val image = InputImage.fromByteBuffer(
        byteBuffer,
        /* image width */ 480,
        /* image height */ 360,
        rotationDegrees,
        InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12
)

একটি ব্যবহার Bitmap

একটি তৈরি করতে InputImage একটি থেকে অবজেক্ট Bitmap বস্তু, নিম্নলিখিত ঘোষণা করুন:

জাভা

InputImage image = InputImage.fromBitmap(bitmap, rotationDegree);

কোটলিন+কেটিএক্স

val image = InputImage.fromBitmap(bitmap, 0)

ছবিটি একটি দ্বারা প্রতিনিধিত্ব করা হয় Bitmap ঘূর্ণন মাত্রার বস্তুর একসঙ্গে।

3. ইমেজ লেবেলার চালান

একটি লেবেল একটি ছবিতে বস্তু, পাস image বস্তুর ImageLabeler এর process() পদ্ধতি।

জাভা

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

কোটলিন

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

4. লেবেলযুক্ত বস্তু সম্পর্কে তথ্য পান

ইমেজ লেবেল অপারেশন সফল হয়, তাহলে একটি তালিকা ImageLabel বস্তু সাফল্য শ্রোতার কাছে পাস করা হয়েছে। প্রতিটি ImageLabel বস্তুর এমন কিছু বিষয় যা ছবিতে লেবেল ছিল প্রতিনিধিত্ব করে। আপনি প্রতিটি লেবেলের পাঠ্য বিবরণ, ম্যাচের আত্মবিশ্বাস স্কোর এবং ম্যাচের সূচক পেতে পারেন। উদাহরণ স্বরূপ:

জাভা

for (ImageLabel label : labels) {
    String text = label.getText();
    float confidence = label.getConfidence();
    int index = label.getIndex();
}

কোটলিন

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

রিয়েল-টাইম পারফরম্যান্স উন্নত করার টিপস

আপনি যদি রিয়েল-টাইম অ্যাপ্লিকেশনে ছবিগুলি লেবেল করতে চান, তাহলে সেরা ফ্রেমরেট অর্জনের জন্য এই নির্দেশিকাগুলি অনুসরণ করুন:
  • থ্রোটল ইমেজ লেবেলারে কল করে। ইমেজ লেবেলার চলমান অবস্থায় যদি একটি নতুন ভিডিও ফ্রেম পাওয়া যায়, তাহলে ফ্রেমটি ফেলে দিন। দেখুন VisionProcessorBase উদাহরণের জন্য দ্রুতশুরু নমুনা অ্যাপ্লিকেশানে বর্গ।
  • আপনি যদি ইনপুট ইমেজে গ্রাফিক্স ওভারলে করার জন্য ইমেজ লেবেলারের আউটপুট ব্যবহার করছেন, তাহলে প্রথমে ফলাফল পান, তারপর ইমেজ রেন্ডার করুন এবং একটি ধাপে ওভারলে করুন। এটি করার মাধ্যমে, আপনি প্রতিটি ইনপুট ফ্রেমের জন্য শুধুমাত্র একবার ডিসপ্লে সারফেসে রেন্ডার করুন। দেখুন CameraSourcePreview এবং GraphicOverlay উদাহরণের জন্য দ্রুতশুরু নমুনা অ্যাপ্লিকেশানে ক্লাস।
  • আপনি Camera2 এপিআই, ক্যাপচার ইমেজ ব্যবহার করেন তাহলে ImageFormat.YUV_420_888 বিন্যাস।

    আপনি পুরোনো ক্যামেরা এপিআই, ক্যাপচার ইমেজ ব্যবহার করেন তাহলে ImageFormat.NV21 বিন্যাস।