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

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

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

इसे आज़माएं

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

  1. अपनी Podfile में, नीचे दिए गए ML Kit पॉड शामिल करें:
    pod 'GoogleMLKit/ObjectDetection', '3.2.0'
    
  2. अपने प्रोजेक्ट के Pods को इंस्टॉल या अपडेट करने के बाद, इसके .xcworkspace. 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. इनपुट इमेज तैयार करें

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

एक VisionImage ऑब्जेक्ट को UIImage या CMSampleBuffer.

अगर 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;
      }
    }
          
  • इसका इस्तेमाल करके एक VisionImage ऑब्जेक्ट बनाएं CMSampleBuffer ऑब्जेक्ट और ओरिएंटेशन:

    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 देखें उदाहरण के लिए, एमएल किट क्विकस्टार्ट सैंपल में.