راهنمای تشخیص چهره برای iOS

وظیفه تشخیص چهره به شما امکان می دهد چهره ها را در یک تصویر یا ویدیو تشخیص دهید. می توانید از این کار برای تعیین مکان چهره و ویژگی های صورت در یک قاب استفاده کنید. این کار از یک مدل یادگیری ماشینی (ML) استفاده می کند که با تصاویر منفرد یا یک جریان پیوسته از تصاویر کار می کند. این وظیفه مکان‌های صورت را همراه با نکات کلیدی صورت زیر نمایش می‌دهد: چشم چپ، چشم راست، نوک بینی، دهان، تراژیون چشم چپ و تراژیون چشم راست.

نمونه کد شرح داده شده در این دستورالعمل ها در GitHub موجود است. شما می توانید با مشاهده این نسخه نمایشی وب، این کار را در عمل مشاهده کنید. برای اطلاعات بیشتر در مورد قابلیت‌ها، مدل‌ها و گزینه‌های پیکربندی این کار، به نمای کلی مراجعه کنید.

نمونه کد

کد مثال MediaPipe Tasks یک پیاده سازی ساده از یک برنامه Face Detector برای iOS است. این مثال از دوربین یک دستگاه اندروید فیزیکی برای شناسایی چهره‌ها در یک جریان ویدیویی مداوم استفاده می‌کند. این برنامه همچنین می‌تواند چهره‌ها را در تصاویر و ویدیوهای گالری دستگاه تشخیص دهد.

می‌توانید از برنامه به‌عنوان نقطه شروع برای برنامه iOS خودتان استفاده کنید، یا هنگام تغییر یک برنامه موجود به آن مراجعه کنید. کد نمونه Face Detector در GitHub میزبانی می شود.

کد را دانلود کنید

دستورالعمل های زیر به شما نشان می دهد که چگونه با استفاده از ابزار خط فرمان git یک کپی محلی از کد مثال ایجاد کنید.

برای دانلود کد نمونه:

  1. با استفاده از دستور زیر مخزن git را کلون کنید:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. به صورت اختیاری، نمونه git خود را برای استفاده از پرداخت پراکنده پیکربندی کنید، بنابراین فقط فایل‌های مربوط به برنامه نمونه Face Detector را داشته باشید:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_detector/ios/
    

پس از ایجاد یک نسخه محلی از کد نمونه، می توانید کتابخانه وظایف MediaPipe را نصب کنید، پروژه را با استفاده از Xcode باز کنید و برنامه را اجرا کنید. برای دستورالعمل‌ها، به راهنمای راه‌اندازی برای iOS مراجعه کنید.

اجزای کلیدی

فایل‌های زیر حاوی کد حیاتی برای برنامه مثالی Face Detector هستند:

  • FaceDetectorService.swift : آشکارساز را راه‌اندازی می‌کند، انتخاب مدل را مدیریت می‌کند و استنتاج را روی داده‌های ورودی اجرا می‌کند.
  • CameraViewController : رابط کاربری را برای حالت ورودی تغذیه دوربین زنده پیاده‌سازی می‌کند و نتایج تشخیص را به تصویر می‌کشد.
  • MediaLibraryViewController.swift : رابط کاربری را برای حالت ورودی تصویر ثابت و فایل ویدیویی پیاده‌سازی می‌کند و نتایج تشخیص را به تصویر می‌کشد.

راه اندازی

این بخش مراحل کلیدی را برای تنظیم محیط توسعه و پروژه های کد برای استفاده از Face Detector شرح می دهد. برای اطلاعات کلی در مورد تنظیم محیط توسعه خود برای استفاده از وظایف MediaPipe، از جمله الزامات نسخه پلت فرم، به راهنمای راه اندازی برای iOS مراجعه کنید.

وابستگی ها

Face Detector از کتابخانه MediaPipeTasksVision استفاده می کند که باید با استفاده از CocoaPods نصب شود. این کتابخانه با هر دو برنامه Swift و Objective-C سازگار است و نیازی به تنظیمات زبان خاصی ندارد.

برای دستورالعمل‌های نصب CocoaPods در macOS، به راهنمای نصب CocoaPods مراجعه کنید. برای دستورالعمل‌های نحوه ایجاد یک Podfile با پادهای لازم برای برنامه خود، به استفاده از CocoaPods مراجعه کنید.

با استفاده از کد زیر، MediaPipeTasksVision pod را در Podfile اضافه کنید:

target 'MyFaceDetectorApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

اگر برنامه شما شامل اهداف تست واحد است، برای اطلاعات بیشتر در مورد راه‌اندازی Podfile ، به راهنمای تنظیم برای iOS مراجعه کنید.

مدل

وظیفه آشکارساز چهره MediaPipe به یک مدل آموزش دیده نیاز دارد که با این کار سازگار باشد. برای اطلاعات بیشتر در مورد مدل‌های آموزش‌دیده موجود برای تشخیص چهره، به بخش مدل‌های نمای کلی کار مراجعه کنید.

یک مدل را انتخاب و دانلود کنید و با استفاده از Xcode آن را به فهرست پروژه خود اضافه کنید. برای دستورالعمل‌هایی درباره نحوه افزودن فایل‌ها به پروژه Xcode، به مدیریت فایل‌ها و پوشه‌ها در پروژه Xcode خود مراجعه کنید.

از ویژگی BaseOptions.modelAssetPath برای تعیین مسیر مدل در بسته نرم افزاری خود استفاده کنید. برای مثال کد، بخش بعدی را ببینید.

کار را ایجاد کنید

می توانید با فراخوانی یکی از آغازگرهای آن، وظیفه Face Detector را ایجاد کنید. شروع کننده FaceDetector(options:) مقادیری را برای گزینه های پیکربندی می پذیرد.

اگر نیازی به تشخیص چهره اولیه با گزینه های پیکربندی سفارشی ندارید، می توانید از مقداردهی اولیه FaceDetector(modelPath:) برای ایجاد یک آشکارساز چهره با گزینه های پیش فرض استفاده کنید. برای اطلاعات بیشتر درباره گزینه‌های پیکربندی، به نمای کلی پیکربندی مراجعه کنید.

وظیفه آشکارساز چهره از 3 نوع داده ورودی پشتیبانی می کند: تصاویر ثابت، فایل های ویدیویی و پخش جریانی ویدیویی زنده. به طور پیش فرض، FaceDetector(modelPath:) یک کار را برای تصاویر ثابت مقداردهی اولیه می کند. اگر می‌خواهید وظیفه شما برای پردازش فایل‌های ویدیویی یا پخش جریانی زنده ویدیویی اولیه شود، از FaceDetector(options:) برای تعیین حالت اجرای ویدیو یا پخش زنده استفاده کنید. حالت پخش زنده همچنین به گزینه پیکربندی faceDetectorLiveStreamDelegate اضافی نیاز دارد، که Face Detector را قادر می سازد تا نتایج تشخیص چهره را به صورت ناهمزمان به نماینده ارائه دهد.

برای مشاهده نحوه ایجاد کار و اجرای استنتاج، برگه مربوط به حالت در حال اجرا خود را انتخاب کنید.

سویفت

تصویر

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image

let faceDetector = try FaceDetector(options: options)
    

ویدئو

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video

let faceDetector = try FaceDetector(options: options)
    

پخش زنده

import MediaPipeTasksVision

// Class that conforms to the `FaceDetectorLiveStreamDelegate` protocol and
// implements the method that the face detector calls once it finishes
// detecting faces in each input frame.
class FaceDetectorResultProcessor: NSObject, FaceDetectorLiveStreamDelegate {

  func faceDetector(
    _ faceDetector: FaceDetector,
    didFinishDetection result: FaceDetectorResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the face detection result or errors here.

  }
}

let modelPath = Bundle.main.path(
  forResource: "model",
  ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream

// Assign an object of the class to the `faceDetectorLiveStreamDelegate`
// property.
let processor = FaceDetectorResultProcessor()
options.faceDetectorLiveStreamDelegate = processor

let faceDetector = try FaceDetector(options: options)
    

هدف-C

تصویر

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

ویدئو

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

پخش زنده

@import MediaPipeTasksVision;

// Class that conforms to the `MPPFaceDetectorLiveStreamDelegate` protocol
// and implements the method that the face detector calls once it finishes
// detecting faces in each input frame.

@interface APPFaceDetectorResultProcessor : NSObject 

@end

@implementation APPFaceDetectorResultProcessor

-   (void)faceDetector:(MPPFaceDetector *)faceDetector
    didFinishDetectionWithResult:(MPPFaceDetectorResult *)faceDetectorResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the face detector result or errors here.

}

@end

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;

// Assign an object of the class to the `faceDetectorLiveStreamDelegate`
// property.
APPFaceDetectorResultProcessor *processor = [APPFaceDetectorResultProcessor new];
options.faceDetectorLiveStreamDelegate = processor;

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

توجه: اگر از حالت ویدیو یا حالت پخش زنده استفاده می‌کنید، Face Detector از ردیابی برای جلوگیری از راه‌اندازی مدل تشخیص در هر فریم استفاده می‌کند که به کاهش تأخیر کمک می‌کند.

گزینه های پیکربندی

این کار دارای گزینه های پیکربندی زیر برای برنامه های iOS است:

نام گزینه توضیحات محدوده ارزش مقدار پیش فرض
runningMode حالت اجرا را برای کار تنظیم می کند. سه حالت وجود دارد:

IMAGE: حالت برای ورودی های تک تصویر.

VIDEO: حالت برای فریم های رمزگشایی شده یک ویدیو.

LIVE_STREAM: حالت پخش زنده داده های ورودی، مانند دوربین. در این حالت، resultListener باید فراخوانی شود تا شنونده ای را برای دریافت نتایج به صورت ناهمزمان تنظیم کند.
{ RunningMode.image, RunningMode.video, RunningMode.liveStream } RunningMode.image
minDetectionConfidence حداقل امتیاز اطمینان برای تشخیص چهره موفق در نظر گرفته شود. Float [0,1] 0.5
minSuppressionThreshold حداقل آستانه غیر حداکثری سرکوب برای تشخیص چهره که باید همپوشانی در نظر گرفته شود. Float [0,1] 0.3

پیکربندی پخش زنده

هنگامی که حالت اجرا روی پخش زنده تنظیم می شود، Face Detector به گزینه پیکربندی faceDetectorLiveStreamDelegate اضافی نیاز دارد، که به تشخیص چهره امکان می دهد نتایج تشخیص را به صورت ناهمزمان ارائه دهد. نماینده متد faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) را پیاده سازی می کند که Face Detector پس از پردازش نتایج تشخیص چهره برای هر فریم آن را فراخوانی می کند.

نام گزینه توضیحات محدوده ارزش مقدار پیش فرض
faceDetectorLiveStreamDelegate تشخیص چهره را فعال می کند تا نتایج تشخیص چهره را به صورت ناهمزمان در حالت پخش زنده دریافت کند. کلاسی که نمونه آن روی این ویژگی تنظیم شده است باید متد faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) را پیاده سازی کند. قابل اجرا نیست تنظیم نشده است

داده ها را آماده کنید

قبل از ارسال آن به Face Detector باید تصویر یا فریم ورودی را به یک شی MPImage تبدیل کنید. MPImage از انواع فرمت های تصویر iOS پشتیبانی می کند و می تواند از آنها در هر حالت در حال اجرا برای استنتاج استفاده کند. برای اطلاعات بیشتر در مورد MPImage ، به MPImage API مراجعه کنید.

یک قالب تصویر iOS را بر اساس مورد استفاده خود و حالت اجرای مورد نیاز برنامه خود انتخاب کنید. MPImage فرمت‌های تصویر UIImage ، CVPixelBuffer ، و CMSampleBuffer را می‌پذیرد.

تصویر UII

فرمت UIImage برای حالت‌های اجرای زیر مناسب است:

  • تصاویر: تصاویر از یک بسته نرم افزاری، گالری کاربر یا سیستم فایل فرمت شده به عنوان تصاویر UIImage را می توان به یک شی MPImage تبدیل کرد.

  • ویدیوها: از AVAssetImageGenerator برای استخراج فریم های ویدیو به فرمت CGImage استفاده کنید، سپس آنها را به تصاویر UIImage تبدیل کنید.

سویفت

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(uiImage: image)
    

هدف-C

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

این مثال یک MPImage با جهت پیش‌فرض UIImage.Orientation.Up مقداردهی اولیه می‌کند. می توانید یک MPImage با هر یک از مقادیر UIImage.Orientation پشتیبانی شده مقداردهی کنید. آشکارساز چهره از جهت‌های آینه‌ای مانند .upMirrored ، .downMirrored ، .leftMirrored ، .rightMirrored پشتیبانی نمی‌کند.

برای اطلاعات بیشتر در مورد UIImage ، به UIImage Apple Developer Documentation مراجعه کنید.

CVPixelBuffer

فرمت CVPixelBuffer برای برنامه هایی که فریم تولید می کنند و از چارچوب CoreImage iOS برای پردازش استفاده می کنند، مناسب است.

فرمت CVPixelBuffer برای حالت‌های اجرای زیر مناسب است:

  • تصاویر: برنامه هایی که تصاویر CVPixelBuffer پس از مدتی پردازش با استفاده از چارچوب CoreImage iOS تولید می کنند، می توانند در حالت اجرای تصویر به Face Detector ارسال شوند.

  • فیلم‌ها: فریم‌های ویدیو را می‌توان برای پردازش به فرمت CVPixelBuffer تبدیل کرد و سپس در حالت ویدیو به آشکارساز چهره فرستاد.

  • پخش زنده: برنامه هایی که از دوربین iOS برای تولید فریم استفاده می کنند ممکن است قبل از ارسال به Face Detector در حالت پخش زنده به فرمت CVPixelBuffer برای پردازش تبدیل شوند.

سویفت

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(pixelBuffer: pixelBuffer)
    

هدف-C

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

برای اطلاعات بیشتر در مورد CVPixelBuffer ، به مستندات برنامه‌نویس اپل CVPixelBuffer مراجعه کنید.

CMSampleBuffer

فرمت CMSampleBuffer نمونه‌های رسانه‌ای از یک نوع رسانه یکنواخت را ذخیره می‌کند و برای حالت پخش زنده مناسب است. قاب‌های زنده دوربین‌های iOS به‌صورت ناهمزمان در قالب CMSampleBuffer توسط iOS AVCaptureVideoDataOutput ارائه می‌شوند.

سویفت

// Obtain a CMSampleBuffer.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(sampleBuffer: sampleBuffer)
    

هدف-C

// Obtain a `CMSampleBuffer`.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
    

برای اطلاعات بیشتر در مورد CMSampleBuffer ، به مستندات توسعه دهنده Apple CMSampleBuffer مراجعه کنید.

وظیفه را اجرا کنید

برای اجرای Face Detector، از متد detect() مخصوص حالت اجرای اختصاص داده شده استفاده کنید:

  • تصویر ثابت: detect(image:)
  • ویدیو: detect(videoFrame:timestampInMilliseconds:)
  • پخش زنده: detectAsync(image:timestampInMilliseconds:)

آشکارساز چهره چهره های شناسایی شده را در داخل تصویر یا قاب ورودی برمی گرداند.

نمونه کد زیر نمونه های ساده ای از نحوه اجرای Face Detector در این حالت های مختلف اجرا را نشان می دهد:

سویفت

تصویر

let result = try faceDetector.detect(image: image)
    

ویدئو

let result = try faceDetector.detect(
  videoFrame: image,
  timestampInMilliseconds: timestamp)
    

پخش زنده

try faceDetector.detectAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

هدف-C

تصویر

MPPFaceDetectorResult *result = [faceDetector detectInImage:image
                                                      error:nil];
    

ویدئو

MPPFaceDetectorResult *result = [faceDetector detectInVideoFrame:image
                                         timestampInMilliseconds:timestamp
                                                           error:nil];
    

پخش زنده

BOOL success = [faceDetector detectAsyncInImage:image
                        timestampInMilliseconds:timestamp
                                          error:nil];
    

مثال کد Face Detector پیاده‌سازی هر یک از این حالت‌ها را با جزئیات بیشتری نشان می‌دهد detect(image:) , detect(videoFrame:timestampInMilliseconds:) و detectAsync(image:timestampInMilliseconds:) . کد مثال به کاربر اجازه می دهد تا بین حالت های پردازشی که ممکن است برای مورد استفاده شما مورد نیاز نباشد جابجا شود.

به موارد زیر توجه کنید:

  • هنگام اجرا در حالت ویدیو یا حالت پخش زنده، باید مهر زمانی فریم ورودی را نیز به وظیفه Face Detector ارائه دهید.

  • هنگامی که در حالت تصویر یا ویدیو اجرا می شود، وظیفه آشکارساز چهره رشته فعلی را مسدود می کند تا زمانی که پردازش تصویر یا فریم ورودی به پایان برسد. برای جلوگیری از مسدود کردن رشته فعلی، پردازش را در یک رشته پس‌زمینه با استفاده از چارچوب‌های iOS Dispatch یا NSOperation انجام دهید.

  • هنگامی که در حالت پخش زنده اجرا می شود، وظیفه آشکارساز چهره بلافاصله برمی گردد و رشته فعلی را مسدود نمی کند. پس از پردازش هر فریم ورودی، متد faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) را با نتیجه تشخیص چهره فراخوانی می کند. Face Detector این روش را به صورت ناهمزمان در یک صف پخش سریال اختصاصی فراخوانی می کند. برای نمایش نتایج در رابط کاربری، پس از پردازش نتایج، نتایج را به صف اصلی ارسال کنید. اگر زمانی که وظیفه Face Detector مشغول پردازش فریم دیگری است، تابع detectAsync فراخوانی شود، Face Detector قاب ورودی جدید را نادیده می گیرد.

کنترل و نمایش نتایج

پس از اجرای استنتاج، وظیفه Face Detector یک شی FaceDetectorResult را برمی‌گرداند که شامل کادرهای مرزی برای چهره‌های شناسایی‌شده و یک امتیاز اطمینان برای هر چهره شناسایی‌شده است.

در زیر نمونه ای از داده های خروجی از این کار را نشان می دهد:

FaceDetectionResult:
  Detections:
    Detection #0:
      BoundingBox:
        origin_x: 126
        origin_y: 100
        width: 463
        height: 463
      Categories:
        Category #0:
          index: 0
          score: 0.9729152917861938
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.18298381567001343
          y: 0.2961040139198303
        NormalizedKeypoint #1:
          x: 0.3302789330482483
          y: 0.29289937019348145
        ... (6 keypoints for each face)
    Detection #1:
      BoundingBox:
        origin_x: 616
        origin_y: 193
        width: 430
        height: 430
      Categories:
        Category #0:
          index: 0
          score: 0.9251380562782288
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.6151331663131714
          y: 0.3713381886482239
        NormalizedKeypoint #1:
          x: 0.7460576295852661
          y: 0.38825345039367676
        ... (6 keypoints for each face)

تصویر زیر تصویری از خروجی کار را نشان می دهد:

برای تصویر بدون کادرهای محدود، تصویر اصلی را ببینید.

کد نمونه Face Detector نحوه نمایش نتایج را نشان می دهد. برای جزئیات بیشتر به مثال کد مراجعه کنید.