التعرّف على الوجوه باستخدام حزمة تعلُّم الآلة على أجهزة iOS

يمكنك استخدام أدوات تعلُّم الآلة لرصد الوجوه في الصور والفيديوهات.

قبل البدء

  1. إذا لم يسبق لك إضافة Firebase إلى تطبيقك، عليك اتّباع الخطوات الواردة في دليل البدء.
  2. تضمين مكتبات ML Kit في Podfile:
    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'
    
    بعد تثبيت مجموعات Podfile الخاصة بمشروعك أو تعديلها، احرص على فتح مشروع Xcode الخاص بك باستخدام .xcworkspace.
  3. في تطبيقك، استورد Firebase:

    Swift

    import Firebase

    Objective-C

    @import Firebase;

إرشادات إدخال الصور

لكي تتمكّن أداة تعلّم الآلة من رصد الوجوه بدقة، يجب أن تحتوي الصور المدخلة على وجوه ممثلة ببيانات بكسل كافية. بشكل عام، يجب ألا يقلّ حجم كل وجه تريد رصده في الصورة عن 100×100 بكسل. إذا كنت تريد رصد خطوط الوجوه، تتطلب أداة ML Kit إدخالاً بدقة أعلى: يجب أن يبلغ حجم كل وجه 200×200 بكسل على الأقل.

إذا كنت بصدد التعرّف على الوجوه في تطبيق في الوقت الفعلي، ننصحك أيضًا بمراعاة الأبعاد العامة للصور التي يتم إدخالها. يمكن معالجة الصور الأصغر حجمًا بشكل أسرع، ولتقليل وقت الاستجابة، ننصحك بالتقاط الصور بدرجات دقة أقل (مع الأخذ في الاعتبار متطلبات الدقة المذكورة أعلاه) والتأكّد من أنّ وجه الشخص يشغل أكبر قدر ممكن من الصورة. يمكنك أيضًا الاطّلاع على نصائح لتحسين الأداء في الوقت الفعلي.

يمكن أن يؤثر التركيز الضعيف للصورة على الدقة. وإذا لم تحصل على نتائج مقبولة، حاوِل أن تطلب من المستخدم تلخيص الصورة.

إنّ اتجاه الوجه بالنسبة إلى الكاميرا يمكن أن يؤثّر أيضًا في ملامح الوجه التي ترصدها أداة "تعلُّم الآلة". راجِع مفاهيم ميزة "التعرّف على الوجوه".

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- تشغيل أداة رصد الوجوه

لاكتشاف الوجوه في صورة ما، مرِّر الصورة كـ UIImage أو CMSampleBufferRef إلى طريقة detect(in:) في VisionFaceDetector:

  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. يمكنك إنشاء عنصر VisionImage باستخدام UIImage أو CMSampleBufferRef.

    لاستخدام UIImage:

    1. إذا لزم الأمر، عليك تدوير الصورة لتكون السمة imageOrientation هي .up.
    2. أنشِئ كائن VisionImage باستخدام عنصر UIImage الذي تم تدويره بشكل صحيح. لا تحدِّد أي بيانات وصفية حول عرض الإعلانات بالتناوب، يجب استخدام القيمة التلقائية .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. يمكنك إنشاء عنصر VisionImage باستخدام الكائن CMSampleBufferRef والبيانات الوصفية الخاصة بالتدوير:

      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 (مفعَّل تلقائيًا).

  • يمكنك التقاط صور بدقة أقل. ومع ذلك، ضع في اعتبارك أيضًا متطلبات أبعاد الصورة في واجهة برمجة التطبيقات هذه.

  • التحكُّم في المكالمات الواردة إلى أداة الرصد. إذا أصبح إطار فيديو جديد متاحًا أثناء تشغيل أداة الرصد، أفلِت الإطار.
  • إذا كنت تستخدم ناتج أداة الرصد لتركيب رسومات على الصورة التي تم إدخالها، يمكنك أولاً الحصول على النتيجة من ML Kit، ثم عرض الصورة والمحتوى الذي يظهر على سطح الصورة في خطوة واحدة. ومن خلال إجراء ذلك، ستظهر على سطح الشاشة مرة واحدة فقط لكل إطار إدخال. للاطّلاع على مثال، يمكنك الاطّلاع على الفئتَين previewOverlayView وFIRDetectionOverlayView في نموذج تطبيق العرض