iOS-এ ML Kit-এর মাধ্যমে অবজেক্ট শনাক্ত ও ট্র্যাক করা

পরপর ভিডিও ফ্রেমে অবজেক্ট শনাক্ত ও ট্র্যাক করতে আপনি ML Kit ব্যবহার করতে পারবেন।

আপনি ML Kit-এ কোনও ছবি পাস করলে, এটি ছবিতে সর্বাধিক পাঁচটি অবজেক্ট শনাক্ত করে এবং ছবিতে প্রতিটি অবজেক্টের অবস্থানও শনাক্ত করে। ভিডিও স্ট্রিমে অবজেক্ট শনাক্ত করার সময়, প্রতিটি অবজেক্টের একটি অনন্য আইডি থাকে যা আপনি ফ্রেম থেকে ফ্রেমে অবজেক্ট ট্র্যাক করতে ব্যবহার করতে পারেন। এছাড়াও, আপনি ঐচ্ছিকভাবে মোটা অবজেক্ট শ্রেণীবিভাগ চালু করতে পারেন, যা বিস্তারিত বিভাগীয় বিবরণ সহ অবজেক্ট লেবেল করে।

এটি ব্যবহার করে দেখুন

শুরু করার আগে

  1. আপনার Podfile-এ নিম্নলিখিত ML Kit পড অন্তর্ভুক্ত করুন:
    pod 'GoogleMLKit/ObjectDetection', '8.0.0'
    
  2. আপনার প্রোজেক্টের Pod ইনস্টল বা আপডেট করার পরে, এর .xcworkspace ব্যবহার করে আপনার Xcode প্রোজেক্ট খুলুন। Xcode ভার্সন 12.4 বা তার পরের যেকোনও ভার্সনে ML Kit কাজ করে।

১. অবজেক্ট ডিটেক্টর কনফিগার করা

অবজেক্ট শনাক্ত ও ট্র্যাক করতে, প্রথমে ObjectDetector-এর একটি ইনস্ট্যান্স তৈরি করুন এবং ডিফল্ট থেকে পরিবর্তন করতে চান এমন যেকোনও ডিটেক্টর সেটিংস ঐচ্ছিকভাবে নির্দিষ্ট করুন।

  1. ObjectDetectorOptions অবজেক্টের সাহায্যে আপনার ব্যবহারের ক্ষেত্রে অবজেক্ট ডিটেক্টর কনফিগার করুন। আপনি নিম্নলিখিত সেটিংস পরিবর্তন করতে পারবেন:

    অবজেক্ট ডিটেক্টর সেটিংস
    শনাক্তকরণ মোড .stream (ডিফল্ট) | .singleImage

    স্ট্রিম মোডে (ডিফল্ট), অবজেক্ট ডিটেক্টর খুব কম লেটেন্সি সহ রান করে, কিন্তু ডিটেক্টর প্রথম কয়েকবার ইনভোক করার সময় অসম্পূর্ণ ফলাফল (যেমন, অনির্দিষ্ট বাউন্ডিং বক্স বা বিভাগ) দিতে পারে। এছাড়াও, স্ট্রিম মোডে, ডিটেক্টর অবজেক্টে ট্র্যাকিং আইডি অ্যাসাইন করে, যা আপনি ফ্রেম জুড়ে অবজেক্ট ট্র্যাক করতে ব্যবহার করতে পারেন। আপনি যখন অবজেক্ট ট্র্যাক করতে চান বা যখন কম লেটেন্সি গুরুত্বপূর্ণ, যেমন রিয়েল টাইমে ভিডিও স্ট্রিম প্রসেস করার সময় এই মোডটি ব্যবহার করুন।

    সিঙ্গেল ইমেজ মোডে, অবজেক্টের বাউন্ডিং বক্স নির্ধারণ করার পরে অবজেক্ট ডিটেক্টর ফলাফল রিটার্ন করে। আপনি যদি শ্রেণীবিভাগও চালু করেন, তাহলে বাউন্ডিং বক্স ও ক্যাটাগরি লেবেল, দুটিই উপলভ্য হওয়ার পরে ফলাফল রিটার্ন করে। এর ফলে, শনাক্তকরণ লেটেন্সি সম্ভাব্যভাবে বেশি হয়। এছাড়াও, সিঙ্গেল ইমেজ মোডে, ট্র্যাকিং আইডি অ্যাসাইন করা হয় না। লেটেন্সি খুব গুরুত্বপূর্ণ না হলে এবং আংশিক ফলাফল নিয়ে কাজ করতে না চাইলে এই মোড ব্যবহার করুন।

    একাধিক অবজেক্ট শনাক্ত ও ট্র্যাক করুন false (ডিফল্ট) | true

    সর্বাধিক পাঁচটি অবজেক্ট শনাক্ত ও ট্র্যাক করা হবে নাকি শুধুমাত্র সবচেয়ে গুরুত্বপূর্ণ অবজেক্ট (ডিফল্ট)।

    অবজেক্ট শ্রেণীবদ্ধ করা false (ডিফল্ট) | true

    শনাক্ত করা অবজেক্টকে মোটা মোটা বিভাগে ভাগ করা হবে কিনা। চালু করা হলে, অবজেক্ট ডিটেক্টর অবজেক্টকে নিম্নলিখিত বিভাগে শ্রেণীবদ্ধ করে: ফ্যাশন আইটেম, খাবার, গৃহস্থালির জিনিস, জায়গা এবং গাছপালা।

    এই দুটি মূল সম্ভাব্য পরিস্থিতির জন্য অবজেক্ট ডিটেকশন ও ট্র্যাকিং API অপ্টিমাইজ করা হয়েছে:

    • ক্যামেরা ভিউফাইন্ডারে সবচেয়ে গুরুত্বপূর্ণ অবজেক্টের লাইভ ডিটেকশন ও ট্র্যাকিং।
    • স্ট্যাটিক ছবিতে একাধিক অবজেক্ট শনাক্ত করা।

    এইসব ব্যবহারের ক্ষেত্রে API কনফিগার করতে:

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];

২. ইনপুট ছবি প্রস্তুত করুন

অবজেক্ট শনাক্ত ও ট্র্যাক করতে, প্রতিটি ছবি বা ভিডিওর ফ্রেমের জন্য নিম্নলিখিত ধাপগুলি অনুসরণ করুন। আপনি স্ট্রিম মোড চালু করলে, আপনাকে অবশ্যই VisionImage থেকে CMSampleBuffer অবজেক্ট তৈরি করতে হবে।

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];

৩. ছবি প্রসেস করা

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.

৪. শনাক্ত করা অবজেক্ট সম্পর্কে তথ্য পাওয়া

ইমেজ প্রসেসরে কল করা সফল হলে, এটি হয় সম্পূর্ণকরণ হ্যান্ডলারে 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:) সিঙ্ক্রোনাস API ব্যবহার করুন। প্রদত্ত ভিডিও ফ্রেম থেকে সিঙ্ক্রোনাসভাবে ফলাফল পেতে, AVCaptureVideoDataOutputSampleBufferDelegate's captureOutput(_, didOutput:from:) ফাংশন থেকে এই মেথডটি কল করুন। ডিটেক্টরে কল থ্রটল করতে AVCaptureVideoDataOutput-এর alwaysDiscardsLateVideoFrames true হিসেবে রাখুন। ডিটেক্টর চলাকালীন নতুন ভিডিও ফ্রেম উপলভ্য হলে, সেটি বাদ দেওয়া হবে।
  • ইনপুট ছবিতে গ্রাফিক্স ওভারলে করতে আপনি যদি ডিটেক্টরের আউটপুট ব্যবহার করেন, তাহলে প্রথমে ML Kit থেকে ফলাফল পান, তারপরে ছবি রেন্ডার করুন এবং একটি ধাপে ওভারলে করুন। এটি করার মাধ্যমে, আপনি প্রসেস করা প্রতিটি ইনপুট ফ্রেমের জন্য ডিসপ্লে সারফেসে শুধুমাত্র একবার রেন্ডার করেন। উদাহরণের জন্য ML Kit কুইকস্টার্ট স্যাম্পেলে updatePreviewOverlayViewWithLastFrame দেখুন।