رصد الوجوه باستخدام حزمة تعلّم الآلة على نظام التشغيل iOS

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

جرّبه الآن

قبل البدء

  1. تضمين مجموعات ML Kit التالية في Podfile:
    pod 'GoogleMLKit/FaceDetection', '3.2.0'
    
  2. بعد تثبيت لوحات مشروعك أو تحديثها، افتح مشروع Xcode باستخدام .xcworkspace تتوفّر حزمة تعلّم الآلة في الإصدار 12.4 من Xcode أو الإصدارات الأحدث.

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

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

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

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

يمكن أن يؤثر اتجاه الوجه بالنسبة إلى الكاميرا أيضًا في الشكل الميزات التي يكتشفها تعلّم الآلة. عرض مفاهيم التعرّف على الوجوه:

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. تحضير صورة الإدخال

لاكتشاف الوجوه في صورة ما، يمكنك ضبط الصورة كـ UIImage أو من CMSampleBufferRef إلى FaceDetector باستخدام إما الطريقة process(_:completion:) أو results(in:):

إنشاء عنصر VisionImage باستخدام UIImage أو CMSampleBuffer

إذا كنت تستخدم UIImage، يُرجى اتّباع الخطوات التالية:

  • أنشئ كائن VisionImage باستخدام UIImage. تأكَّد من تحديد قيمة .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;
      }
    }
          
  • إنشاء عنصر VisionImage باستخدام عنصر CMSampleBuffer والاتجاه:

    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 لضبط الاتصالات الموجَّهة إلى أداة الرصد. إذا كانت تجربة يصبح إطار الفيديو متاحًا أثناء تشغيل أداة الكشف، وسيتم إسقاطه.
  • إذا استخدمت مخرجات أداة الكشف لتراكب الرسومات على الصورة المدخلة، والحصول أولاً على النتيجة من ML Kit، ثم عرض الصورة وتراكبها في خطوة واحدة. ومن خلال القيام بذلك، يمكنك العرض على سطح الشاشة مرة واحدة فقط لكل إطار إدخال تمت معالجته. راجع updatePreviewOverlayViewWithLastFrame في عينة البدء السريع لأدوات تعلُّم الآلة كمثال.