iOS पर कस्टम मॉडल के साथ इमेज लेबल करना

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

कस्टम मॉडल को इंटिग्रेट करने के दो तरीके हैं. मॉडल को अपने ऐप्लिकेशन के एसेट फ़ोल्डर में रखकर, उसे बंडल किया जा सकता है या डाइनैमिक तरीके से Firebase से डाउनलोड किया जा सकता है. नीचे दी गई टेबल में दोनों विकल्पों की तुलना की गई है.

बंडल किया गया मॉडल होस्ट किया गया मॉडल
मॉडल आपके ऐप्लिकेशन के APK का हिस्सा है, जिससे इसका साइज़ बढ़ जाता है. मॉडल आपके APK का हिस्सा नहीं है. इसे Firebase मशीन लर्निंग पर अपलोड करके होस्ट किया जाता है.
मॉडल Android डिवाइस के ऑफ़लाइन होने पर भी तुरंत उपलब्ध होता है मॉडल को मांग पर डाउनलोड किया गया है
Firebase प्रोजेक्ट की ज़रूरत नहीं है Firebase प्रोजेक्ट की ज़रूरत है
मॉडल को अपडेट करने के लिए, आपको अपना ऐप्लिकेशन फिर से प्रकाशित करना होगा अपने ऐप्लिकेशन को फिर से प्रकाशित किए बिना मॉडल अपडेट भेजें
पहले से मौजूद A/B टेस्टिंग नहीं Firebase रिमोट कॉन्फ़िगरेशन की मदद से, आसान A/B टेस्टिंग

इसे आज़माएं

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

  1. अपनी Podfile में ML किट लाइब्रेरी शामिल करें:

    अपने ऐप्लिकेशन के साथ किसी मॉडल को बंडल करने के लिए:

    pod 'GoogleMLKit/ImageLabelingCustom', '3.2.0'
    

    Firebase से कोई मॉडल डाइनैमिक तौर पर डाउनलोड करने के लिए, LinkFirebase निर्भरता:

    pod 'GoogleMLKit/ImageLabelingCustom', '3.2.0'
    pod 'GoogleMLKit/LinkFirebase', '3.2.0'
    
  2. अपने प्रोजेक्ट के पॉड इंस्टॉल या अपडेट करने के बाद, .xcworkspace का इस्तेमाल करके अपना Xcode प्रोजेक्ट खोलें. ML किट, Xcode के 13.2.1 या उसके बाद के वर्शन पर काम करती है.

  3. अगर आप कोई मॉडल डाउनलोड करना चाहते हैं, तो पक्का करें कि आपने अपने iOS प्रोजेक्ट में Firebase जोड़ा हो, अगर आपने पहले से ऐसा नहीं किया है, तो मॉडल को बंडल करते समय इसकी ज़रूरत नहीं है.

1. मॉडल लोड करें

लोकल मॉडल सोर्स को कॉन्फ़िगर करना

अपने ऐप्लिकेशन के साथ मॉडल को बंडल करने के लिए:

  1. मॉडल फ़ाइल (आम तौर पर, .tflite या .lite से खत्म होने वाली) को अपने Xcode प्रोजेक्ट में कॉपी करें. ऐसा करते समय, Copy bundle resources को चुनें. मॉडल फ़ाइल को ऐप्लिकेशन बंडल में शामिल किया जाएगा और यह ML किट में उपलब्ध होगी.

  2. मॉडल फ़ाइल का पाथ बताने वाला LocalModel ऑब्जेक्ट बनाएं:

    Swift

    let localModel = LocalModel(path: localModelFilePath)

    Objective-C

    MLKLocalModel *localModel =
        [[MLKLocalModel alloc] initWithPath:localModelFilePath];

Firebase से होस्ट किए गए मॉडल सोर्स को कॉन्फ़िगर करना

रिमोट तरीके से होस्ट किए गए मॉडल का इस्तेमाल करने के लिए, वह RemoteModel ऑब्जेक्ट बनाएं जिसमें आपके मॉडल को प्रकाशित करते समय असाइन किया गया है:

Swift

let firebaseModelSource = FirebaseModelSource(
    name: "your_remote_model") // The name you assigned in
                               // the Firebase console.
let remoteModel = CustomRemoteModel(remoteModelSource: firebaseModelSource)

Objective-C

MLKFirebaseModelSource *firebaseModelSource =
    [[MLKFirebaseModelSource alloc]
        initWithName:@"your_remote_model"]; // The name you assigned in
                                            // the Firebase console.
MLKCustomRemoteModel *remoteModel =
    [[MLKCustomRemoteModel alloc]
        initWithRemoteModelSource:firebaseModelSource];

इसके बाद, मॉडल डाउनलोड करने से जुड़ा टास्क शुरू करें. इसमें उन शर्तों की जानकारी दें जिनके तहत आपको डाउनलोड करने की अनुमति देनी है. अगर मॉडल डिवाइस पर नहीं है या अगर मॉडल का कोई नया वर्शन उपलब्ध है, तो यह काम Firebase से मॉडल को एसिंक्रोनस रूप से डाउनलोड करेगा:

Swift

let downloadConditions = ModelDownloadConditions(
  allowsCellularAccess: true,
  allowsBackgroundDownloading: true
)

let downloadProgress = ModelManager.modelManager().download(
  remoteModel,
  conditions: downloadConditions
)

Objective-C

MLKModelDownloadConditions *downloadConditions =
    [[MLKModelDownloadConditions alloc] initWithAllowsCellularAccess:YES
                                         allowsBackgroundDownloading:YES];

NSProgress *downloadProgress =
    [[MLKModelManager modelManager] downloadModel:remoteModel
                                       conditions:downloadConditions];

कई ऐप्लिकेशन अपने शुरुआती कोड में डाउनलोड टास्क शुरू करते हैं, लेकिन मॉडल इस्तेमाल करने से पहले आप किसी भी समय ऐसा कर सकते हैं.

इमेज लेबलर को कॉन्फ़िगर करें

अपने मॉडल सोर्स कॉन्फ़िगर करने के बाद, उनमें से एक से ImageLabeler ऑब्जेक्ट बनाएं.

फ़िल्टर के लिए, यहां दिए गए विकल्प उपलब्ध होते हैं:

विकल्प
confidenceThreshold

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

maxResultCount

लौटाए जाने वाले लेबल की ज़्यादा से ज़्यादा संख्या. अगर यह सेट नहीं है, तो डिफ़ॉल्ट वैल्यू के तौर पर 10 का इस्तेमाल किया जाएगा.

अगर आपके पास सिर्फ़ स्थानीय तौर पर बंडल किया गया मॉडल है, तो बस अपने LocalModel ऑब्जेक्ट से लेबलर बनाएं:

Swift

let options = CustomImageLabelerOptions(localModel: localModel)
options.confidenceThreshold = NSNumber(value: 0.0)
let imageLabeler = ImageLabeler.imageLabeler(options: options)

Objective-C

MLKCustomImageLabelerOptions *options =
    [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel];
options.confidenceThreshold = @(0.0);
MLKImageLabeler *imageLabeler =
    [MLKImageLabeler imageLabelerWithOptions:options];

अगर आपके पास रिमोट से होस्ट किया गया मॉडल है, तो आपको इसे चलाने से पहले जांच लेना होगा. मॉडल मैनेजर के isModelDownloaded(remoteModel:) तरीके का इस्तेमाल करके, मॉडल डाउनलोड टास्क की स्थिति देखी जा सकती है.

भले ही, लेबल करने वाले को चलाने से पहले, आपको इसकी पुष्टि करनी हो, लेकिन अगर आपके पास रिमोट से होस्ट किया गया मॉडल और स्थानीय तौर पर बंडल किया गया मॉडल, दोनों हैं, तो ImageLabeler को शुरू करते समय यह जांच करनी पड़ सकती है. अगर रिमोट मॉडल डाउनलोड हो चुका है, तो हो सकता है कि वह लेबल बना हो. अगर ऐसा नहीं है, तो स्थानीय मॉडल से लेबल बनाएं.

Swift

var options: CustomImageLabelerOptions!
if (ModelManager.modelManager().isModelDownloaded(remoteModel)) {
  options = CustomImageLabelerOptions(remoteModel: remoteModel)
} else {
  options = CustomImageLabelerOptions(localModel: localModel)
}
options.confidenceThreshold = NSNumber(value: 0.0)
let imageLabeler = ImageLabeler.imageLabeler(options: options)

Objective-C

MLKCustomImageLabelerOptions *options;
if ([[MLKModelManager modelManager] isModelDownloaded:remoteModel]) {
  options = [[MLKCustomImageLabelerOptions alloc] initWithRemoteModel:remoteModel];
} else {
  options = [[MLKCustomImageLabelerOptions alloc] initWithLocalModel:localModel];
}
options.confidenceThreshold = @(0.0);
MLKImageLabeler *imageLabeler =
    [MLKImageLabeler imageLabelerWithOptions:options];

अगर आपके पास सिर्फ़ रिमोट तरीके से होस्ट किया गया मॉडल है, तो मॉडल से जुड़ी सुविधाओं को बंद कर देना चाहिए. उदाहरण के लिए, अपने यूज़र इंटरफ़ेस (यूआई) के हिस्से को धूसर कर दें या छिपाएं.

डिफ़ॉल्ट सूचना केंद्र में ऑब्ज़र्वर जोड़कर, मॉडल की स्थिति को डाउनलोड करने की स्थिति देखी जा सकती है. ध्यान रखें कि ऑब्ज़र्वर ब्लॉक में self का कमज़ोर रेफ़रंस मिले, क्योंकि डाउनलोड होने में कुछ समय लग सकता है. साथ ही, डाउनलोड पूरा होने तक मूल ऑब्जेक्ट का डेटा आ सकता है. उदाहरण के लिए :

Swift

NotificationCenter.default.addObserver(
    forName: .mlkitModelDownloadDidSucceed,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let strongSelf = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? RemoteModel,
        model.name == "your_remote_model"
        else { return }
    // The model was downloaded and is available on the device
}

NotificationCenter.default.addObserver(
    forName: .mlkitModelDownloadDidFail,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let strongSelf = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? RemoteModel
        else { return }
    let error = userInfo[ModelDownloadUserInfoKey.error.rawValue]
    // ...
}

Objective-C

__weak typeof(self) weakSelf = self;

[NSNotificationCenter.defaultCenter
    addObserverForName:MLKModelDownloadDidSucceedNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }
              __strong typeof(self) strongSelf = weakSelf;

              MLKRemoteModel *model = note.userInfo[MLKModelDownloadUserInfoKeyRemoteModel];
              if ([model.name isEqualToString:@"your_remote_model"]) {
                // The model was downloaded and is available on the device
              }
            }];

[NSNotificationCenter.defaultCenter
    addObserverForName:MLKModelDownloadDidFailNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }
              __strong typeof(self) strongSelf = weakSelf;

              NSError *error = note.userInfo[MLKModelDownloadUserInfoKeyError];
            }];

2. इनपुट इमेज तैयार करें

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. इमेज लेबलर चलाएं

किसी इमेज में मौजूद चीज़ों को लेबल करने के लिए, image ऑब्जेक्ट को ImageLabeler के process() तरीके में पास करें.

एसिंक्रोनस रूप से:

Swift

imageLabeler.process(image) { labels, error in
    guard error == nil, let labels = labels, !labels.isEmpty else {
        // Handle the error.
        return
    }
    // Show results.
}

Objective-C

[imageLabeler
    processImage:image
      completion:^(NSArray *_Nullable labels,
                   NSError *_Nullable error) {
        if (label.count == 0) {
            // Handle the error.
            return;
        }
        // Show results.
     }];

सिंक्रोनस रूप से:

Swift

var labels: [ImageLabel]
do {
    labels = try imageLabeler.results(in: image)
} catch let error {
    // Handle the error.
    return
}
// Show results.

Objective-C

NSError *error;
NSArray *labels =
    [imageLabeler resultsInImage:image error:&error];
// Show results or handle the error.

4. लेबल की गई इकाइयों के बारे में जानकारी पाना

इमेज लेबल करने की कार्रवाई पूरी होने पर, यह ImageLabel की रेंज दिखाता है. हर ImageLabel इमेज में लेबल की गई किसी चीज़ को दिखाता है. आप हर लेबल का टेक्स्ट ब्यौरा (अगर TensorFlow लाइट मॉडल फ़ाइल के मेटाडेटा में उपलब्ध हो), कॉन्फ़िडेंस स्कोर, और इंडेक्स पा सकते हैं. उदाहरण के लिए :

Swift

for label in labels {
  let labelText = label.text
  let confidence = label.confidence
  let index = label.index
}

Objective-C

for (MLKImageLabel *label in labels) {
  NSString *labelText = label.text;
  float confidence = label.confidence;
  NSInteger index = label.index;
}

रीयल-टाइम में परफ़ॉर्मेंस को बेहतर बनाने के लिए सलाह

अगर आप रीयल-टाइम ऐप्लिकेशन में इमेज को लेबल करना चाहते हैं, तो सबसे अच्छे फ़्रेम रेट पाने के लिए, इन दिशा-निर्देशों का पालन करें:

  • वीडियो फ़्रेम प्रोसेस करने के लिए, डिटेक्टर के results(in:) सिंक्रोनस एपीआई का इस्तेमाल करें. दिए गए वीडियो फ़्रेम से सिंक्रोनस रूप से परिणाम पाने के लिए AVCaptureVideoDataOutputSampleBufferDelegate के captureOutput(_, didOutput:from:) फ़ंक्शन से इस विधि को कॉल करें. AVCaptureVideoDataOutput की alwaysDiscardsLateVideoFrames को true के तौर पर रखें, ताकि डिटेक्टर को कॉल थ्रॉटल किए जा सकें. अगर डिटेक्टर चलने के दौरान नया वीडियो फ़्रेम उपलब्ध हो जाता है, तो उसे छोड़ दिया जाएगा.
  • अगर आप इनपुट इमेज पर ग्राफ़िक ओवरले करने के लिए डिटेक्टर के आउटपुट का इस्तेमाल करते हैं, तो पहले ML किट से नतीजा पाएं. इसके बाद, इमेज और ओवरले को एक ही चरण में रेंडर करें. ऐसा करके, आप हर प्रोसेस किए गए इनपुट फ़्रेम के लिए डिसप्ले को सिर्फ़ एक बार रेंडर करते हैं. उदाहरण के लिए, ML किट क्विकस्टार्ट सैंपल में updatepreviewOverlayViewWithLastFrame देखें.