iOS पर एमएल किट की मदद से चेहरों की पहचान करना

इमेज और वीडियो में चेहरों की पहचान करने के लिए, एमएल किट का इस्तेमाल किया जा सकता है.

इसे आज़माएं

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

  1. अपनी Podfile में, इन एमएल किट के पॉड शामिल करें:
    pod 'GoogleMLKit/FaceDetection', '3.2.0'
    
  2. अपने प्रोजेक्ट के पॉड इंस्टॉल या अपडेट करने के बाद, .xcworkspace का इस्तेमाल करके Xcode प्रोजेक्ट खोलें. ML Kit, Xcode के 12.4 या इसके बाद वाले वर्शन पर काम करती है.

इनपुट इमेज के लिए दिशा-निर्देश

चेहरा पहचानने के लिए, आपको ऐसी इमेज का इस्तेमाल करना चाहिए जिसका डाइमेंशन कम से कम 480x360 पिक्सल हो. एमएल किट में चेहरों की सटीक पहचान करने के लिए, इनपुट इमेज में ऐसे चेहरे होने चाहिए जिन्हें काफ़ी पिक्सल डेटा से दिखाया गया हो. आम तौर पर, इमेज में मौजूद हर चेहरे की पहचान कम से कम 100x100 पिक्सल की होनी चाहिए. अगर आपको चेहरों के कंटूर का पता लगाना है, तो एमएल किट को ज़्यादा रिज़ॉल्यूशन वाले इनपुट की ज़रूरत होती है: हर चेहरे को कम से कम 200x200 पिक्सल का होना चाहिए.

अगर रीयल-टाइम ऐप्लिकेशन में चेहरों की पहचान की जाती है, तो हो सकता है कि आप इनपुट इमेज के सभी डाइमेंशन पर भी विचार करना चाहें. छोटी इमेज को तेज़ी से प्रोसेस किया जा सकता है. इसलिए, इंतज़ार का समय कम करने के लिए, इमेज को कम रिज़ॉल्यूशन में कैप्चर करें. हालांकि, सटीक जानकारी पाने के लिए ऊपर बताई गई ज़रूरी शर्तों का ध्यान रखें. साथ ही, पक्का करें कि इमेज में व्यक्ति का चेहरा ज़्यादा से ज़्यादा जगह ले. रीयल-टाइम में परफ़ॉर्मेंस को बेहतर बनाने के बारे में सलाह भी देखें.

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

एमएल किट, चेहरे की किन सुविधाओं का पता लगाती है, इस पर भी कैमरे के चेहरे की स्क्रीन की दिशा से असर पड़ सकता है. चेहरे की पहचान करने वाले तरीके देखें.

1. चेहरे की पहचान करने वाले टूल को कॉन्फ़िगर करें

किसी इमेज पर चेहरे की पहचान करने की सुविधा लागू करने से पहले, अगर आपको किसी भी फ़ेस डिटेक्टर की डिफ़ॉल्ट सेटिंग में बदलाव करना है, तो 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;

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

किसी इमेज में चेहरों की पहचान करने के लिए, process(_:completion:) या results(in:) तरीके का इस्तेमाल करके, उस इमेज को UIImage या CMSampleBufferRef के तौर पर FaceDetector को पास करें:

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. FaceDetector का इंस्टेंस पाएं

FaceDetector का इंस्टेंस पाएं:

Swift

let faceDetector = FaceDetector.faceDetector(options: options)

Objective-C

MLKFaceDetector *faceDetector = [MLKFaceDetector faceDetectorWithOptions:options];
      

4. इमेज प्रोसेस करें

इसके बाद, इमेज को 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
  }
}];

5. पहचाने गए चेहरों के बारे में जानकारी पाना

अगर चेहरे की पहचान करने का काम पूरा हो जाता है, तो फ़ेस डिटेक्टर, 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 मोड चालू करें. यह डिफ़ॉल्ट रूप से चालू होता है.

  • इससे कम रिज़ॉल्यूशन वाली इमेज कैप्चर की जा सकती हैं. हालांकि, इस एपीआई की इमेज डाइमेंशन से जुड़ी शर्तों का भी ध्यान रखें.

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