আপনি ML Kit-এ কোনও ছবি পাস করলে, এটি ছবিতে সর্বাধিক পাঁচটি অবজেক্ট শনাক্ত করে এবং ছবিতে প্রতিটি অবজেক্টের অবস্থানও শনাক্ত করে। ভিডিও স্ট্রিমে অবজেক্ট শনাক্ত করার সময়, প্রতিটি অবজেক্টের একটি অনন্য আইডি থাকে যা আপনি ফ্রেম থেকে ফ্রেমে অবজেক্ট ট্র্যাক করার জন্য ব্যবহার করতে পারেন।
শনাক্ত করা অবজেক্টকে শ্রেণীবদ্ধ করতে আপনি কাস্টম ইমেজ ক্লাসিফিকেশন মডেল ব্যবহার করতে পারেন। মডেলের মানানসই হওয়ার প্রয়োজনীয়তা, আগে থেকে ট্রেনিং দেওয়া মডেল কোথায় পাওয়া যাবে এবং কীভাবে আপনার নিজস্ব মডেলকে ট্রেনিং দেবেন সেই বিষয়ে নির্দেশিকার জন্য ML Kit-এর সাথে কাস্টম মডেল দেখুন।
কাস্টম মডেল ইন্টিগ্রেট করার দুটি উপায় আছে। আপনি মডেলটি বান্ডেল করতে পারেন, এর জন্য আপনার অ্যাপের অ্যাসেট ফোল্ডারের মধ্যে এটি রাখুন অথবা আপনি Cloud Storage থেকে এটি ডায়নামিক ডাউনলোড করতে পারেন। নিম্নলিখিত সারণীতে দুটি বিকল্পের তুলনা করা হয়েছে।
| বান্ডেল করা মডেল | হোস্ট করা মডেল |
|---|---|
| মডেলটি আপনার অ্যাপের APK-এর অংশ, যার ফলে এর সাইজ বেড়ে যায়। | মডেলটি আপনার APK-এর অংশ নয়। এটি Cloud Storage-এ আপলোড করে হোস্ট করা হয়। আমরা Firebase-এর জন্য ক্লাউড স্টোরেজ ব্যবহার করার সাজেশন দিই। |
| Android ডিভাইস অফলাইনে থাকলেও মডেলটি সঙ্গে সঙ্গে উপলভ্য হয় | আপনার অ্যাপে অবশ্যই চাহিদা অনুযায়ী মডেল ডাউনলোড করার কোড থাকতে হবে |
| Firebase প্রোজেক্টের প্রয়োজন নেই | Firebase প্রোজেক্ট প্রয়োজন (Firebase-এর জন্য Cloud Storage ব্যবহার করলে)। |
| মডেল আপডেট করতে হলে আপনাকে অবশ্যই অ্যাপ আবার প্রকাশ করতে হবে | আপনার অ্যাপ আবার প্রকাশ না করেই মডেল আপডেট পুশ করা |
| কোনও বিল্ট-ইন A/B টেস্টিং নেই | Firebase রিমোট কনফিগ ব্যবহার করে A/B টেস্টিং |
এটি ব্যবহার করে দেখুন
- বান্ডেল করা মডেলের ব্যবহারের উদাহরণ দেখতে ভিশন কুইকস্টার্ট অ্যাপ এবং হোস্ট করা মডেলের ব্যবহারের উদাহরণ দেখতে automl কুইকস্টার্ট অ্যাপ দেখুন।
- এই API-এর এন্ড-টু-এন্ড প্রয়োগের জন্য Material Design শোকেস অ্যাপ দেখুন।
শুরু করার আগে
১. আপনার প্রোজেক্ট-লেভেলbuild.gradle.kts ফাইলে, এগুলি অন্তর্ভুক্ত করতে ভুলবেন না:
আপনার buildscript এবং
allprojects বিভাগে Google-এর Maven রিপোজিটরি।
আপনার মডিউলের অ্যাপ-লেভেল গ্রেডেল ফাইলে ML Kit Android লাইব্রেরির ডিপেন্ডেন্সি যোগ করুন, যা সাধারণত
app/build.gradle.kts:আপনার অ্যাপের সাথে মডেল বান্ডেল করতে:
dependencies { // ... // Object detection & tracking feature with custom bundled model implementation("com.google.mlkit:object-detection-custom:17.0.2") }আপনি Firebase-এর জন্য Cloud Storage থেকে কোনও মডেল ডাউনলোড করতে চাইলে, নিশ্চিত করুন যে আপনি আপনার Android প্রোজেক্টে Firebase যোগ করেছেন, যদি আগে থেকে এটি না করে থাকেন। আপনি মডেল বান্ডেল করলে এটি করার প্রয়োজন নেই।
১. মডেল লোড করুন
আপনি কোনও লোকালি-বান্ডেল করা সোর্স বা রিমোটলি-হোস্ট করা সোর্স থেকে মডেল লোড করতে পারবেন।
লোকাল মডেল সোর্স কনফিগার করা
আপনার অ্যাপের সাথে মডেল বান্ডেল করতে:
আপনার অ্যাপের
assets/ফোল্ডারে মডেল ফাইল (সাধারণত.tfliteবা.liteএক্সটেনশন থাকে) কপি করুন। (আপনাকে হয়ত প্রথমেapp/ফোল্ডারে ডানদিকের বোতামে ক্লিক করে ফোল্ডার তৈরি করতে হবে, তারপর নতুন > ফোল্ডার > অ্যাসেট ফোল্ডার বিকল্পে ক্লিক করতে হবে। )মডেল ফাইলের পাথ উল্লেখ করে একটি
LocalModelঅবজেক্ট তৈরি করুন:Kotlin
val localModel = LocalModel.Builder() .setAssetFilePath("model.tflite") // or .setAbsoluteFilePath(absolute path to model file) // or .setUri(URI to model file) .build()
Java
LocalModel localModel = new LocalModel.Builder() .setAssetFilePath("model.tflite") // or .setAbsoluteFilePath(absolute path to model file) // or .setUri(URI to model file) .build();
রিমোট লোকেশন থেকে হোস্ট করা মডেল সোর্স কনফিগার করুন
রিমোটলি-হোস্ট করা মডেল ব্যবহার করতে, আপনাকে অবশ্যই নিজের অ্যাপ লজিক ব্যবহার করে ডিভাইসের লোকাল স্টোরেজে মডেল ফাইল ডাউনলোড করতে হবে এবং তারপরে এটি লোকাল মডেল হিসেবে লোড করতে হবে। মডেল হোস্ট করার জন্য আমরা Firebase-এর জন্য ক্লাউড স্টোরেজ ব্যবহার করার সাজেশন দিই। ইমপ্লিমেন্টেশন সম্পর্কিত বিবরণের জন্য, Firebase ML থেকে Cloud Storage মাইগ্রেশন গাইড দেখুন।
২. অবজেক্ট ডিটেক্টর কনফিগার করুন
আপনার মডেল সোর্স কনফিগার করার পরে, CustomObjectDetectorOptions অবজেক্টের সাহায্যে আপনার
ইউজ কেসের জন্য অবজেক্ট ডিটেক্টর কনফিগার করুন। আপনি নিম্নলিখিত সেটিংস
পরিবর্তন করতে পারবেন:
| অবজেক্ট ডিটেক্টর সেটিংস | |
|---|---|
| শনাক্তকরণ মোড |
STREAM_MODE (ডিফল্ট) | SINGLE_IMAGE_MODE
|
| একাধিক অবজেক্ট শনাক্ত ও ট্র্যাক করা |
false (ডিফল্ট) | true
সর্বাধিক পাঁচটি অবজেক্ট শনাক্ত ও ট্র্যাক করা হবে নাকি শুধুমাত্র সবচেয়ে গুরুত্বপূর্ণ অবজেক্ট (ডিফল্ট)। |
| অবজেক্ট শ্রেণীবদ্ধ করা |
false (ডিফল্ট) | true
প্রদত্ত কাস্টম ক্লাসিফায়ার মডেল ব্যবহার করে শনাক্ত করা অবজেক্টকে শ্রেণীবিভক্ত
করতে হবে কিনা। আপনার কাস্টম শ্রেণীবিভাগ
মডেল ব্যবহার করতে, আপনাকে এটি |
| শ্রেণীবিভাগ সংক্রান্ত কনফিডেন্স থ্রেশহোল্ড |
শনাক্ত করা লেবেলের ন্যূনতম কনফিডেন্স স্কোর। সেট করা না থাকলে, মডেলের মেটাডেটা দ্বারা নির্দিষ্ট করা যেকোনও ক্লাসিফায়ার থ্রেশহোল্ড ব্যবহার করা হবে। মডেলের মধ্যে কোনও মেটাডেটা না থাকলে অথবা মেটাডেটা কোনও শ্রেণীবিন্যাসকারী থ্রেশহোল্ড নির্দিষ্ট না করলে, 0.0-এর একটি ডিফল্ট থ্রেশহোল্ড ব্যবহার করা হবে। |
| অবজেক্ট প্রতি সর্বাধিক লেবেল |
ডিটেক্টর কোনও অবজেক্টের জন্য সর্বাধিক যতগুলি লেবেল রিটার্ন করবে। সেট করা না থাকলে, ডিফল্ট ভ্যালু হিসেবে ১০ ব্যবহার করা হবে। |
এই দুটি মূল সম্ভাব্য পরিস্থিতির জন্য অবজেক্ট ডিটেকশন ও ট্র্যাকিং API অপ্টিমাইজ করা হয়েছে:
- ক্যামেরা ভিউফাইন্ডারে সবচেয়ে গুরুত্বপূর্ণ অবজেক্টের লাইভ ডিটেকশন ও ট্র্যাকিং।
- স্ট্যাটিক ছবি থেকে একাধিক অবজেক্ট শনাক্ত করা।
লোকালভাবে বান্ডেল করা মডেলের সাহায্যে এই ধরনের ব্যবহারের জন্য API কনফিগার করতে:
Kotlin
// Live detection and tracking val customObjectDetectorOptions = CustomObjectDetectorOptions.Builder(localModel) .setDetectorMode(CustomObjectDetectorOptions.STREAM_MODE) .enableClassification() .setClassificationConfidenceThreshold(0.5f) .setMaxPerObjectLabelCount(3) .build() // Multiple object detection in static images val customObjectDetectorOptions = CustomObjectDetectorOptions.Builder(localModel) .setDetectorMode(CustomObjectDetectorOptions.SINGLE_IMAGE_MODE) .enableMultipleObjects() .enableClassification() .setClassificationConfidenceThreshold(0.5f) .setMaxPerObjectLabelCount(3) .build() val objectDetector = ObjectDetection.getClient(customObjectDetectorOptions)
Java
// Live detection and tracking CustomObjectDetectorOptions customObjectDetectorOptions = new CustomObjectDetectorOptions.Builder(localModel) .setDetectorMode(CustomObjectDetectorOptions.STREAM_MODE) .enableClassification() .setClassificationConfidenceThreshold(0.5f) .setMaxPerObjectLabelCount(3) .build(); // Multiple object detection in static images CustomObjectDetectorOptions customObjectDetectorOptions = new CustomObjectDetectorOptions.Builder(localModel) .setDetectorMode(CustomObjectDetectorOptions.SINGLE_IMAGE_MODE) .enableMultipleObjects() .enableClassification() .setClassificationConfidenceThreshold(0.5f) .setMaxPerObjectLabelCount(3) .build(); ObjectDetector objectDetector = ObjectDetection.getClient(customObjectDetectorOptions);
আপনার কাছে রিমোট-হোস্টেড মডেল থাকলে, সেটি চালানোর আগে আপনাকে চেক করে দেখতে হবে যে সেটি ডাউনলোড করা হয়েছে কিনা।
যদিও ডিটেক্টর চালানোর আগে আপনাকে এটি একবারই কনফার্ম করতে হবে, তবে আপনার কাছে রিমোট হোস্টেড মডেল ও লোকালি বান্ডেল করা মডেল, দুটিই থাকলে, ইমেজ ডিটেক্টর ইনস্ট্যানশিয়েট করার সময় এই চেকটি করলে ভালো হয়: রিমোট মডেল ডাউনলোড করা হয়ে থাকলে সেটি থেকে ডিটেক্টর তৈরি করুন, না হলে লোকাল মডেল থেকে তৈরি করুন।
Kotlin
val modelFile = File(context.cacheDir, "my_remote_model.tflite") val model = if (modelFile.exists()) { // Use the downloaded model if available LocalModel.Builder().setAbsoluteFilePath(modelFile.absolutePath).build() } else { // Fall back to the bundled model LocalModel.Builder().setAssetFilePath("model.tflite").build() } val customObjectDetectorOptions = CustomObjectDetectorOptions.Builder(model) .setDetectorMode(CustomObjectDetectorOptions.SINGLE_IMAGE_MODE) .enableClassification() .setClassificationConfidenceThreshold(0.5f) .setMaxPerObjectLabelCount(3) .build() val objectDetector = ObjectDetection.getClient(customObjectDetectorOptions)
Java
File modelFile = new File(context.getCacheDir(), "my_remote_model.tflite"); LocalModel model; if (modelFile.exists()) { // Use the downloaded model if available model = new LocalModel.Builder().setAbsoluteFilePath(modelFile.getAbsolutePath()).build(); } else { // Fall back to the bundled model model = new LocalModel.Builder().setAssetFilePath("model.tflite").build(); } CustomObjectDetectorOptions customObjectDetectorOptions = new CustomObjectDetectorOptions.Builder(model) .setDetectorMode(CustomObjectDetectorOptions.SINGLE_IMAGE_MODE) .enableClassification() .setClassificationConfidenceThreshold(0.5f) .setMaxPerObjectLabelCount(3) .build(); ObjectDetector objectDetector = ObjectDetection.getClient(customObjectDetectorOptions);
আপনার কাছে শুধুমাত্র রিমোট-হোস্টেড মডেল থাকলে, মডেল-সম্পর্কিত কার্যকারিতা বন্ধ করে দেওয়া উচিত—যেমন, আপনার UI-এর অংশ গ্রে-আউট বা লুকানো—যতক্ষণ না আপনি নিশ্চিত করছেন যে মডেলটি ডাউনলোড করা হয়েছে।
Kotlin
val localFile = File(context.cacheDir, "my_remote_model.tflite") if (localFile.exists()) { // Model is already cached, initialize immediately initializeDetector(localFile) } else { // Model is not yet available, show loading UI and start download showLoadingUI() val storage = Firebase.storage val modelRef = storage.getReferenceFromUrl("gs://YOUR_BUCKET/path/to/model.tflite") modelRef.getFile(localFile) .addOnSuccessListener { // Download complete, initialize the detector hideLoadingUI() initializeDetector(localFile) } .addOnFailureListener { // Handle download error showErrorUI() } } private fun initializeDetector(modelFile: File) { val localModel = LocalModel.Builder().setAbsoluteFilePath(modelFile.absolutePath).build() val customObjectDetectorOptions = CustomObjectDetectorOptions.Builder(localModel) .setDetectorMode(CustomObjectDetectorOptions.SINGLE_IMAGE_MODE) .enableClassification() .build() val objectDetector = ObjectDetection.getClient(customObjectDetectorOptions) // Enable ML-related UI features here enableMLFeatures(objectDetector) }
Java
File localFile = new File(context.getCacheDir(), "my_remote_model.tflite"); if (localFile.exists()) { // Model is already cached, initialize immediately initializeDetector(localFile); } else { // Model is not yet available, show loading UI and start download showLoadingUI(); FirebaseStorage storage = FirebaseStorage.getInstance(); StorageReference modelRef = storage.getReferenceFromUrl("gs://YOUR_BUCKET/path/to/model.tflite"); modelRef.getFile(localFile) .addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() { @Override public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) { // Download complete, initialize the detector hideLoadingUI(); initializeDetector(localFile); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { // Handle download error showErrorUI(); } }); } private void initializeDetector(File modelFile) { LocalModel localModel = new LocalModel.Builder().setAbsoluteFilePath(modelFile.getAbsolutePath()).build(); CustomObjectDetectorOptions customObjectDetectorOptions = new CustomObjectDetectorOptions.Builder(localModel) .setDetectorMode(CustomObjectDetectorOptions.SINGLE_IMAGE_MODE) .enableClassification() .build(); ObjectDetector objectDetector = ObjectDetection.getClient(customObjectDetectorOptions); // Enable ML-related UI features here enableMLFeatures(objectDetector); }
৩. ইনপুট ছবি প্রস্তুত করুন
আপনার ছবি থেকেInputImage অবজেক্ট তৈরি করুন।
অবজেক্ট ডিটেক্টর সরাসরি Bitmap, NV21 ByteBuffer বা
YUV_420_888 media.Image থেকে রান করে। আপনার যদি সেগুলির মধ্যে কোনও একটিতে সরাসরি অ্যাক্সেস থাকে, তাহলে সেই সোর্স থেকে InputImage তৈরি করা
সাজেস্ট করা হয়। আপনি অন্য সোর্স থেকে
InputImage তৈরি করলে, আমরা ইন্টার্নালি আপনার জন্য
কনভার্সন ম্যানেজ করব এবং এটি কম দক্ষ হতে পারে।
আপনি বিভিন্ন সোর্স থেকে InputImage
অবজেক্ট তৈরি করতে পারবেন, নিচে প্রতিটি সোর্স সম্পর্কে ব্যাখ্যা করা হয়েছে।
media.Image ব্যবহার করে
media.Image অবজেক্ট থেকে InputImage
অবজেক্ট তৈরি করতে, যেমন, আপনি কোনও
ডিভাইসের ক্যামেরা থেকে ছবি ক্যাপচার করলে, InputImage.fromMediaImage()-এ media.Image অবজেক্ট ও ছবির
রোটেশন পাস করুন।
আপনি যদি
CameraX লাইব্রেরি ব্যবহার করেন, তাহলে OnImageCapturedListener এবং
ImageAnalysis.Analyzer ক্লাস আপনার জন্য রোটেশন ভ্যালু
গণনা করে।
Kotlin
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 // ... } } }
Java
private class YourAnalyzer implements ImageAnalysis.Analyzer { @Override public void analyze(ImageProxy imageProxy) { Image mediaImage = imageProxy.getImage(); if (mediaImage != null) { InputImage image = InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees()); // Pass image to an ML Kit Vision API // ... } } }
আপনি যদি এমন কোনও ক্যামেরা লাইব্রেরি ব্যবহার না করেন যা আপনাকে ছবির ঘূর্ণনের ডিগ্রি দেয়, তাহলে আপনি ডিভাইসের ঘূর্ণনের ডিগ্রি এবং ডিভাইসে ক্যামেরা সেন্সরের ওরিয়েন্টেশন থেকে এটি গণনা করতে পারেন:
Kotlin
private val ORIENTATIONS = SparseIntArray() init { ORIENTATIONS.append(Surface.ROTATION_0, 0) ORIENTATIONS.append(Surface.ROTATION_90, 90) ORIENTATIONS.append(Surface.ROTATION_180, 180) ORIENTATIONS.append(Surface.ROTATION_270, 270) } /** * 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, isFrontFacing: Boolean): 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) // Get the device's sensor orientation. val cameraManager = activity.getSystemService(CAMERA_SERVICE) as CameraManager val sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION)!! if (isFrontFacing) { rotationCompensation = (sensorOrientation + rotationCompensation) % 360 } else { // back-facing rotationCompensation = (sensorOrientation - rotationCompensation + 360) % 360 } return rotationCompensation }
Java
private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 0); ORIENTATIONS.append(Surface.ROTATION_90, 90); ORIENTATIONS.append(Surface.ROTATION_180, 180); ORIENTATIONS.append(Surface.ROTATION_270, 270); } /** * 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, boolean isFrontFacing) 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); // Get the device's sensor orientation. CameraManager cameraManager = (CameraManager) activity.getSystemService(CAMERA_SERVICE); int sensorOrientation = cameraManager .getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SENSOR_ORIENTATION); if (isFrontFacing) { rotationCompensation = (sensorOrientation + rotationCompensation) % 360; } else { // back-facing rotationCompensation = (sensorOrientation - rotationCompensation + 360) % 360; } return rotationCompensation; }
তারপরে, media.Image অবজেক্ট এবং
InputImage.fromMediaImage()-এ রোটেশন ডিগ্রি ভ্যালু পাস করুন:
Kotlin
val image = InputImage.fromMediaImage(mediaImage, rotation)
Java
InputImage image = InputImage.fromMediaImage(mediaImage, rotation);
ফাইল URI ব্যবহার করা
ফাইল URI থেকে InputImage
অবজেক্ট তৈরি করতে, অ্যাপ কনটেক্সট ও ফাইল URI-কে
InputImage.fromFilePath()-এ পাস করুন। আপনি যখন
ACTION_GET_CONTENT ইনটেন্ট ব্যবহার করে ব্যবহারকারীকে তার গ্যালারি অ্যাপ থেকে
ছবি বেছে নিতে প্রম্পট করেন, তখন এটি কাজে লাগে।
Kotlin
val image: InputImage try { image = InputImage.fromFilePath(context, uri) } catch (e: IOException) { e.printStackTrace() }
Java
InputImage image; try { image = InputImage.fromFilePath(context, uri); } catch (IOException e) { e.printStackTrace(); }
ByteBuffer বা ByteArray ব্যবহার করে
ByteBuffer বা ByteArray থেকে InputImage
অবজেক্ট তৈরি করতে, প্রথমে media.Image ইনপুটের জন্য আগে বর্ণনা করা পদ্ধতি অনুযায়ী ছবির
রোটেশন ডিগ্রি গণনা করুন।
তারপর, বাফার বা অ্যারে সহ InputImage অবজেক্ট তৈরি করুন, এর সাথে ছবির
উচ্চতা, প্রস্থ, কালার এনকোডিং ফর্ম্যাট এবং রোটেশন ডিগ্রি যোগ করুন:
Kotlin
val image = InputImage.fromByteBuffer( byteBuffer, /* image width */ 480, /* image height */ 360, rotationDegrees, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 ) // Or: val image = InputImage.fromByteArray( byteArray, /* image width */ 480, /* image height */ 360, rotationDegrees, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 )
Java
InputImage image = InputImage.fromByteBuffer(byteBuffer, /* image width */ 480, /* image height */ 360, rotationDegrees, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 ); // Or: InputImage image = InputImage.fromByteArray( byteArray, /* image width */480, /* image height */360, rotation, InputImage.IMAGE_FORMAT_NV21 // or IMAGE_FORMAT_YV12 );
Bitmap ব্যবহার করা
Bitmap অবজেক্ট থেকে InputImage
অবজেক্ট তৈরি করতে, নিম্নলিখিত ঘোষণা করুন:
Kotlin
val image = InputImage.fromBitmap(bitmap, 0)
Java
InputImage image = InputImage.fromBitmap(bitmap, rotationDegree);
ছবিটি Bitmap অবজেক্টের মাধ্যমে উপস্থাপন করা হয়, এর সাথে ঘোরানোর ডিগ্রিও থাকে।
৪. অবজেক্ট ডিটেক্টর রান করুন
Kotlin
objectDetector .process(image) .addOnFailureListener(e -> {...}) .addOnSuccessListener(results -> { for (detectedObject in results) { // ... } });
Java
objectDetector .process(image) .addOnFailureListener(e -> {...}) .addOnSuccessListener(results -> { for (DetectedObject detectedObject : results) { // ... } });
৫. লেবেল করা অবজেক্ট সম্পর্কে তথ্য পান
process()-এ কল করা সফল হলে, DetectedObject-এর একটি তালিকা
সাকসেস লিসেনারে পাস করা হয়।
প্রতিটি DetectedObject-এ নিম্নলিখিত প্রপার্টি থাকে:
| বাউন্ডিং বক্স | একটি Rect যা ছবিতে অবজেক্টের অবস্থান
নির্দেশ করে। |
||||||
| ট্র্যাকিং আইডি | একটি পূর্ণসংখ্যা যা একাধিক ছবি জুড়ে অবজেক্টকে শনাক্ত করে। SINGLE_IMAGE_MODE-এ Null। | ||||||
| লেবেল |
|
Kotlin
// The list of detected objects contains one item if multiple // object detection wasn't enabled. for (detectedObject in results) { val boundingBox = detectedObject.boundingBox val trackingId = detectedObject.trackingId for (label in detectedObject.labels) { val text = label.text val index = label.index val confidence = label.confidence } }
Java
// The list of detected objects contains one item if multiple // object detection wasn't enabled. for (DetectedObject detectedObject : results) { Rect boundingBox = detectedObject.getBoundingBox(); Integer trackingId = detectedObject.getTrackingId(); for (Label label : detectedObject.getLabels()) { String text = label.getText(); int index = label.getIndex(); float confidence = label.getConfidence(); } }
ব্যবহারকারীর দুর্দান্ত অভিজ্ঞতা নিশ্চিত করা
ব্যবহারকারীর সেরা অভিজ্ঞতার জন্য, আপনার অ্যাপে এইসব নির্দেশিকা অনুসরণ করুন:
- অবজেক্টের ভিজ্যুয়াল জটিলতার উপর নির্ভর করে অবজেক্ট ডিটেকশন সফল হয়। শনাক্ত করার জন্য, অল্প সংখ্যক ভিজ্যুয়াল ফিচার সহ অবজেক্টকে ছবির একটি বড় অংশ জুড়ে থাকতে হতে পারে। আপনি যে ধরনের অবজেক্ট শনাক্ত করতে চান, সেগুলির সাথে ভালভাবে কাজ করে এমন ইনপুট ক্যাপচার করার বিষয়ে ব্যবহারকারীদের নির্দেশিকা প্রদান করা উচিত।
- শ্রেণীবিভাগ ব্যবহার করার সময়, আপনি যদি এমন অবজেক্ট শনাক্ত করতে চান যা সমর্থিত বিভাগের মধ্যে পড়ে না, তাহলে অজানা অবজেক্টের জন্য বিশেষ হ্যান্ডলিং প্রয়োগ করুন।
এছাড়াও, ML Kit মেটেরিয়াল ডিজাইন শোকেস অ্যাপ এবং মেটেরিয়াল ডিজাইন মেশিন লার্নিং-পরিচালিত ফিচারের জন্য প্যাটার্ন কালেকশন দেখুন।
পারফর্ম্যান্স উন্নত করা
আপনি যদি রিয়েল-টাইম অ্যাপ্লিকেশনে অবজেক্ট শনাক্তকরণ ব্যবহার করতে চান, তাহলে সেরা ফ্রেমরেট পেতে এইসব নির্দেশিকা অনুসরণ করুন:রিয়েল-টাইম অ্যাপ্লিকেশনে স্ট্রিমিং মোড ব্যবহার করার সময়, একাধিক অবজেক্ট ডিটেকশন ব্যবহার করবেন না, কারণ বেশিরভাগ ডিভাইস পর্যাপ্ত ফ্রেমরেট তৈরি করতে পারবে না।
- আপনি
Cameraবাcamera2API ব্যবহার করলে, ডিটেক্টরে কল থ্রটল করুন। ডিটেক্টর চলাকালীন নতুন ভিডিও ফ্রেম উপলভ্য হলে, ফ্রেমটি ড্রপ করুন। উদাহরণ হিসেবে কুইকস্টার্ট স্যাম্পেল অ্যাপেVisionProcessorBaseক্লাস দেখুন। - আপনি
CameraXAPI ব্যবহার করলে, ব্যাকপ্রেশার স্ট্র্যাটেজি যাতে ডিফল্ট ভ্যালুতে সেট করা থাকে তা নিশ্চিত করুনImageAnalysis.STRATEGY_KEEP_ONLY_LATEST. এর ফলে, একবারে বিশ্লেষণের জন্য শুধুমাত্র একটি ছবিই ডেলিভার করা হবে। অ্যানালাইজার ব্যস্ত থাকাকালীন আরও ছবি তৈরি হলে, সেগুলি অটোমেটিক বাদ দেওয়া হবে এবং ডেলিভারির জন্য সঞ্চয় করা হবে না। ImageProxy.close() কল করে বিশ্লেষণ করা ছবি বন্ধ করে দিলে, পরবর্তী লেটেস্ট ছবি ডেলিভার করা হবে। - ইনপুট ইমেজে গ্রাফিক্স ওভারলে করার জন্য আপনি ডিটেক্টরের আউটপুট ব্যবহার করলে, প্রথমে ML Kit থেকে ফলাফল পান, তারপর ইমেজ রেন্ডার করুন
এবং একটি ধাপে ওভারলে করুন। এটি প্রতিটি ইনপুট ফ্রেমের জন্য শুধুমাত্র একবার
ডিসপ্লে সারফেসে রেন্ডার করে। উদাহরণ হিসেবে কুইকস্টার্ট স্যাম্পেল অ্যাপে
CameraSourcePreviewএবংGraphicOverlayক্লাস দেখুন। - আপনি Camera2 API ব্যবহার করলে,
ImageFormat.YUV_420_888ফর্ম্যাটে ছবি ক্যাপচার করুন। আপনি পুরনো Camera API ব্যবহার করলে,ImageFormat.NV21ফর্ম্যাটে ছবি তুলুন।