iOS-এ ML কিটের সাথে সেলফি সেগমেন্টেশন

ML কিট সেলফি সেগমেন্টেশনের জন্য একটি অপ্টিমাইজ করা SDK প্রদান করে। সেলফি সেগমেন্টার সম্পদগুলি বিল্ড টাইমে আপনার অ্যাপের সাথে স্ট্যাটিকভাবে লিঙ্ক করা হয়। এটি আপনার অ্যাপের আকার 24MB পর্যন্ত বাড়িয়ে দেবে এবং API লেটেন্সি ~7ms থেকে ~12ms হতে পারে ইনপুট ইমেজ সাইজের উপর নির্ভর করে, যেমন iPhone X এ পরিমাপ করা হয়।

চেষ্টা করে দেখুন

আপনি শুরু করার আগে

  1. আপনার পডফাইলে নিম্নলিখিত এমএল কিট লাইব্রেরিগুলি অন্তর্ভুক্ত করুন:

    pod 'GoogleMLKit/SegmentationSelfie', '15.5.0'
    
  2. আপনি আপনার প্রকল্পের পডগুলি ইনস্টল বা আপডেট করার পরে, এটি ব্যবহার করে আপনার Xcode প্রকল্পটি খুলুন। xcworkspace । ML কিট Xcode সংস্করণ 13.2.1 বা উচ্চতর সমর্থিত।

1. সেগমেন্টারের একটি উদাহরণ তৈরি করুন

সেলফি ইমেজে সেগমেন্টেশন করতে, প্রথমে SelfieSegmenterOptions সহ Segmenter একটি উদাহরণ তৈরি করুন এবং ঐচ্ছিকভাবে সেগমেন্টেশন সেটিংস নির্দিষ্ট করুন।

সেগমেন্টার বিকল্প

সেগমেন্টার মোড

Segmenter দুটি মোডে কাজ করে। আপনার ব্যবহারের ক্ষেত্রে মেলে এমন একটি বেছে নিন তা নিশ্চিত করুন।

STREAM_MODE (default)

এই মোডটি ভিডিও বা ক্যামেরা থেকে ফ্রেম স্ট্রিম করার জন্য ডিজাইন করা হয়েছে। এই মোডে, সেগমেন্টার মসৃণ সেগমেন্টেশন ফলাফল ফিরিয়ে আনতে পূর্ববর্তী ফ্রেমের ফলাফলগুলি লাভ করবে।

SINGLE_IMAGE_MODE (default)

এই মোডটি একক ছবিগুলির জন্য ডিজাইন করা হয়েছে যা সম্পর্কিত নয়৷ এই মোডে, সেগমেন্টার প্রতিটি ছবি স্বাধীনভাবে প্রক্রিয়া করবে, ফ্রেমের উপর কোন মসৃণতা ছাড়াই।

কাঁচা আকারের মাস্ক সক্ষম করুন

সেগমেন্টারকে কাঁচা আকারের মাস্ক ফেরত দিতে বলে যা মডেল আউটপুট আকারের সাথে মেলে।

কাঁচা মুখোশের আকার (যেমন 256x256) সাধারণত ইনপুট চিত্রের আকারের চেয়ে ছোট হয়।

এই বিকল্পটি নির্দিষ্ট না করেই, সেগমেন্টার ইনপুট চিত্রের আকারের সাথে মেলে কাঁচা মুখোশটি পুনরায় স্কেল করবে। আপনি যদি কাস্টমাইজড রিস্কেলিং লজিক প্রয়োগ করতে চান বা আপনার ব্যবহারের ক্ষেত্রে রিস্কেলিংয়ের প্রয়োজন নেই তাহলে এই বিকল্পটি ব্যবহার করার কথা বিবেচনা করুন।

সেগমেন্টার বিকল্পগুলি নির্দিষ্ট করুন:

সুইফট

let options = SelfieSegmenterOptions()
options.segmenterMode = .singleImage
options.shouldEnableRawSizeMask = true

উদ্দেশ্য-C

MLKSelfieSegmenterOptions *options = [[MLKSelfieSegmenterOptions alloc] init];
options.segmenterMode = MLKSegmenterModeSingleImage;
options.shouldEnableRawSizeMask = YES;

অবশেষে, Segmenter একটি উদাহরণ পান। আপনার নির্দিষ্ট করা বিকল্পগুলি পাস করুন:

সুইফট

let segmenter = Segmenter.segmenter(options: options)

উদ্দেশ্য-C

MLKSegmenter *segmenter = [MLKSegmenter segmenterWithOptions:options];

2. ইনপুট ইমেজ প্রস্তুত করুন

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

একটি UIImage বা একটি CMSampleBuffer ব্যবহার করে একটি VisionImage অবজেক্ট তৈরি করুন।

আপনি একটি UIImage ব্যবহার করলে, এই পদক্ষেপগুলি অনুসরণ করুন:

  • UIImage দিয়ে একটি VisionImage অবজেক্ট তৈরি করুন। সঠিক .orientation উল্লেখ করতে ভুলবেন না।

    সুইফট

    let image = VisionImage(image: UIImage)
    visionImage.orientation = image.imageOrientation

    উদ্দেশ্য-C

    MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
    visionImage.orientation = image.imageOrientation;

আপনি যদি একটি CMSampleBuffer ব্যবহার করেন তবে এই পদক্ষেপগুলি অনুসরণ করুন:

  • CMSampleBuffer এ থাকা ইমেজ ডেটার ওরিয়েন্টেশন নির্দিষ্ট করুন।

    ইমেজ ওরিয়েন্টেশন পেতে:

    সুইফট

    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
      }
    }
          

    উদ্দেশ্য-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 অবজেক্ট তৈরি করুন:

    সুইফট

    let image = VisionImage(buffer: sampleBuffer)
    image.orientation = imageOrientation(
      deviceOrientation: UIDevice.current.orientation,
      cameraPosition: cameraPosition)

    উদ্দেশ্য-C

     MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer];
     image.orientation =
       [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                    cameraPosition:cameraPosition];

3. চিত্রটি প্রক্রিয়া করুন

Segmenter ইমেজ প্রসেসিং পদ্ধতির একটিতে VisionImage অবজেক্ট পাস করুন। আপনি হয় অ্যাসিঙ্ক্রোনাস process(image:) পদ্ধতি বা সিঙ্ক্রোনাস results(in:) পদ্ধতি ব্যবহার করতে পারেন।

সিঙ্ক্রোনাসভাবে একটি সেলফি ইমেজে বিভাজন সম্পাদন করতে:

সুইফট

var mask: [SegmentationMask]
do {
  mask = try segmenter.results(in: image)
} catch let error {
  print("Failed to perform segmentation with error: \(error.localizedDescription).")
  return
}

// Success. Get a segmentation mask here.

উদ্দেশ্য-C

NSError *error;
MLKSegmentationMask *mask =
    [segmenter resultsInImage:image error:&error];
if (error != nil) {
  // Error.
  return;
}

// Success. Get a segmentation mask here.

অ্যাসিঙ্ক্রোনাসভাবে একটি সেলফি ইমেজে বিভাজন সম্পাদন করতে:

সুইফট

segmenter.process(image) { mask, error in
  guard error == nil else {
    // Error.
    return
  }
  // Success. Get a segmentation mask here.

উদ্দেশ্য-C

[segmenter processImage:image
             completion:^(MLKSegmentationMask * _Nullable mask,
                          NSError * _Nullable error) {
               if (error != nil) {
                 // Error.
                 return;
               }
               // Success. Get a segmentation mask here.
             }];

4. সেগমেন্টেশন মাস্ক পান

আপনি নিম্নলিখিত হিসাবে বিভাজন ফলাফল পেতে পারেন:

সুইফট

let maskWidth = CVPixelBufferGetWidth(mask.buffer)
let maskHeight = CVPixelBufferGetHeight(mask.buffer)

CVPixelBufferLockBaseAddress(mask.buffer, CVPixelBufferLockFlags.readOnly)
let maskBytesPerRow = CVPixelBufferGetBytesPerRow(mask.buffer)
var maskAddress =
    CVPixelBufferGetBaseAddress(mask.buffer)!.bindMemory(
        to: Float32.self, capacity: maskBytesPerRow * maskHeight)

for _ in 0...(maskHeight - 1) {
  for col in 0...(maskWidth - 1) {
    // Gets the confidence of the pixel in the mask being in the foreground.
    let foregroundConfidence: Float32 = maskAddress[col]
  }
  maskAddress += maskBytesPerRow / MemoryLayout<Float32>.size
}

উদ্দেশ্য-C

size_t width = CVPixelBufferGetWidth(mask.buffer);
size_t height = CVPixelBufferGetHeight(mask.buffer);

CVPixelBufferLockBaseAddress(mask.buffer, kCVPixelBufferLock_ReadOnly);
size_t maskBytesPerRow = CVPixelBufferGetBytesPerRow(mask.buffer);
float *maskAddress = (float *)CVPixelBufferGetBaseAddress(mask.buffer);

for (int row = 0; row < height; ++row) {
  for (int col = 0; col < width; ++col) {
    // Gets the confidence of the pixel in the mask being in the foreground.
    float foregroundConfidence = maskAddress[col];
  }
  maskAddress += maskBytesPerRow / sizeof(float);
}

বিভাজন ফলাফলগুলি কীভাবে ব্যবহার করবেন তার সম্পূর্ণ উদাহরণের জন্য, অনুগ্রহ করে ML কিট কুইকস্টার্ট নমুনাটি দেখুন।

কর্মক্ষমতা উন্নত করার টিপস

আপনার ফলাফলের গুণমান ইনপুট চিত্রের মানের উপর নির্ভর করে:

  • ML Kit একটি সঠিক বিভাজন ফলাফল পেতে, চিত্রটি কমপক্ষে 256x256 পিক্সেল হওয়া উচিত।
  • আপনি যদি একটি রিয়েল-টাইম অ্যাপ্লিকেশনে সেলফি সেগমেন্টেশন সঞ্চালন করেন, তাহলে আপনি ইনপুট চিত্রগুলির সামগ্রিক মাত্রাগুলিও বিবেচনা করতে চাইতে পারেন। ছোট ছবিগুলি দ্রুত প্রক্রিয়া করা যেতে পারে, তাই বিলম্ব কমাতে, কম রেজোলিউশনে ছবিগুলি ক্যাপচার করুন, তবে উপরের রেজোলিউশনের প্রয়োজনীয়তাগুলি মনে রাখবেন এবং নিশ্চিত করুন যে বিষয়টি যতটা সম্ভব চিত্রটি দখল করে।
  • খারাপ ইমেজ ফোকাস এছাড়াও নির্ভুলতা প্রভাবিত করতে পারে. আপনি গ্রহণযোগ্য ফলাফল না পেলে, ব্যবহারকারীকে ছবিটি পুনরায় ক্যাপচার করতে বলুন।

আপনি যদি রিয়েল-টাইম অ্যাপ্লিকেশনে সেগমেন্টেশন ব্যবহার করতে চান, তাহলে সেরা ফ্রেম রেটগুলি অর্জন করতে এই নির্দেশিকাগুলি অনুসরণ করুন:

  • stream সেগমেন্টার মোড ব্যবহার করুন।
  • কম রেজোলিউশনে ছবি তোলার কথা বিবেচনা করুন। যাইহোক, এই API এর চিত্র মাত্রা প্রয়োজনীয়তাও মনে রাখবেন।
  • ভিডিও ফ্রেম প্রক্রিয়াকরণের জন্য, সেগমেন্টারের results(in:) সিঙ্ক্রোনাস API ব্যবহার করুন। প্রদত্ত ভিডিও ফ্রেম থেকে সুসংগতভাবে ফলাফল পেতে AVCaptureVideoDataOutputSampleBufferDelegate 's captureOutput(_, didOutput:from:) ফাংশন থেকে এই পদ্ধতিতে কল করুন। AVCaptureVideoDataOutput- এর সর্বদা ডিসকার্ডসলেটভিডিওফ্রেমগুলিকে সেগমেন্টারের কাছে থ্রোটল কলের জন্য সত্য হিসাবে রাখুন৷ সেগমেন্টার চলাকালীন একটি নতুন ভিডিও ফ্রেম উপলব্ধ হলে, এটি বাদ দেওয়া হবে৷
  • আপনি যদি ইনপুট ইমেজে গ্রাফিক্স ওভারলে করার জন্য সেগমেন্টারের আউটপুট ব্যবহার করেন, তাহলে প্রথমে ML Kit থেকে ফলাফল পান, তারপর একটি একক ধাপে চিত্র এবং ওভারলে রেন্ডার করুন। এটি করার মাধ্যমে, আপনি প্রতিটি প্রক্রিয়াকৃত ইনপুট ফ্রেমের জন্য শুধুমাত্র একবার প্রদর্শন পৃষ্ঠে রেন্ডার করবেন। একটি উদাহরণের জন্য ML কিট কুইকস্টার্ট নমুনায় প্রিভিউওভারলেভিউ এবং ক্যামেরাভিউ কন্ট্রোলার ক্লাসগুলি দেখুন।