আপনি ML Kit-এ কোনও ছবি দিলে, এটি ছবিতে সর্বাধিক পাঁচটি অবজেক্ট শনাক্ত করে এবং ছবির মধ্যে প্রতিটি অবজেক্টের অবস্থানও শনাক্ত করে। ভিডিও স্ট্রিমে অবজেক্ট শনাক্ত করার সময়, প্রতিটি অবজেক্টের একটি অনন্য আইডি থাকে যা আপনি ফ্রেম থেকে ফ্রেমে অবজেক্ট ট্র্যাক করতে ব্যবহার করতে পারেন।
শনাক্ত করা অবজেক্টকে শ্রেণীবদ্ধ করতে আপনি কাস্টম ইমেজ ক্লাসিফিকেশন মডেল ব্যবহার করতে পারেন। মডেলের উপযুক্ততা সংক্রান্ত প্রয়োজনীয়তা, আগে থেকে ট্রেনিং দেওয়া মডেল কোথায় পাবেন এবং কীভাবে আপনার নিজস্ব মডেলকে ট্রেনিং দেবেন সেই সম্পর্কে নির্দেশিকা পেতে, ML Kit সহ কাস্টম মডেল দেখুন।
কাস্টম মডেল ইন্টিগ্রেট করার দুটি উপায় আছে। আপনি মডেলটি বান্ডেল করতে পারেন, এর জন্য আপনার অ্যাপের অ্যাসেট ফোল্ডারের মধ্যে এটি রাখুন অথবা আপনি Cloud Storage থেকে এটি ডায়নামিক ডাউনলোড করতে পারেন। নিম্নলিখিত সারণীতে দুটি বিকল্পের তুলনা করা হয়েছে।
| বান্ডেল করা মডেল | হোস্ট করা মডেল |
|---|---|
মডেলটি আপনার অ্যাপের .ipa ফাইলের অংশ, যা
এর সাইজ বাড়ায়। |
মডেলটি আপনার অ্যাপের .ipa ফাইলের অংশ নয়। এটি Cloud Storage-এ আপলোড করে
হোস্ট করা হয়। আমরা
Firebase-এর জন্য
Cloud Storage ব্যবহার করার সাজেশন দিই। |
| Android ডিভাইস অফলাইনে থাকলেও, মডেলটি অবিলম্বে উপলভ্য হয় | চাহিদা অনুযায়ী মডেল ডাউনলোড করার কোড আপনার অ্যাপে থাকতে হবে |
| Firebase প্রোজেক্টের প্রয়োজন নেই | Firebase প্রোজেক্ট প্রয়োজন (Firebase-এর জন্য Cloud Storage ব্যবহার করলে)। |
| মডেল আপডেট করতে আপনাকে অবশ্যই অ্যাপ আবার প্রকাশ করতে হবে | আপনার অ্যাপ আবার প্রকাশ না করেই মডেল আপডেট পুশ করা |
| কোনও বিল্ট-ইন A/B টেস্টিং নেই | Firebase রিমোট কনফিগ-এর সাথে A/B টেস্টিং |
এটি ব্যবহার করে দেখুন
- বান্ডেল করা মডেলের ব্যবহারের উদাহরণ দেখতে ভিশন কুইকস্টার্ট অ্যাপ এবং হোস্ট করা মডেলের ব্যবহারের উদাহরণ দেখতে automl কুইকস্টার্ট অ্যাপ দেখুন।
- এই API-এর এন্ড-টু-এন্ড প্রয়োগের জন্য মেটেরিয়াল ডিজাইন শোকেস অ্যাপ দেখুন।
শুরু করার আগে
আপনার Podfile-এ ML Kit লাইব্রেরি অন্তর্ভুক্ত করুন:
pod 'GoogleMLKit/ObjectDetectionCustom', '8.0.0'আপনার প্রোজেক্টের Pods ইনস্টল বা আপডেট করার পরে,
.xcworkspaceব্যবহার করে আপনার Xcode প্রোজেক্ট খুলুন। ML Kit, Xcode ভার্সন 13.2.1 বা তার পরবর্তী যেকোনও ভার্সনে কাজ করে।আপনি Firebase-এর জন্য Cloud Storage ব্যবহার করে কোনও মডেল ডাউনলোড করতে চাইলে, নিশ্চিত করুন যে আপনি iOS প্রোজেক্টে Firebase যোগ করেছেন, যদি আগে থেকে এটি না করে থাকেন। আপনি মডেল বান্ডেল করলে এটি প্রয়োজন হয় না।
১. মডেল লোড করুন
স্থানীয় মডেল সোর্স কনফিগার করুন
আপনার অ্যাপের সাথে মডেল বান্ডেল করতে:
আপনার Xcode প্রোজেক্টে মডেল ফাইল (সাধারণত
.tfliteবা.liteদিয়ে শেষ হয়) কপি করুন, এটি করার সময়Copy bundle resourcesবেছে নিতে ভুলবেন না। মডেল ফাইলটি অ্যাপ বান্ডেলে অন্তর্ভুক্ত করা হবে এবং ML Kit-এর জন্য উপলভ্য হবে।মডেল ফাইলের পাথ উল্লেখ করে
LocalModelঅবজেক্ট তৈরি করুন:Swift
let localModel = LocalModel(path: localModelFilePath)
Objective-C
MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:localModelFilePath];
রিমোট লোকেশন থেকে হোস্ট করা মডেল সোর্স কনফিগার করুন
রিমোটলি-হোস্ট করা মডেল ব্যবহার করতে, আপনাকে অবশ্যই নিজের অ্যাপ লজিক ব্যবহার করে ডিভাইসের লোকাল স্টোরেজে মডেল ফাইল ডাউনলোড করতে হবে এবং তারপরে এটি লোকাল মডেল হিসেবে লোড করতে হবে। মডেল হোস্ট করার জন্য Firebase-এর জন্য Cloud Storage ব্যবহার করার সাজেশন দিই। প্রয়োগ সংক্রান্ত বিবরণের জন্য, Firebase ML থেকে Cloud Storage-এ মাইগ্রেশন গাইড দেখুন।
২. অবজেক্ট ডিটেক্টর কনফিগার করা
আপনার মডেল সোর্স কনফিগার করার পরে, CustomObjectDetectorOptions অবজেক্ট সহ আপনার ব্যবহারের ক্ষেত্রে অবজেক্ট ডিটেক্টর কনফিগার করুন। আপনি নিম্নলিখিত সেটিংস
পরিবর্তন করতে পারবেন:
| অবজেক্ট ডিটেক্টর সেটিংস | |
|---|---|
| শনাক্তকরণ মোড |
STREAM_MODE (ডিফল্ট) | SINGLE_IMAGE_MODE
|
| একাধিক অবজেক্ট শনাক্ত ও ট্র্যাক করুন |
false (ডিফল্ট) | true
পাঁচটি পর্যন্ত অবজেক্ট নাকি শুধুমাত্র সবচেয়ে বিশিষ্ট অবজেক্ট (ডিফল্ট) শনাক্ত ও ট্র্যাক করা হবে কিনা। |
| অবজেক্ট শ্রেণীবদ্ধ করা |
false (ডিফল্ট) | true
প্রদত্ত কাস্টম ক্লাসিফায়ার মডেল ব্যবহার করে শনাক্ত করা অবজেক্টকে শ্রেণীবদ্ধ করা হবে কিনা। আপনার কাস্টম ক্লাসিফিকেশন মডেল ব্যবহার করতে, আপনাকে এটি |
| শ্রেণীবিভাগের কনফিডেন্স থ্রেশহোল্ড |
শনাক্ত করা লেবেলের ন্যূনতম কনফিডেন্স স্কোর। সেট করা না থাকলে, মডেলের মেটাডেটা দ্বারা নির্দিষ্ট করা যেকোনও ক্লাসিফায়ার থ্রেশহোল্ড ব্যবহার করা হবে। মডেলে কোনও মেটাডেটা না থাকলে বা মেটাডেটায় ক্লাসিফায়ার থ্রেশহোল্ড নির্দিষ্ট করা না থাকলে, ডিফল্ট থ্রেশহোল্ড হিসেবে 0.0 ব্যবহার করা হবে। |
| অবজেক্ট পিছু সর্বাধিক লেবেল |
ডিটেক্টর প্রতিটি অবজেক্টের জন্য সর্বাধিক যতগুলি লেবেল ফেরত দেবে। সেট করা না থাকলে, ডিফল্ট ভ্যালু হিসেবে ১০ ব্যবহার করা হবে। |
আপনার কাছে শুধুমাত্র লোকালি-বান্ডেল করা মডেল থাকলে, আপনার LocalModel অবজেক্ট থেকে
একটি অবজেক্ট ডিটেক্টর তৈরি করুন:
Swift
let options = CustomObjectDetectorOptions(localModel: localModel) options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true options.classificationConfidenceThreshold = NSNumber(value: 0.5) options.maxPerObjectLabelCount = 3
Objective-C
MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; options.classificationConfidenceThreshold = @(0.5); options.maxPerObjectLabelCount = 3;
আপনার কাছে রিমোটলি-হোস্ট করা মডেল থাকলে, সেটি চালানোর আগে ডাউনলোড করা হয়েছে কিনা তা আপনাকে চেক করতে হবে।
অবজেক্ট ডিটেক্টর চালানোর আগে আপনাকে শুধু এটি কনফার্ম করতে হবে, তবে
আপনার কাছে রিমোটলি-হোস্ট করা মডেল এবং লোকালি-বান্ডেল করা মডেল, দুটিই থাকলে,
ObjectDetector ইনস্ট্যান্টিয়েট করার সময় এই চেকটি করা যুক্তিযুক্ত হতে পারে: রিমোট মডেল থেকে
একটি ডিটেক্টর তৈরি করুন যদি এটি ডাউনলোড করা থাকে, অন্যথায় লোকাল মডেল থেকে
তৈরি করুন।
Swift
// Path where your download logic saves the model let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let localModelURL = documentDirectory.appendingPathComponent("my_remote_model.tflite") let model: LocalModel if FileManager.default.fileExists(atPath: localModelURL.path) { // Use the downloaded model model = LocalModel(path: localModelURL.path) } else { // Fall back to bundled model guard let bundledModelPath = Bundle.main.path(forResource: "model", ofType: "tflite") else { return } model = LocalModel(path: bundledModelPath) } let options = CustomObjectDetectorOptions(localModel: model) options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true options.classificationConfidenceThreshold = NSNumber(value: 0.5) options.maxPerObjectLabelCount = 3 let objectDetector = ObjectDetector.objectDetector(options: options)
Objective-C
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *localModelPath = [documentsDirectory stringByAppendingPathComponent:@"my_remote_model.tflite"]; MLKLocalModel *model; if ([NSFileManager.defaultManager fileExistsAtPath:localModelPath]) { // Use the downloaded model model = [[MLKLocalModel alloc] initWithPath:localModelPath]; } else { // Fall back to bundled model NSString *bundledModelPath = [NSBundle.mainBundle pathForResource:@"model" ofType:@"tflite"]; model = [[MLKLocalModel alloc] initWithPath:bundledModelPath]; } MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:model]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; options.classificationConfidenceThreshold = @(0.5); options.maxPerObjectLabelCount = 3; MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
আপনার কাছে শুধু রিমোটলি-হোস্ট করা মডেল থাকলে, মডেল ডাউনলোড হয়েছে কিনা তা কনফার্ম না করা পর্যন্ত মডেল-সম্পর্কিত কার্যকারিতা বন্ধ করে দেওয়া উচিত—যেমন, আপনার UI-এর অংশ গ্রে-আউট বা লুকিয়ে রাখা।
Swift
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let localModelURL = documentDirectory.appendingPathComponent("my_remote_model.tflite") if FileManager.default.fileExists(atPath: localModelURL.path) { // Model is already cached, initialize immediately self.initializeDetector(with: localModelURL) } else { // Model is not yet available, show loading UI and start download self.showLoadingUI() let storage = Storage.storage() let modelRef = storage.reference(forURL: "gs://YOUR_BUCKET/path/to/model.tflite") modelRef.write(toFile: localModelURL) { url, error in self.hideLoadingUI() if let error = error { // Handle download error self.showErrorUI() } else if let modelURL = url { // Download success, initialize detector self.initializeDetector(with: modelURL) } } } func initializeDetector(with modelURL: URL) { let localModel = LocalModel(path: modelURL.path) let options = CustomObjectDetectorOptions(localModel: localModel) options.detectorMode = .singleImage options.shouldEnableClassification = true options.shouldEnableMultipleObjects = true self.objectDetector = ObjectDetector.objectDetector(options: options) // Enable ML features in UI self.enableMLFeatures() }
Objective-C
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *localModelPath = [documentsDirectory stringByAppendingPathComponent:@"my_remote_model.tflite"]; NSURL *localModelURL = [NSURL fileURLWithPath:localModelPath]; if ([NSFileManager.defaultManager fileExistsAtPath:localModelPath]) { // Model is already cached, initialize immediately [self initializeDetectorWithURL:localModelURL]; } else { // Model is not yet available, show loading UI and start download [self showLoadingUI]; FIRStorage *storage = [FIRStorage storage]; FIRStorageReference *modelRef = [storage referenceForURL:@"gs://YOUR_BUCKET/path/to/model.tflite"]; [modelRef writeToFile:localModelURL completion:^(NSURL * _Nullable URL, NSError * _Nullable error) { [self hideLoadingUI]; if (error != nil) { // Handle download error [self showErrorUI]; } else { // Download success, initialize detector [self initializeDetectorWithURL:URL]; } }]; } - (void)initializeDetectorWithURL:(NSURL *)modelURL { MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:modelURL.path]; MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableClassification = YES; options.shouldEnableMultipleObjects = YES; self.objectDetector = [MLKObjectDetector objectDetectorWithOptions:options]; // Enable ML features in UI [self enableMLFeatures]; }
অবজেক্ট ডিটেকশন ও ট্র্যাকিং API এই দুটি মূল ব্যবহারের ক্ষেত্রে অপ্টিমাইজ করা হয়েছে:
- ক্যামেরা ভিউফাইন্ডারে সবচেয়ে স্পষ্ট অবজেক্টের লাইভ শনাক্তকরণ ও ট্র্যাকিং।
- স্ট্যাটিক ছবি থেকে একাধিক অবজেক্ট শনাক্ত করা।
এইসব ব্যবহারের ক্ষেত্রে API কনফিগার করতে:
Swift
// Live detection and tracking let options = CustomObjectDetectorOptions(localModel: localModel) options.shouldEnableClassification = true options.maxPerObjectLabelCount = 3 // Multiple object detection in static images let options = CustomObjectDetectorOptions(localModel: localModel) options.detectorMode = .singleImage options.shouldEnableMultipleObjects = true options.shouldEnableClassification = true options.maxPerObjectLabelCount = 3
Objective-C
// Live detection and tracking MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.shouldEnableClassification = YES; options.maxPerObjectLabelCount = 3; // Multiple object detection in static images MLKCustomObjectDetectorOptions *options = [[MLKCustomObjectDetectorOptions alloc] initWithLocalModel:localModel]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableMultipleObjects = YES; options.shouldEnableClassification = YES; options.maxPerObjectLabelCount = 3;
৩. ইনপুট ছবি প্রস্তুত করা
UIImage বা CMSampleBuffer ব্যবহার করে
VisionImage অবজেক্ট তৈরি করুন।
আপনি UIImage ব্যবহার করলে, এইসব ধাপ অনুসরণ করুন:
UIImage-এর সাহায্যেVisionImageঅবজেক্ট তৈরি করুন। সঠিক.orientationউল্লেখ করতে ভুলবেন না।Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
আপনি CMSampleBuffer ব্যবহার করলে, এইসব ধাপ অনুসরণ করুন:
-
CMSampleBuffer-এ থাকা ইমেজ ডেটার ওরিয়েন্টেশন নির্দিষ্ট করুন।ছবির ওরিয়েন্টেশন পেতে:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
CMSampleBufferঅবজেক্ট ও ওরিয়েন্টেশন ব্যবহার করেVisionImageঅবজেক্ট তৈরি করুন:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
৪. অবজেক্ট ডিটেক্টর তৈরি ও রান করা
নতুন অবজেক্ট ডিটেক্টর তৈরি করুন:
Swift
let objectDetector = ObjectDetector.objectDetector(options: options)
Objective-C
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
তারপর, ডিটেক্টর ব্যবহার করুন:
অ্যাসিঙ্ক্রোনাসভাবে:
Swift
objectDetector.process(image) { objects, error in guard error == nil, let objects = objects, !objects.isEmpty else { // Handle the error. return } // Show results. }
Objective-C
[objectDetector processImage:image completion:^(NSArray
*_Nullable objects, NSError *_Nullable error) { if (objects.count == 0) { // Handle the error. return; } // Show results. }]; সিঙ্ক্রোনাস:
Swift
var objects: [Object] do { objects = try objectDetector.results(in: image) } catch let error { // Handle the error. return } // Show results.
Objective-C
NSError *error; NSArray
*objects = [objectDetector resultsInImage:image error:&error]; // Show results or handle the error.
৫. লেবেল করা অবজেক্ট সম্পর্কে তথ্য পাওয়া
ইমেজ প্রসেসরের কল সফল হলে, এটি হয় সম্পূর্ণতা হ্যান্ডলারে
Objects-এর একটি তালিকা পাস করে অথবা আপনি অ্যাসিঙ্ক্রোনাস বা সিঙ্ক্রোনাস পদ্ধতি কল করেছেন কিনা তার উপর নির্ভর করে
তালিকাটি ফেরত দেয়।
প্রতিটি Object-এ নিম্নলিখিত প্রপার্টি থাকে:
frame |
একটি CGRect যা ছবিতে অবজেক্টের অবস্থান
নির্দেশ করে। |
||||||
trackingID |
একটি পূর্ণসংখ্যা যা একাধিক ছবি জুড়ে অবজেক্টকে শনাক্ত করে অথবা SINGLE_IMAGE_MODE-এ `nil`। | ||||||
labels |
|
Swift
// objects contains one item if multiple object detection wasn't enabled. for object in objects { let frame = object.frame let trackingID = object.trackingID let description = object.labels.enumerated().map { (index, label) in "Label \(index): \(label.text), \(label.confidence), \(label.index)" }.joined(separator: "\n") }
Objective-C
// The list of detected objects contains one item if multiple object detection // wasn't enabled. for (MLKObject *object in objects) { CGRect frame = object.frame; NSNumber *trackingID = object.trackingID; for (MLKObjectLabel *label in object.labels) { NSString *labelString = [NSString stringWithFormat:@"%@, %f, %lu", label.text, label.confidence, (unsigned long)label.index]; } }
ব্যবহারকারীর দুর্দান্ত অভিজ্ঞতা নিশ্চিত করা
ব্যবহারকারীর সেরা অভিজ্ঞতার জন্য, আপনার অ্যাপে এইসব নির্দেশিকা অনুসরণ করুন:
- অবজেক্টের ভিজ্যুয়াল জটিলতার উপর নির্ভর করে অবজেক্ট ডিটেকশন কতটা সফল হবে। শনাক্ত করার জন্য, অল্প সংখ্যক ভিজ্যুয়াল ফিচার সহ অবজেক্টকে ছবির একটি বড় অংশ জুড়ে থাকতে হতে পারে। আপনি যে ধরনের অবজেক্ট শনাক্ত করতে চান, সেগুলির সাথে ভালভাবে কাজ করে এমন ইনপুট ক্যাপচার করার বিষয়ে ব্যবহারকারীদের নির্দেশিকা প্রদান করা উচিত।
- আপনি শ্রেণীবিভাগ ব্যবহার করার সময়, যদি এমন অবজেক্ট শনাক্ত করতে চান যা স্পষ্টভাবে সাপোর্ট করা বিভাগে পড়ে না, তাহলে অজানা অবজেক্টের জন্য বিশেষ হ্যান্ডেলিং প্রয়োগ করুন।
এছাড়াও, ML Kit মেটেরিয়াল ডিজাইন শোকেস অ্যাপ এবং মেটেরিয়াল ডিজাইন মেশিন লার্নিং-পরিচালিত ফিচারের জন্য প্যাটার্ন কালেকশন দেখুন।
পারফর্ম্যান্স উন্নত করা
আপনি যদি রিয়েল-টাইম অ্যাপ্লিকেশনে অবজেক্ট ডিটেকশন ব্যবহার করতে চান, তাহলে সেরা ফ্রেমরেট পেতে এই নির্দেশিকা অনুসরণ করুন:আপনি রিয়েল-টাইম অ্যাপ্লিকেশনে স্ট্রিমিং মোড ব্যবহার করলে, একাধিক অবজেক্ট শনাক্তকরণ ব্যবহার করবেন না, কারণ বেশিরভাগ ডিভাইস পর্যাপ্ত ফ্রেমরেট তৈরি করতে পারবে না।
- ভিডিও ফ্রেম প্রসেস করার জন্য, ডিটেক্টরের
results(in:)সিঙ্ক্রোনাস API ব্যবহার করুন। প্রদত্ত ভিডিও ফ্রেম থেকে সিঙ্ক্রোনাসভাবে ফলাফল পেতেAVCaptureVideoDataOutputSampleBufferDelegate-এরcaptureOutput(_, didOutput:from:)ফাংশন থেকে এই পদ্ধতি কল করুন। ডিটেক্টরে কল থ্রটল করতেAVCaptureVideoDataOutput-এরalwaysDiscardsLateVideoFramestrueহিসেবে রাখুন। ডিটেক্টর চলাকালীন নতুন ভিডিও ফ্রেম উপলভ্য হলে, সেটি বাদ দেওয়া হবে। - ইনপুট ইমেজে গ্রাফিক্স ওভারলে করার জন্য আপনি ডিটেক্টরের আউটপুট ব্যবহার করলে, প্রথমে ML Kit থেকে ফলাফল পান, তারপর ইমেজ রেন্ডার করুন এবং একটি ধাপে ওভারলে করুন। এটি করলে, আপনি প্রতিটি প্রসেস করা ইনপুট ফ্রেমের জন্য ডিসপ্লে সারফেসে শুধুমাত্র একবার রেন্ডার করেন। উদাহরণ হিসেবে ML Kit কুইকস্টার্ট স্যাম্পেলে updatePreviewOverlayViewWithLastFrame দেখুন।