التعرّف على الوجوه باستخدام حزمة تعلُّم الآلة على أجهزة 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'
    
    بعد تثبيت مجموعات مشروعك الصغيرة أو تحديثها، احرص على فتح ملف Xcode باستخدام .xcworkspace.
  3. في تطبيقك، استورد Firebase:

    Swift

    import Firebase

    Objective-C

    @import Firebase;

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

يجب أن تحتوي الصور المدخلة على وجوه لكي يتمكّن تطبيق ML Kit من رصد الوجوه بدقة. التي يتم تمثيلها ببيانات بكسل كافية. بشكل عام، يجب تخصيص كل وجه تريده يجب أن يكون استكشافه في صورة 100x100 بكسل على الأقل. إذا كنت تريد اكتشاف لمحيطات الوجوه، تتطلب أدوات "تعلّم الآلة" مدخلات عالية الدقة: يجب أن يكون كل وجه يجب أن يكون حجمها 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 الفئات في نموذج تطبيق العرض كمثال.