iOS पर एमएल किट की मदद से ऑब्जेक्ट का पता लगाएं और उन्हें ट्रैक करें

एमएल किट का इस्तेमाल करके, एक के बाद एक आने वाले वीडियो फ़्रेम में चीज़ों का पता लगाया और उन्हें ट्रैक किया जा सकता है.

जब किसी इमेज को एमएल किट में भेजा जाता है, तो वह इमेज में मौजूद पांच ऑब्जेक्ट की पहचान करता है. साथ ही, इमेज में मौजूद हर ऑब्जेक्ट की जगह की पहचान भी करता है. वीडियो स्ट्रीम में ऑब्जेक्ट का पता लगाते समय, हर ऑब्जेक्ट का एक खास आईडी होता है. इसका इस्तेमाल करके, ऑब्जेक्ट को फ़्रेम से फ़्रेम तक ट्रैक किया जा सकता है. इसके अलावा, मोटे ऑब्जेक्ट क्लासिफ़िकेशन को चालू किया जा सकता है. इससे ऑब्जेक्ट को, कैटगरी के ब्यौरे के साथ लेबल किया जाता है.

इसे आज़माएं

शुरू करने से पहले

  1. अपनी Podfile में, इन एमएल किट के पॉड शामिल करें:
    pod 'GoogleMLKit/ObjectDetection', '3.2.0'
    
  2. अपने प्रोजेक्ट के पॉड इंस्टॉल या अपडेट करने के बाद, .xcworkspace का इस्तेमाल करके Xcode प्रोजेक्ट खोलें. ML Kit, Xcode के 12.4 या इसके बाद वाले वर्शन पर काम करती है.

1. ऑब्जेक्ट डिटेक्टर को कॉन्फ़िगर करें

ऑब्जेक्ट का पता लगाने और उन्हें ट्रैक करने के लिए, सबसे पहले ObjectDetector का इंस्टेंस बनाएं. साथ ही, अगर आपको डिटेक्टर की कोई सेटिंग डिफ़ॉल्ट से बदलनी है, तो वैकल्पिक तौर पर तय करें.

  1. 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;
  1. 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 एक पूर्णांक जो इमेज में ऑब्जेक्ट की पहचान करता है या एक इमेज वाले मोड में `शून्य` पता लगाता है.
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 के तौर पर सेट करें. अगर डिटेक्टर के चालू रहने के दौरान, कोई नया वीडियो फ़्रेम उपलब्ध होता है, तो उसे हटा दिया जाएगा.
  • अगर इनपुट इमेज पर ग्राफ़िक ओवरले करने के लिए, डिटेक्टर के आउटपुट का इस्तेमाल किया जाता है, तो सबसे पहले एमएल किट से नतीजा पाएं. इसके बाद, एक ही चरण में इमेज और ओवरले को रेंडर करें. ऐसा करने से, प्रोसेस किए गए हर इनपुट फ़्रेम के लिए, डिसप्ले प्लैटफ़ॉर्म पर सिर्फ़ एक बार रेंडर किया जाता है. उदाहरण के लिए, एमएल किट के क्विकस्टार्ट सैंपल में updatePreviewOverlayViewWithLastFrame देखें.