ML Kit को कोई इमेज देने पर, वह इमेज में मौजूद ज़्यादा से ज़्यादा पांच ऑब्जेक्ट की पहचान करता है. साथ ही, इमेज में हर ऑब्जेक्ट की पोज़िशन भी बताता है. वीडियो स्ट्रीम में ऑब्जेक्ट की पहचान करते समय, हर ऑब्जेक्ट का एक यूनीक आईडी होता है. इसका इस्तेमाल करके, ऑब्जेक्ट को एक फ़्रेम से दूसरे फ़्रेम तक ट्रैक किया जा सकता है.
डिटेक्ट किए गए ऑब्जेक्ट को कैटगरी में बांटने के लिए, कस्टम इमेज क्लासिफ़िकेशन मॉडल का इस्तेमाल किया जा सकता है. मॉडल के साथ काम करने की ज़रूरी शर्तों, पहले से ट्रेन किए गए मॉडल कहां मिलेंगे, और अपने मॉडल को ट्रेन करने के तरीके के बारे में जानने के लिए, ML Kit के साथ कस्टम मॉडल लेख पढ़ें.
कस्टम मॉडल को इंटिग्रेट करने के दो तरीके हैं. मॉडल को बंडल किया जा सकता है. इसके लिए, उसे अपने ऐप्लिकेशन के ऐसेट फ़ोल्डर में रखें. इसके अलावा, इसे Cloud Storage से डाइनैमिक तौर पर डाउनलोड किया जा सकता है. यहां दी गई टेबल में, दोनों विकल्पों की तुलना की गई है.
| बंडल किया गया मॉडल | होस्ट किया गया मॉडल |
|---|---|
मॉडल, आपके ऐप्लिकेशन की .ipa फ़ाइल का हिस्सा है. इससे ऐप्लिकेशन का साइज़ बढ़ जाता है. |
यह मॉडल, आपके ऐप्लिकेशन की .ipa फ़ाइल का हिस्सा नहीं है. इसे Cloud Storage पर अपलोड करके होस्ट किया जाता है. हमारा सुझाव है कि आप Firebase के लिए Cloud Storage का इस्तेमाल करें. |
| यह मॉडल तुरंत उपलब्ध हो जाता है. भले ही, Android डिवाइस ऑफ़लाइन हो | आपके ऐप्लिकेशन में, ज़रूरत के हिसाब से मॉडल डाउनलोड करने के लिए कोड शामिल होना चाहिए |
| Firebase प्रोजेक्ट की ज़रूरत नहीं है | अगर Cloud Storage for Firebase का इस्तेमाल किया जा रहा है, तो इसके लिए Firebase प्रोजेक्ट की ज़रूरत होती है. |
| मॉडल को अपडेट करने के लिए, आपको अपना ऐप्लिकेशन फिर से पब्लिश करना होगा | ऐप्लिकेशन को फिर से पब्लिश किए बिना, मॉडल के अपडेट पुश करना |
| इसमें A/B टेस्टिंग की सुविधा पहले से मौजूद नहीं होती | Firebase Remote Config की मदद से A/B टेस्टिंग |
इसे आज़माएं
- बंडल किए गए मॉडल के इस्तेमाल का उदाहरण देखने के लिए, Vision Quickstart ऐप्लिकेशन देखें. साथ ही, होस्ट किए गए मॉडल के इस्तेमाल का उदाहरण देखने के लिए, AutoML Quickstart ऐप्लिकेशन देखें.
- इस एपीआई को शुरू से लेकर आखिर तक लागू करने के लिए, मटीरियल डिज़ाइन शोकेस ऐप्लिकेशन देखें.
शुरू करने से पहले
अपने Podfile में ML Kit की लाइब्रेरी शामिल करें:
pod 'GoogleMLKit/ObjectDetectionCustom', '8.0.0'अपने प्रोजेक्ट के पॉड इंस्टॉल या अपडेट करने के बाद, Xcode प्रोजेक्ट को
.xcworkspaceका इस्तेमाल करके खोलें. ML Kit, Xcode के 13.2.1 या इसके बाद के वर्शन के साथ काम करता है.अगर आपको Cloud Storage for Firebase का इस्तेमाल करके कोई मॉडल डाउनलोड करना है, तो पक्का करें कि आपने अपने iOS प्रोजेक्ट में Firebase को जोड़ लिया हो. अगर आपने ऐसा पहले से नहीं किया है, तो ऐसा करें. मॉडल को बंडल करने पर, इसकी ज़रूरत नहीं होती.
1. मॉडल लोड करना
लोकल मॉडल सोर्स कॉन्फ़िगर करना
मॉडल को अपने ऐप्लिकेशन के साथ बंडल करने के लिए:
मॉडल फ़ाइल को अपने Xcode प्रोजेक्ट में कॉपी करें. आम तौर पर, यह फ़ाइल
.tfliteया.liteपर खत्म होती है. ऐसा करते समय,Copy bundle resourcesको चुनना न भूलें. मॉडल फ़ाइल को ऐप्लिकेशन बंडल में शामिल किया जाएगा और यह ML Kit के लिए उपलब्ध होगी.मॉडल फ़ाइल का पाथ तय करके,
LocalModelऑब्जेक्ट बनाएं:Swift
let localModel = LocalModel(path: localModelFilePath)
Objective-C
MLKLocalModel *localModel = [[MLKLocalModel alloc] initWithPath:localModelFilePath];
रिमोटली होस्ट किए गए मॉडल सोर्स को कॉन्फ़िगर करना
रिमोटली होस्ट किए गए मॉडल का इस्तेमाल करने के लिए, आपको मॉडल फ़ाइल को डिवाइस के लोकल स्टोरेज में डाउनलोड करना होगा. इसके लिए, आपको अपने ऐप्लिकेशन लॉजिक का इस्तेमाल करना होगा. इसके बाद, इसे लोकल मॉडल के तौर पर लोड करना होगा. हमारा सुझाव है कि मॉडल को होस्ट करने के लिए, Cloud Storage for Firebase का इस्तेमाल करें. लागू करने के बारे में ज़्यादा जानकारी के लिए, Firebase ML से Cloud Storage पर माइग्रेट करने से जुड़ी गाइड देखें.
2. ऑब्जेक्ट डिटेक्टर को कॉन्फ़िगर करना
मॉडल सोर्स कॉन्फ़िगर करने के बाद, अपने इस्तेमाल के उदाहरण के लिए ऑब्जेक्ट डिटेक्टर को CustomObjectDetectorOptions ऑब्जेक्ट के साथ कॉन्फ़िगर करें. इन सेटिंग को बदला जा सकता है:
| ऑब्जेक्ट डिटेक्टर की सेटिंग | |
|---|---|
| डिटेक्शन मोड |
STREAM_MODE (डिफ़ॉल्ट) | SINGLE_IMAGE_MODE
|
| एक से ज़्यादा ऑब्जेक्ट का पता लगाना और उन्हें ट्रैक करना |
false (डिफ़ॉल्ट) | true
पांच ऑब्जेक्ट तक का पता लगाना और उन्हें ट्रैक करना है या सिर्फ़ सबसे अहम ऑब्जेक्ट (डिफ़ॉल्ट). |
| ऑब्जेक्ट का वर्गीकरण करना |
false (डिफ़ॉल्ट) | true
यह तय करता है कि पता लगाए गए ऑब्जेक्ट को, दिए गए कस्टम क्लासिफ़ायर मॉडल का इस्तेमाल करके क्लासिफ़ाई करना है या नहीं. कस्टम क्लासिफ़िकेशन मॉडल का इस्तेमाल करने के लिए, आपको इसे |
| क्लासिफ़िकेशन कॉन्फ़िडेंस थ्रेशोल्ड |
पहचाने गए लेबल का कम से कम कॉन्फ़िडेंस स्कोर. अगर इसे सेट नहीं किया जाता है, तो मॉडल के मेटाडेटा में तय किए गए किसी भी क्लासिफ़ायर थ्रेशोल्ड का इस्तेमाल किया जाएगा. अगर मॉडल में कोई मेटाडेटा नहीं है या मेटाडेटा में क्लासिफ़ायर थ्रेशोल्ड के बारे में नहीं बताया गया है, तो 0.0 का डिफ़ॉल्ट थ्रेशोल्ड इस्तेमाल किया जाएगा. |
| हर ऑब्जेक्ट के लिए ज़्यादा से ज़्यादा लेबल |
डिटेक्टर, हर ऑब्जेक्ट के लिए ज़्यादा से ज़्यादा इतने लेबल दिखाएगा. अगर यह सेट नहीं है, तो डिफ़ॉल्ट वैल्यू 10 का इस्तेमाल किया जाएगा. |
अगर आपके पास सिर्फ़ स्थानीय तौर पर बंडल किया गया मॉडल है, तो अपने 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];
अगर आपके पास सिर्फ़ रिमोटली होस्ट किया गया मॉडल है, तो आपको मॉडल से जुड़ी सुविधा बंद करनी चाहिए. उदाहरण के लिए, जब तक मॉडल डाउनलोड नहीं हो जाता, तब तक अपने यूज़र इंटरफ़ेस (यूआई) के किसी हिस्से को धूसर कर दें या छिपा दें.
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]; }
ऑब्जेक्ट का पता लगाने और उसे ट्रैक करने वाले एपीआई को इन दो मुख्य इस्तेमाल के लिए ऑप्टिमाइज़ किया गया है:
- कैमरे के व्यूफ़ाइंडर में मौजूद सबसे अहम ऑब्जेक्ट का लाइव पता लगाना और उसे ट्रैक करना.
- किसी स्टैटिक इमेज में मौजूद एक से ज़्यादा ऑब्जेक्ट का पता लगाना.
इन इस्तेमाल के उदाहरणों के लिए एपीआई कॉन्फ़िगर करने के लिए:
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;
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];
4. ऑब्जेक्ट डिटेक्टर बनाना और उसे चलाना
नया ऑब्जेक्ट डिटेक्टर बनाएं:
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.
5. लेबल किए गए ऑब्जेक्ट के बारे में जानकारी पाना
अगर इमेज प्रोसेसर को कॉल करने का अनुरोध पूरा हो जाता है, तो यह पूरा होने वाले हैंडलर को Object की सूची पास करता है या सूची दिखाता है. यह इस बात पर निर्भर करता है कि आपने एसिंक्रोनस या सिंक्रोनस तरीके को कॉल किया है या नहीं.
हर 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 का मटीरियल डिज़ाइन शोकेस ऐप्लिकेशन और मशीन लर्निंग की सुविधाओं के लिए, मटीरियल डिज़ाइन के पैटर्न कलेक्शन को भी देखें.
Improving performance
अगर आपको रीयल-टाइम ऐप्लिकेशन में ऑब्जेक्ट का पता लगाने की सुविधा का इस्तेमाल करना है, तो सबसे अच्छे फ़्रेमरेट पाने के लिए, इन दिशा-निर्देशों का पालन करें:रीयल-टाइम ऐप्लिकेशन में स्ट्रीमिंग मोड का इस्तेमाल करते समय, एक साथ कई ऑब्जेक्ट का पता लगाने की सुविधा का इस्तेमाल न करें. ऐसा इसलिए, क्योंकि ज़्यादातर डिवाइसों पर फ़्रेमरेट सही नहीं मिल पाएगा.
- वीडियो फ़्रेम प्रोसेस करने के लिए, डिटेक्टर के
results(in:)सिंक्रोनस एपीआई का इस्तेमाल करें. दिए गए वीडियो फ़्रेम से नतीजे पाने के लिए, इस तरीके कोAVCaptureVideoDataOutputSampleBufferDelegateकेcaptureOutput(_, didOutput:from:)फ़ंक्शन से कॉल करें. डिटेक्टर को कॉल करने की फ़्रीक्वेंसी कम करने के लिए,AVCaptureVideoDataOutputकेalwaysDiscardsLateVideoFramesकोtrueके तौर पर सेट करें. अगर डिटेक्टर के चालू होने के दौरान कोई नया वीडियो फ़्रेम उपलब्ध होता है, तो उसे छोड़ दिया जाएगा. - अगर आपको इनपुट इमेज पर ग्राफ़िक ओवरले करने के लिए, डिटेक्टर के आउटपुट का इस्तेमाल करना है, तो पहले ML Kit से नतीजे पाएं. इसके बाद, इमेज रेंडर करें और उसे एक ही चरण में ओवरले करें. ऐसा करने से, आपको प्रोसेस किए गए हर इनपुट फ़्रेम के लिए, डिसप्ले सर्फ़ेस पर सिर्फ़ एक बार रेंडर करना होगा. उदाहरण के लिए, ML Kit के क्विकस्टार्ट सैंपल में updatePreviewOverlayViewWithLastFrame देखें.