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

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

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

  1. अगर आपने पहले से ही अपने ऐप्लिकेशन में Firebase नहीं जोड़ा है, तो शुरुआती निर्देश में दिए गए निर्देशों का पालन करके ऐसा करें.
  2. अपनी Podfile में ML Kit लाइब्रेरी शामिल करें:
    pod 'Firebase/MLVision', '6.25.0'
    # If you want to detect face contours (landmark detection and classification
    # don't require this additional model):
    pod 'Firebase/MLVisionFaceModel', '6.25.0'
    
    अपने प्रोजेक्ट के पॉड को इंस्टॉल या अपडेट करने के बाद, पक्का करें कि आपने Xcode प्रोजेक्ट को इसके .xcworkspace का इस्तेमाल करके खोला हो.
  3. अपने ऐप्लिकेशन में, Firebase इंपोर्ट करें:

    Swift

    import Firebase

    Objective-C

    @import Firebase;

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

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

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

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

कैमरे के हिसाब से किसी चेहरे का ओरिएंटेशन इस बात पर भी असर डाल सकता है कि एमएल किट में चेहरे की कौनसी विशेषताएं पहचानी गई हैं. चेहरे की पहचान करने के तरीके देखें.

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

किसी इमेज पर चेहरे की पहचान करने की सुविधा इस्तेमाल करने से पहले, अगर आपको चेहरे की पहचान करने वाले टूल की किसी भी डिफ़ॉल्ट सेटिंग को बदलना है, तो VisionFaceDetectorOptions ऑब्जेक्ट का इस्तेमाल करके सेटिंग तय करें. ये सेटिंग बदली जा सकती हैं:

सेटिंग
performanceMode fast (डिफ़ॉल्ट) | accurate

चेहरे की पहचान करते समय गति या सटीक जानकारी दें.

landmarkMode none (डिफ़ॉल्ट) | all

पहचान किए गए सभी चेहरों की पहचान करने की कोशिश करनी हो या नहीं, जैसे कि आंखें, कान, नाक, गाल, मुंह.

contourMode none (डिफ़ॉल्ट) | all

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

classificationMode none (डिफ़ॉल्ट) | all

"मुस्कुराना", "आंखें खुली हैं" जैसी कैटगरी में चेहरों को कैटगरी में बांटना है या नहीं.

minFaceSize CGFloat (डिफ़ॉल्ट: 0.1)

इमेज के हिसाब से, पता लगाए जाने वाले चेहरों का कम से कम साइज़.

isTrackingEnabled false (डिफ़ॉल्ट) | true

चेहरों को आईडी असाइन करें या नहीं. इसका इस्तेमाल, सभी इमेज में चेहरों को ट्रैक करने के लिए किया जा सकता है.

ध्यान दें कि कॉन्टूर डिटेक्शन के चालू होने पर, सिर्फ़ एक चेहरे की पहचान की जाती है. इस वजह से, चेहरे को ट्रैक करने की सुविधा से काम के नतीजे नहीं मिलते. इस वजह से, इमेज का पता लगाने की स्पीड को बेहतर बनाने के लिए, कॉन्टूर और चेहरे को ट्रैक करने वाली सुविधा, दोनों को चालू न करें.

उदाहरण के लिए, नीचे दिए गए उदाहरणों में से किसी एक जैसा VisionFaceDetectorOptions ऑब्जेक्ट बनाएं:

Swift

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

// Real-time contour detection of multiple faces
let options = VisionFaceDetectorOptions()
options.contourMode = .all

Objective-C

// High-accuracy landmark detection and face classification
FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init];
options.performanceMode = FIRVisionFaceDetectorPerformanceModeAccurate;
options.landmarkMode = FIRVisionFaceDetectorLandmarkModeAll;
options.classificationMode = FIRVisionFaceDetectorClassificationModeAll;

// Real-time contour detection of multiple faces
FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init];
options.contourMode = FIRVisionFaceDetectorContourModeAll;

2. चेहरे की पहचान करने वाला टूल चलाएं

किसी इमेज में चेहरों की पहचान करने के लिए, VisionFaceDetector के detect(in:) तरीके में इमेज को UIImage या CMSampleBufferRef के तौर पर पास करें:

  1. VisionFaceDetector का इंस्टेंस पाएं:

    Swift

    lazy var vision = Vision.vision()
    
    let faceDetector = vision.faceDetector(options: options)
    

    Objective-C

    FIRVision *vision = [FIRVision vision];
    FIRVisionFaceDetector *faceDetector = [vision faceDetector];
    // Or, to change the default settings:
    // FIRVisionFaceDetector *faceDetector =
    //     [vision faceDetectorWithOptions:options];
    
  2. UIImage या CMSampleBufferRef का इस्तेमाल करके, VisionImage ऑब्जेक्ट बनाएं.

    UIImage का इस्तेमाल करने के लिए:

    1. अगर ज़रूरी हो, तो इमेज को घुमाएं, ताकि उसकी imageOrientation प्रॉपर्टी .up हो.
    2. सही तरीके से घुमाए गए UIImage का इस्तेमाल करके, VisionImage ऑब्जेक्ट बनाएं. कोई भी रोटेशन मेटाडेटा तय न करें—डिफ़ॉल्ट वैल्यू, .topLeft, का इस्तेमाल किया जाना चाहिए.

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    CMSampleBufferRef का इस्तेमाल करने के लिए:

    1. एक VisionImageMetadata ऑब्जेक्ट बनाएं, जो CMSampleBufferRef बफ़र में शामिल इमेज डेटा का ओरिएंटेशन बताता हो.

      इमेज का ओरिएंटेशन पाने के लिए:

      Swift

      func imageOrientation(
          deviceOrientation: UIDeviceOrientation,
          cameraPosition: AVCaptureDevice.Position
          ) -> VisionDetectorImageOrientation {
          switch deviceOrientation {
          case .portrait:
              return cameraPosition == .front ? .leftTop : .rightTop
          case .landscapeLeft:
              return cameraPosition == .front ? .bottomLeft : .topLeft
          case .portraitUpsideDown:
              return cameraPosition == .front ? .rightBottom : .leftBottom
          case .landscapeRight:
              return cameraPosition == .front ? .topRight : .bottomRight
          case .faceDown, .faceUp, .unknown:
              return .leftTop
          }
      }

      Objective-C

      - (FIRVisionDetectorImageOrientation)
          imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                                 cameraPosition:(AVCaptureDevicePosition)cameraPosition {
        switch (deviceOrientation) {
          case UIDeviceOrientationPortrait:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationLeftTop;
            } else {
              return FIRVisionDetectorImageOrientationRightTop;
            }
          case UIDeviceOrientationLandscapeLeft:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationBottomLeft;
            } else {
              return FIRVisionDetectorImageOrientationTopLeft;
            }
          case UIDeviceOrientationPortraitUpsideDown:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationRightBottom;
            } else {
              return FIRVisionDetectorImageOrientationLeftBottom;
            }
          case UIDeviceOrientationLandscapeRight:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationTopRight;
            } else {
              return FIRVisionDetectorImageOrientationBottomRight;
            }
          default:
            return FIRVisionDetectorImageOrientationTopLeft;
        }
      }

      इसके बाद, मेटाडेटा ऑब्जेक्ट बनाएं:

      Swift

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )

      Objective-C

      FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
      AVCaptureDevicePosition cameraPosition =
          AVCaptureDevicePositionBack;  // Set to the capture device you used.
      metadata.orientation =
          [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                       cameraPosition:cameraPosition];
    2. CMSampleBufferRef ऑब्जेक्ट और रोटेशन मेटाडेटा का इस्तेमाल करके VisionImage ऑब्जेक्ट बनाएं:

      Swift

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. इसके बाद, detect(in:) तरीके से इमेज पास करें:

    Swift

    faceDetector.process(visionImage) { faces, error in
      guard error == nil, let faces = faces, !faces.isEmpty else {
        // ...
        return
      }
    
      // Faces detected
      // ...
    }
    

    Objective-C

    [faceDetector detectInImage:image
                     completion:^(NSArray<FIRVisionFace *> *faces,
                                  NSError *error) {
      if (error != nil) {
        return;
      } else if (faces != nil) {
        // Recognized faces
      }
    }];
    

3. पहचाने गए चेहरों की जानकारी पाएं

अगर चेहरे की पहचान करने की कार्रवाई पूरी हो जाती है, तो चेहरे की पहचान करने वाला टूल, VisionFace ऑब्जेक्ट के कलेक्शन को पूरा हैंडलर को पास करता है. हर VisionFace ऑब्जेक्ट, इमेज में मिले चेहरे को दिखाता है. हर चेहरे के लिए, आप इनपुट इमेज में उसके सीमा वाले निर्देशांक पा सकते हैं और साथ ही वह जानकारी भी पा सकते हैं जिसे ढूंढने के लिए आपने फ़ेस डिटेक्टर को कॉन्फ़िगर किया था. उदाहरण के लिए:

Swift

for face in faces {
  let frame = face.frame
  if face.hasHeadEulerAngleY {
    let rotY = face.headEulerAngleY  // Head is rotated to the right rotY degrees
  }
  if face.hasHeadEulerAngleZ {
    let rotZ = face.headEulerAngleZ  // Head is rotated upward 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 (FIRVisionFace *face in faces) {
  // Boundaries of face in image
  CGRect frame = face.frame;

  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):
  FIRVisionFaceLandmark *leftEar = [face landmarkOfType:FIRFaceLandmarkTypeLeftEar];
  if (leftEar != nil) {
    FIRVisionPoint *leftEarPosition = leftEar.position;
  }

  // If contour detection was enabled:
  FIRVisionFaceContour *upperLipBottomContour = [face contourOfType:FIRFaceContourTypeUpperLipBottom];
  if (upperLipBottomContour != nil) {
    NSArray<FIRVisionPoint *> *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 मोड चालू करें (डिफ़ॉल्ट रूप से चालू रहता है).

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

  • डिटेक्टर को कॉल थ्रॉटल करें. अगर डिटेक्टर के चलने के दौरान कोई नया वीडियो फ़्रेम उपलब्ध हो जाता है, तो फ़्रेम को छोड़ दें.
  • अगर इनपुट इमेज पर ग्राफ़िक ओवरले करने के लिए, डिटेक्टर के आउटपुट का इस्तेमाल किया जाता है, तो सबसे पहले एमएल किट का इस्तेमाल करें. इसके बाद, एक ही चरण में इमेज और ओवरले को रेंडर करें. ऐसा करने पर, हर इनपुट फ़्रेम के लिए आपको डिसप्ले प्लैटफ़ॉर्म पर सिर्फ़ एक बार रेंडर करना होगा. उदाहरण के लिए, शोकेस सैंपल ऐप्लिकेशन में previewOverlayView और FIRDetectionOverlayView क्लास देखें.