iOS-এ ML Kit-এর মাধ্যমে মুখ শনাক্ত করা

ছবি ও ভিডিওতে মুখ শনাক্ত করতে আপনি ML Kit ব্যবহার করতে পারবেন।

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

শুরু করার আগে

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

ইনপুট ছবি সংক্রান্ত নির্দেশিকা

ফেস রিকগনিশনের জন্য, আপনাকে অন্তত ৪৮০x৩৬০ পিক্সেল সাইজের ছবি ব্যবহার করতে হবে। ML Kit-এর মাধ্যমে মুখ সঠিকভাবে শনাক্ত করার জন্য, ইনপুট ছবিতে এমন মুখ থাকতে হবে যেগুলি পর্যাপ্ত পিক্সেল ডেটা দ্বারা উপস্থাপিত হয়। সাধারণত, আপনি কোনও ছবিতে যে মুখ শনাক্ত করতে চান, সেটি কমপক্ষে ১০০x১০০ পিক্সেল হতে হবে। আপনি যদি মুখের আউটলাইন শনাক্ত করতে চান, তাহলে ML Kit-এর জন্য আরও উন্নত রেজোলিউশনের ইনপুট প্রয়োজন: প্রতিটি মুখ অন্তত ২০০x২০০ পিক্সেল হতে হবে।

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

ছবির ফোকাস ভাল না হলে, তার প্রভাব নির্ভুলতার উপরেও পড়তে পারে। আপনি গ্রহণযোগ্য ফলাফল না পেলে, ব্যবহারকারীকে ছবিটি আবার ক্যাপচার করতে বলুন।

ক্যামেরার সাথে সম্পর্কিত কোনও মুখের ওরিয়েন্টেশনও ML Kit-এর শনাক্ত করা ফেসিয়াল ফিচারকে প্রভাবিত করতে পারে। ফেস ডিটেকশন সংক্রান্ত ধারণা দেখুন।

১. ফেস ডিটেক্টর কনফিগার করা

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

সেটিংস
performanceMode fast (ডিফল্ট) | accurate

ফেস শনাক্ত করার সময় স্পিড বা নির্ভুলতার মধ্যে কোনও একটিকে অগ্রাধিকার দিন।

landmarkMode none (ডিফল্ট) | all

শনাক্ত করা সব মুখের "ল্যান্ডমার্ক"—চোখ, কান, নাক, গাল, মুখ—শনাক্ত করার চেষ্টা করা হবে কিনা।

contourMode none (ডিফল্ট) | all

মুখের বৈশিষ্ট্যগুলির কনট্যুর শনাক্ত করা হবে কিনা। কোনও ছবিতে সবচেয়ে স্পষ্ট ভাবে দেখা যাওয়া মুখের কনট্যুর শনাক্ত করা হয়।

classificationMode none (ডিফল্ট) | all

"হাসিমুখ" ও "খোলা চোখ"-এর মতো বিভাগে মুখগুলিকে শ্রেণীবদ্ধ করা হবে কিনা।

minFaceSize CGFloat (ডিফল্ট: 0.1)

সবচেয়ে ছোট কাঙ্ক্ষিত মুখের সাইজ সেট করে, যা মাথার প্রস্থ ও ছবির প্রস্থের অনুপাত হিসেবে প্রকাশ করা হয়।

isTrackingEnabled false (ডিফল্ট) | true

ফেসের জন্য আইডি অ্যাসাইন করা হবে কিনা, যা বিভিন্ন ছবি জুড়ে ফেস ট্র্যাক করতে ব্যবহার করা যেতে পারে।

মনে রাখবেন, কনট্যুর ডিটেকশন চালু করা থাকলে, শুধুমাত্র একটি মুখ শনাক্ত করা হয়, তাই ফেস ট্র্যাকিং কোনও কার্যকর ফলাফল দেয় না। এই কারণে এবং শনাক্তকরণের স্পিড উন্নত করতে, কনট্যুর শনাক্তকরণ ও ফেস ট্র্যাকিং, দু'টিই চালু করবেন না।

যেমন, নিম্নলিখিত উদাহরণগুলির মতো একটি FaceDetectorOptions অবজেক্ট তৈরি করুন:

Swift

// High-accuracy landmark detection and face classification
let options = FaceDetectorOptions()
options.performanceMode = .accurate
options.landmarkMode = .all
options.classificationMode = .all

// Real-time contour detection of multiple faces
// options.contourMode = .all

Objective-C

// High-accuracy landmark detection and face classification
MLKFaceDetectorOptions *options = [[MLKFaceDetectorOptions alloc] init];
options.performanceMode = MLKFaceDetectorPerformanceModeAccurate;
options.landmarkMode = MLKFaceDetectorLandmarkModeAll;
options.classificationMode = MLKFaceDetectorClassificationModeAll;

// Real-time contour detection of multiple faces
// options.contourMode = MLKFaceDetectorContourModeAll;

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

কোনও ছবিতে মুখ শনাক্ত করতে, UIImage বা CMSampleBufferRef হিসেবে ছবিটিকে FaceDetector-এ পাস করুন, এর জন্য process(_:completion:) বা results(in:) পদ্ধতি ব্যবহার করুন:

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

৩. FaceDetector-এর একটি ইনস্ট্যান্স পান

FaceDetector-এর ইনস্ট্যান্স পান:

Swift

let faceDetector = FaceDetector.faceDetector(options: options)

Objective-C

MLKFaceDetector *faceDetector = [MLKFaceDetector faceDetectorWithOptions:options];
      

৪. ছবি প্রসেস করুন

তারপর, process() পদ্ধতিতে ছবিটি পাস করুন:

Swift

weak var weakSelf = self
faceDetector.process(visionImage) { faces, error in
  guard let strongSelf = weakSelf else {
    print("Self is nil!")
    return
  }
  guard error == nil, let faces = faces, !faces.isEmpty else {
    // ...
    return
  }

  // Faces detected
  // ...
}

Objective-C

[faceDetector processImage:image
                completion:^(NSArray<MLKFace *> *faces,
                             NSError *error) {
  if (error != nil) {
    return;
  }
  if (faces.count > 0) {
    // Recognized faces
  }
}];

৫. শনাক্ত করা মুখ সম্পর্কে তথ্য পাওয়া

ফেস ডিটেকশন অপারেশন সফল হলে, ফেস ডিটেক্টর, সম্পূর্ণতা হ্যান্ডলারকে Face অবজেক্টের একটি অ্যারে পাস করে। প্রতিটি Face অবজেক্ট ছবিতে শনাক্ত করা একটি করে মুখকে বোঝায়। প্রতিটি ফেসের জন্য, আপনি ইনপুট ইমেজে এর বাউন্ডিং কোঅর্ডিনেট এবং ফেস ডিটেক্টরকে খুঁজে পাওয়ার জন্য কনফিগার করা অন্য যেকোনও তথ্য পেতে পারেন। যেমন:

Swift

for face in faces {
  let frame = face.frame
  if face.hasHeadEulerAngleX {
    let rotX = face.headEulerAngleX  // Head is rotated to the uptoward rotX degrees
  }
  if face.hasHeadEulerAngleY {
    let rotY = face.headEulerAngleY  // Head is rotated to the right rotY degrees
  }
  if face.hasHeadEulerAngleZ {
    let rotZ = face.headEulerAngleZ  // Head is tilted sideways rotZ degrees
  }

  // If landmark detection was enabled (mouth, ears, eyes, cheeks, and
  // nose available):
  if let leftEye = face.landmark(ofType: .leftEye) {
    let leftEyePosition = leftEye.position
  }

  // If contour detection was enabled:
  if let leftEyeContour = face.contour(ofType: .leftEye) {
    let leftEyePoints = leftEyeContour.points
  }
  if let upperLipBottomContour = face.contour(ofType: .upperLipBottom) {
    let upperLipBottomPoints = upperLipBottomContour.points
  }

  // If classification was enabled:
  if face.hasSmilingProbability {
    let smileProb = face.smilingProbability
  }
  if face.hasRightEyeOpenProbability {
    let rightEyeOpenProb = face.rightEyeOpenProbability
  }

  // If face tracking was enabled:
  if face.hasTrackingID {
    let trackingId = face.trackingID
  }
}

Objective-C

for (MLKFace *face in faces) {
  // Boundaries of face in image
  CGRect frame = face.frame;
  if (face.hasHeadEulerAngleX) {
    CGFloat rotX = face.headEulerAngleX;  // Head is rotated to the upward rotX degrees
  }
  if (face.hasHeadEulerAngleY) {
    CGFloat rotY = face.headEulerAngleY;  // Head is rotated to the right rotY degrees
  }
  if (face.hasHeadEulerAngleZ) {
    CGFloat rotZ = face.headEulerAngleZ;  // Head is tilted sideways rotZ degrees
  }

  // If landmark detection was enabled (mouth, ears, eyes, cheeks, and
  // nose available):
  MLKFaceLandmark *leftEar = [face landmarkOfType:FIRFaceLandmarkTypeLeftEar];
  if (leftEar != nil) {
    MLKVisionPoint *leftEarPosition = leftEar.position;
  }

  // If contour detection was enabled:
  MLKFaceContour *upperLipBottomContour = [face contourOfType:FIRFaceContourTypeUpperLipBottom];
  if (upperLipBottomContour != nil) {
    NSArray<MLKVisionPoint *> *upperLipBottomPoints = upperLipBottomContour.points;
    if (upperLipBottomPoints.count > 0) {
      NSLog("Detected the bottom contour of the subject's upper lip.")
    }
  }

  // If classification was enabled:
  if (face.hasSmilingProbability) {
    CGFloat smileProb = face.smilingProbability;
  }
  if (face.hasRightEyeOpenProbability) {
    CGFloat rightEyeOpenProb = face.rightEyeOpenProbability;
  }

  // If face tracking was enabled:
  if (face.hasTrackingID) {
    NSInteger trackingID = face.trackingID;
  }
}

ফেস কনট্যুরের উদাহরণ

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

নিচের ছবিতে দেখানো হয়েছে যে কীভাবে এই পয়েন্টগুলি কোনও মুখের সাথে ম্যাপ করা হয়, ছবিটি বড় করে দেখতে এটিতে ক্লিক করুন:

শনাক্ত করা মুখের কনট্যুর মেশের উদাহরণ

রিয়েল-টাইম ফেস ডিটেকশন

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

  • ফেস ডিটেক্টরকে কনফিগার করে ফেস কনট্যুর শনাক্তকরণ বা শ্রেণীবিভাগ এবং ল্যান্ডমার্ক শনাক্তকরণ ব্যবহার করুন, তবে দু'টিই নয়:

    কনট্যুর শনাক্তকরণ
    ল্যান্ডমার্ক শনাক্তকরণ
    শ্রেণীবিভাগ
    ল্যান্ডমার্ক শনাক্তকরণ ও শ্রেণীবিভাগ
    কনট্যুর শনাক্তকরণ ও ল্যান্ডমার্ক শনাক্তকরণ
    কনট্যুর শনাক্তকরণ ও শ্রেণীবিভাগ
    কনট্যুর শনাক্তকরণ, ল্যান্ডমার্ক শনাক্তকরণ ও শ্রেণীবিভাগ

  • fast মোড চালু করুন (ডিফল্ট হিসেবে চালু করা থাকে)।

  • কম রেজোলিউশনে ছবি তোলার কথা বিবেচনা করুন। তবে, এই API-এর ছবি সংক্রান্ত প্রয়োজনীয়তাও মনে রাখবেন।

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