आप एमएल किट का इस्तेमाल करके, लगातार वीडियो फ़्रेम में चीज़ों का पता लगा सकते हैं और उन्हें ट्रैक कर सकते हैं.
जब आप किसी इमेज को एमएल किट में भेजते हैं, तो वह इमेज में पांच ऑब्जेक्ट के साथ-साथ, हर इमेज की जगह की जानकारी का पता लगाती है. वीडियो स्ट्रीम में ऑब्जेक्ट का पता लगाते समय, हर ऑब्जेक्ट का एक यूनीक आईडी होता है. इसका इस्तेमाल, फ़्रेम से फ़्रेम तक ऑब्जेक्ट को ट्रैक करने के लिए किया जा सकता है. इसके अलावा, तभी बुनियादी ऑब्जेक्ट की कैटगरी तय करने की सुविधा भी चालू की जा सकती है, जो ऑब्जेक्ट को बड़े दायरे वाली जानकारी के साथ लेबल करती है.
इसे आज़माएं
- इस एपीआई के इस्तेमाल का उदाहरण देखने के लिए, ऐप्लिकेशन के नमूने का इस्तेमाल करें.
- इस एपीआई को शुरू से लेकर आखिर तक लागू करने के लिए, मटीरियल डिज़ाइन शोकेस ऐप्लिकेशन देखें.
शुरू करने से पहले
- अपनी Podfile में ये ML किट पॉड शामिल करें:
pod 'GoogleMLKit/ObjectDetection', '3.2.0'
- अपने प्रोजेक्ट के पॉड इंस्टॉल करने या अपडेट करने के बाद, अपने
.xcworkspace
कोड का इस्तेमाल करके Xcode प्रोजेक्ट खोलें. ML किट, Xcode के 12.4 या इसके बाद के वर्शन पर काम करती है.
1. ऑब्जेक्ट डिटेक्टर को कॉन्फ़िगर करें
ऑब्जेक्ट का पता लगाने और उन्हें ट्रैक करने के लिए, पहले ObjectDetector
का एक इंस्टेंस बनाएं और वैकल्पिक रूप से ऐसी कोई भी डिटेक्टर सेटिंग बताएं जिसे आप डिफ़ॉल्ट से बदलना चाहते हैं.
ObjectDetectorOptions
ऑब्जेक्ट के साथ, अपने इस्तेमाल के उदाहरण के लिए ऑब्जेक्ट की पहचान करने वाले को कॉन्फ़िगर करें. इन सेटिंग को बदला जा सकता है:ऑब्जेक्ट डिटेक्टर की सेटिंग वीडियो की पहचान करने वाला मोड .stream
(डिफ़ॉल्ट) |.singleImage
स्ट्रीम मोड (डिफ़ॉल्ट) में, ऑब्जेक्ट डिटेक्टर बहुत कम इंतज़ार के समय के साथ चलता है. हालांकि, हो सकता है कि पहचानने के शुरुआती कुछ अनुरोधों के समय ही, अधूरे नतीजे (जैसे कि बिना किसी सीमा के बाउंडिंग बॉक्स या कैटगरी) खुलें. साथ ही, स्ट्रीम मोड में, पहचानकर्ता ऑब्जेक्ट को ट्रैकिंग आईडी असाइन करता है. इसका इस्तेमाल फ़्रेम में मौजूद ऑब्जेक्ट को ट्रैक करने के लिए किया जा सकता है. इस मोड का इस्तेमाल तब करें, जब ऑब्जेक्ट की निगरानी करनी हो या इंतज़ार का समय कम हो. उदाहरण के लिए, रीयल टाइम में वीडियो स्ट्रीम प्रोसेस करते समय.
सिंगल इमेज मोड में, ऑब्जेक्ट की पहचान करने वाला बॉक्स, ऑब्जेक्ट को जोड़ने वाला बॉक्स तय होने के बाद नतीजे को दिखाता है. अगर आप डेटा की कैटगरी तय करने की सुविधा भी चालू करते हैं, तो बाउंडिंग बॉक्स और कैटगरी लेबल, दोनों के उपलब्ध होने के बाद यह नतीजे दिखाता है. इस वजह से, इंतज़ार का समय ज़्यादा हो सकता है. साथ ही, एक इमेज मोड में, ट्रैकिंग आईडी असाइन नहीं किए जाते. अगर इंतज़ार का समय बहुत ज़्यादा अहम नहीं है और आप कुछ खास नतीजों के साथ काम नहीं करना चाहते हैं, तो इस मोड का इस्तेमाल करें.
एक से ज़्यादा ऑब्जेक्ट का पता लगाएं और उन्हें ट्रैक करें false
(डिफ़ॉल्ट) |true
ज़्यादा से ज़्यादा पांच ऑब्जेक्ट का पता लगाकर उन्हें ट्रैक करना है या सिर्फ़ सबसे अहम ऑब्जेक्ट (डिफ़ॉल्ट) को ट्रैक करना है.
ऑब्जेक्ट की कैटगरी तय करना false
(डिफ़ॉल्ट) |true
पता लगाए गए ऑब्जेक्ट को ऊबड़-खाबड़ कैटगरी में बांटना है या नहीं. इस सुविधा के चालू होने पर, ऑब्जेक्ट की पहचान करने वाले टूल, चीज़ों को उनकी कैटगरी में बांट देता है: फ़ैशन का सामान, खाना, घर का सामान, जगहें, और पौधे.
ऑब्जेक्ट की पहचान और ट्रैकिंग एपीआई को इन दो मुख्य तरीकों से ऑप्टिमाइज़ किया गया है:
- कैमरे के व्यूफ़ाइंडर में सबसे खास चीज़ की लाइव पहचान करना और उसे ट्रैक करना.
- स्टैटिक इमेज में कई ऑब्जेक्ट की पहचान.
इस्तेमाल के इन उदाहरणों के लिए, एपीआई को कॉन्फ़िगर करने का तरीका:
Swift
// Live detection and tracking let options = ObjectDetectorOptions() options.shouldEnableClassification = true // Multiple object detection in static images let options = ObjectDetectorOptions() options.detectorMode = .singleImage options.shouldEnableMultipleObjects = true options.shouldEnableClassification = true
Objective-C
// Live detection and tracking MLKObjectDetectorOptions *options = [[MLKObjectDetectorOptions alloc] init]; options.shouldEnableClassification = YES; // Multiple object detection in static images MLKObjectDetectorOptions *options = [[MLKOptions alloc] init]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableMultipleObjects = YES; options.shouldEnableClassification = YES;
ObjectDetector
का इंस्टेंस पाएं:
Swift
let objectDetector = ObjectDetector.objectDetector() // Or, to change the default settings: let objectDetector = ObjectDetector.objectDetector(options: options)
Objective-C
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetector]; // Or, to change the default settings: MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
2. इनपुट इमेज तैयार करें
चीज़ों का पता लगाने और उन्हें ट्रैक करने के लिए, हर इमेज या वीडियो के फ़्रेम के लिए ये काम करें.
अगर आपने स्ट्रीम मोड चालू किया है, तो आपको CMSampleBuffer
से VisionImage
ऑब्जेक्ट बनाना होगा.
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];
3. इमेज को प्रोसेस करें
ऑब्जेक्ट डिटेक्टर की इमेज प्रोसेसिंग की तरीकों में से किसी एक कोVisionImage
पास करें. आप एसिंक्रोनस process(image:)
तरीके या सिंक्रोनस results()
तरीके का इस्तेमाल करें.
ऑब्जेक्ट को एसिंक्रोनस रूप से पहचानने के लिए:
Swift
objectDetector.process(image) { objects, error in guard error == nil else { // Error. return } guard !objects.isEmpty else { // No objects detected. return } // Success. Get object info here. // ... }
Objective-C
[objectDetector processImage:image completion:^(NSArray* _Nullable objects, NSError * _Nullable error) { if (error == nil) { return; } if (objects.count == 0) { // No objects detected. return; } // Success. Get object info here. }];
सिंक्रोनस रूप से ऑब्जेक्ट का पता लगाने के लिए:
Swift
var objects: [Object] do { objects = try objectDetector.results(in: image) } catch let error { print("Failed to detect object with error: \(error.localizedDescription).") return } guard !objects.isEmpty else { print("Object detector returned no results.") return } // Success. Get object info here.
Objective-C
NSError *error; NSArray*objects = [objectDetector resultsInImage:image error:&error]; if (error == nil) { return; } if (objects.count == 0) { // No objects detected. return; } // Success. Get object info here.
4. पता लगाए गए ऑब्जेक्ट के बारे में जानकारी पाएं
अगर इमेज प्रोसेसर को कॉल हो जाता है, तो यह या तो पूरा होने के हैंडलर कोObject
की सूची भेजता है या इस बात पर निर्भर करता है कि आपने एसिंक्रोनस या सिंक्रोनस तरीके को कॉल किया है या नहीं.
हर Object
में ये प्रॉपर्टी शामिल होती हैं:
frame |
CGRect , इमेज में मौजूद चीज़ की जगह बताता है. |
trackingID |
पूर्णांक, जो इमेज में दिखने वाले ऑब्जेक्ट की पहचान करता है या सिंगल इमेज मोड में `nil`. |
labels |
डिटेक्टर के लौटाए गए ऑब्जेक्ट की जानकारी देने वाले लेबल की श्रेणी.
अगर पहचानकर्ता का विकल्प shouldEnableClassification
false पर सेट है, तो प्रॉपर्टी खाली होती है.
|
Swift
// objects contains one item if multiple object detection wasn't enabled. for object in objects { let frame = object.frame let trackingID = object.trackingID // If classification was enabled: let description = object.labels.enumerated().map { (index, label) in "Label \(index): \(label.text), \(label.confidence)" }.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]; ... } }
उपयोगिता और परफ़ॉर्मेंस को बेहतर बनाना
बेहतरीन उपयोगकर्ता अनुभव के लिए, अपने ऐप्लिकेशन में इन दिशा-निर्देशों का पालन करें:
- ऑब्जेक्ट की पहचान आसान है, जो ऑब्जेक्ट की विज़ुअल जटिलता पर निर्भर करता है. ऐसे ऑब्जेक्ट, जिन्हें कुछ ही विज़ुअल सुविधाओं वाली चीज़ों का पता लगाने के लिए, इमेज के बड़े हिस्से का इस्तेमाल करने की ज़रूरत पड़ती है. आपको उपयोगकर्ताओं को इनपुट कैप्चर करने के बारे में दिशा-निर्देश देने चाहिए, जो उन ऑब्जेक्ट के साथ अच्छी तरह से काम करता है जिनका आप पता लगाना चाहते हैं.
- क्लासिफ़िकेशन का इस्तेमाल करते समय, अगर आपको ऐसी ऑब्जेक्ट की पहचान करनी है जो इसके साथ काम करने वाली कैटगरी में नहीं आती हैं, तो बिना बताए गए ऑब्जेक्ट के लिए, खास हैंडलिंग लागू करें.
साथ ही, मटीरियल डिज़ाइन मशीन लर्निंग की सुविधाओं के पैटर्न का संग्रह भी देखें.
जब आप रीयल-टाइम ऐप्लिकेशन में स्ट्रीमिंग मोड का इस्तेमाल करते हैं, तो सबसे सही फ़्रेम दर पाने के लिए, इन दिशा-निर्देशों का पालन करें:
- स्ट्रीमिंग मोड में एक से ज़्यादा चीज़ों का पता लगाने वाली सुविधा का इस्तेमाल न करें, क्योंकि ज़्यादातर डिवाइस पर फ़्रेमरेट ज़रूरी नहीं होते.
- अगर आपको डेटा क्लासिफ़िकेशन की ज़रूरत नहीं है, तो उसे बंद कर दें.
- वीडियो फ़्रेम प्रोसेस करने के लिए, डिटेक्टर के
results(in:)
सिंक्रोनस एपीआई का इस्तेमाल करें. दिए गए वीडियो फ़्रेम से सिंक्रोनस रूप से परिणाम पाने के लिएAVCaptureVideoDataOutputSampleBufferDelegate
केcaptureOutput(_, didOutput:from:)
फ़ंक्शन से इस विधि को कॉल करें.AVCaptureVideoDataOutput
कीalwaysDiscardsLateVideoFrames
कोtrue
के तौर पर रखें, ताकि डिटेक्टर को कॉल थ्रॉटल किए जा सकें. अगर डिटेक्टर चलने के दौरान नया वीडियो फ़्रेम उपलब्ध हो जाता है, तो उसे छोड़ दिया जाएगा. - अगर आप इनपुट इमेज पर ग्राफ़िक ओवरले करने के लिए डिटेक्टर के आउटपुट का इस्तेमाल करते हैं, तो पहले ML किट से नतीजा पाएं. इसके बाद, इमेज और ओवरले को एक ही चरण में रेंडर करें. ऐसा करके, आप हर प्रोसेस किए गए इनपुट फ़्रेम के लिए डिसप्ले को सिर्फ़ एक बार रेंडर करते हैं. उदाहरण के लिए, ML किट क्विकस्टार्ट सैंपल में updatepreviewOverlayViewWithLastFrame देखें.