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

تنظيم صفحاتك في مجموعات يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.

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

قبل البدء

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

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

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

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

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

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

1- إعداد أداة رصد الوجه

قبل تطبيق ميزة "التعرّف على الوجه" على صورة، إذا كنت تريد تغيير أيٍّ من الإعدادات التلقائية لأداة رصد الوجه، حدِّد هذه الإعدادات باستخدام عنصر FaceDetectorOptions. يمكنك تغيير الإعدادات التالية:

الإعدادات
performanceMode fast (تلقائي) | accurate

تفضيل السرعة أو الدقة عند التعرّف على الوجوه

landmarkMode none (تلقائي) | all

تحديد ما إذا كنت تريد محاولة التعرّف على علامات الوجه أو علامات الاقتباس أو العيون أو الأذنين أو الأنف أو الخدين أو الفم أو كل الوجوه التي تم رصدها

contourMode none (تلقائي) | all

لتحديد ما إذا كانت ملامح الوجه مفعّلة أم لا. يتم التعرّف على الاكتشادات للوجه الأكثر بروزًا في الصورة.

classificationMode none (تلقائي) | all

لتحديد ما إذا كان مطلوبًا تصنيف الوجوه ضمن فئات مثل &&;;;;;; فسيل&م فكهر; و&;;عينة مفتوحة&quot:

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's captureOutput(_, didOutput:from:) للحصول على النتائج بشكل متزامن من إطار الفيديو المحدّد. ابقَ على AVCaptureVideoDataOutput&36 alwaysDiscardsLateVideoFrames كـ true للتحكُّم في المكالمات إلى أداة الرصد. سيتم تجاهل إطار فيديو جديد أثناء تشغيل أداة الرصد.
  • إذا كنت تستخدم ناتج أداة الكشف لتراكب الرسومات على الصورة المُدخلة، عليك أولاً الحصول على النتيجة من حزمة تعلّم الآلة، ثم عرض الصورة والتراكب على خطوة واحدة. يؤدي إجراء ذلك إلى عرض لوحة البيانات على الشاشة مرة واحدة فقط لكل إطار إدخال تمت معالجته. للاطّلاع على مثال، يمكنك الاطّلاع على updatepreviewتراكبViewWithLastframe في نموذج البدء السريع لتطبيق ML Kit.