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

وظیفه MediaPipe Face Landmarker به شما امکان می‌دهد نشانه‌های چهره و حالات چهره را در تصاویر و ویدیوها تشخیص دهید. می‌توانید از این وظیفه برای شناسایی حالات چهره انسان، اعمال فیلترها و جلوه‌های چهره و ایجاد آواتارهای مجازی استفاده کنید. این وظیفه از مدل‌های یادگیری ماشین (ML) استفاده می‌کند که می‌توانند با تصاویر واحد یا جریان پیوسته‌ای از تصاویر کار کنند. این وظیفه، نشانه‌های سه‌بعدی چهره، نمرات blendshape (ضرایب نشان دهنده حالات چهره) را برای استنباط سطوح دقیق چهره در زمان واقعی و ماتریس‌های تبدیل را برای انجام تبدیل‌های مورد نیاز برای رندر جلوه‌ها، خروجی می‌دهد.

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

مثال کد

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

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

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

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

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

  1. مخزن git را با استفاده از دستور زیر کلون کنید:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. به صورت اختیاری، نمونه گیت خود را طوری پیکربندی کنید که از پرداخت پراکنده استفاده کند، تا فقط فایل‌های مربوط به برنامه نمونه Face Landmarker را داشته باشید:
    cd mediapipe-samples
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_landmarker/android
    

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

اجزای کلیدی

فایل‌های زیر حاوی کد حیاتی برای این نمونه برنامه‌ی علامت‌گذاری چهره هستند:

  • FaceLandmarkerHelper.kt - نشانگر چهره را مقداردهی اولیه می‌کند و انتخاب مدل و نماینده را مدیریت می‌کند.
  • CameraFragment.kt - دوربین دستگاه را مدیریت کرده و داده‌های ورودی تصویر و ویدیو را پردازش می‌کند.
  • GalleryFragment.kt - برای نمایش تصویر یا ویدیوی خروجی با OverlayView تعامل دارد.
  • OverlayView.kt - نمایش چهره‌های شناسایی‌شده را با استفاده از یک شبکه چهره پیاده‌سازی می‌کند.

راه‌اندازی

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

وابستگی‌ها

وظیفه Face Landmarker از کتابخانه com.google.mediapipe:tasks-vision استفاده می‌کند. این وابستگی را به فایل build.gradle برنامه اندروید خود اضافه کنید:

dependencies {
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

مدل

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

مدل را انتخاب و دانلود کنید و آن را در دایرکتوری پروژه خود ذخیره کنید:

<dev-project-root>/src/main/assets

مسیر مدل را در پارامتر ModelAssetPath مشخص کنید. در کد مثال، مدل در فایل FaceLandmarkerHelper.kt تعریف شده است:

baseOptionsBuilder.setModelAssetPath(MP_FACE_LANDMARKER_TASK)

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

وظیفه‌ی MediaPipe Face Landmarker از تابع createFromOptions() برای تنظیم وظیفه استفاده می‌کند. تابع createFromOptions() مقادیری را برای گزینه‌های پیکربندی می‌پذیرد. برای اطلاعات بیشتر در مورد گزینه‌های پیکربندی، به Configuration options مراجعه کنید.

ابزار Face Landmarker از انواع داده‌های ورودی زیر پشتیبانی می‌کند: تصاویر ثابت، فایل‌های ویدیویی و پخش زنده ویدیو. هنگام ایجاد وظیفه، باید حالت اجرای مربوط به نوع داده ورودی خود را مشخص کنید. برای مشاهده نحوه ایجاد وظیفه و اجرای استنتاج، برگه مربوط به نوع داده ورودی خود را انتخاب کنید.

تصویر

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_FACE_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()
FaceLandmarker = FaceLandmarker.createFromOptions(context, options)
    

ویدئو

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_FACE_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()
FaceLandmarker = FaceLandmarker.createFromOptions(context, options)
    

پخش زنده

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_FACE_LANDMARKER_TASK)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    FaceLandmarker.FaceLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinFaceDetectionConfidence(minFaceDetectionConfidence)
        .setMinTrackingConfidence(minFaceTrackingConfidence)
        .setMinFacePresenceConfidence(minFacePresenceConfidence)
        .setNumFaces(maxNumFaces)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()
FaceLandmarker = FaceLandmarker.createFromOptions(context, options)
    

پیاده‌سازی کد نمونه‌ی Face Landmarker به کاربر اجازه می‌دهد بین حالت‌های پردازش جابجا شود. این رویکرد، کد ایجاد وظیفه را پیچیده‌تر می‌کند و ممکن است برای مورد استفاده‌ی شما مناسب نباشد. می‌توانید این کد را در تابع setupFaceLandmarker() در فایل FaceLandmarkerHelper.kt مشاهده کنید.

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

این وظیفه گزینه‌های پیکربندی زیر را برای برنامه‌های اندروید دارد:

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

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

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

LIVE_STREAM: حالتی برای پخش زنده داده‌های ورودی، مثلاً از یک دوربین. در این حالت، باید resultListener فراخوانی شود تا یک شنونده برای دریافت نتایج به صورت غیرهمزمان تنظیم شود.
{ IMAGE, VIDEO, LIVE_STREAM } IMAGE
numFaces حداکثر تعداد چهره‌هایی که می‌توانند توسط FaceLandmarker شناسایی شوند. هموارسازی فقط زمانی اعمال می‌شود که num_faces روی ۱ تنظیم شده باشد. Integer > 0 1
minFaceDetectionConfidence حداقل امتیاز اطمینان برای تشخیص چهره که موفقیت‌آمیز تلقی شود. Float [0.0,1.0] 0.5
minFacePresenceConfidence حداقل امتیاز اطمینان از امتیاز حضور چهره در تشخیص نشانه‌های چهره. Float [0.0,1.0] 0.5
minTrackingConfidence حداقل امتیاز اطمینان برای اینکه ردیابی چهره موفقیت‌آمیز تلقی شود. Float [0.0,1.0] 0.5
outputFaceBlendshapes آیا خروجی Face Landmarker ترکیبی از شکل‌های چهره است یا خیر. شکل‌های ترکیبی چهره برای رندر مدل سه‌بعدی چهره استفاده می‌شوند. Boolean False
outputFacialTransformationMatrixes اینکه آیا FaceLandmarker ماتریس تبدیل چهره را خروجی می‌دهد یا خیر. FaceLandmarker از این ماتریس برای تبدیل نشانه‌های چهره از یک مدل چهره استاندارد به چهره شناسایی شده استفاده می‌کند، بنابراین کاربران می‌توانند جلوه‌هایی را روی نشانه‌های شناسایی شده اعمال کنند. Boolean False
resultListener شنونده نتیجه را طوری تنظیم می‌کند که وقتی FaceLandmarker در حالت پخش زنده است، نتایج نشانگر را به صورت غیرهمزمان دریافت کند. فقط زمانی قابل استفاده است که حالت اجرا روی LIVE_STREAM تنظیم شده باشد. ResultListener N/A
errorListener یک شنونده‌ی خطای اختیاری تنظیم می‌کند. ErrorListener N/A

آماده‌سازی داده‌ها

Face Landmarker با تصاویر، فایل‌های ویدیویی و پخش زنده ویدیو کار می‌کند. این وظیفه، پیش‌پردازش داده‌های ورودی، از جمله تغییر اندازه، چرخش و نرمال‌سازی مقادیر را بر عهده دارد.

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

تصویر

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(image).build()
    

ویدئو

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

val argb8888Frame =
    if (frame.config == Bitmap.Config.ARGB_8888) frame
    else frame.copy(Bitmap.Config.ARGB_8888, false)

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(argb8888Frame).build()
    

پخش زنده

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(rotatedBitmap).build()
    

در کد مثال Face Landmarker، آماده‌سازی داده‌ها در فایل FaceLandmarkerHelper.kt انجام می‌شود.

اجرای وظیفه

بسته به نوع داده‌ای که با آن کار می‌کنید، از متد FaceLandmarker.detect...() که مختص آن نوع داده است، استفاده کنید. برای تصاویر تکی detect() ، برای فریم‌های فایل‌های ویدیویی detectForVideo() و برای جریان‌های ویدیویی detectAsync() استفاده کنید. هنگام انجام تشخیص‌ها روی یک جریان ویدیویی، مطمئن شوید که تشخیص‌ها را در یک رشته جداگانه اجرا می‌کنید تا از مسدود شدن رشته رابط کاربری جلوگیری شود.

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

تصویر

val result = FaceLandmarker.detect(mpImage)
    

ویدئو

val timestampMs = i * inferenceIntervalMs

FaceLandmarker.detectForVideo(mpImage, timestampMs)
    .let { detectionResult ->
        resultList.add(detectionResult)
    }
    

پخش زنده

val mpImage = BitmapImageBuilder(rotatedBitmap).build()
val frameTime = SystemClock.uptimeMillis()

FaceLandmarker.detectAsync(mpImage, frameTime)
    

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

  • هنگام اجرا در حالت ویدیو یا حالت پخش زنده، باید مهر زمانی فریم ورودی را به وظیفه Face Landmarker ارائه دهید.
  • هنگام اجرا در حالت تصویر یا ویدیو، وظیفه Face Landmarker تا زمانی که پردازش تصویر یا فریم ورودی را تمام کند، رشته فعلی را مسدود می‌کند. برای جلوگیری از مسدود شدن رابط کاربری، پردازش را در یک رشته پس‌زمینه اجرا کنید.
  • هنگام اجرا در حالت پخش زنده، وظیفه Face Landmarker بلافاصله برمی‌گردد و رشته فعلی را مسدود نمی‌کند. هر بار که پردازش یک فریم ورودی را به پایان می‌رساند، شنونده نتیجه را با نتیجه تشخیص فراخوانی می‌کند.

در کد مثال Face Landmarker، توابع detect ، detectForVideo و detectAsync در فایل FaceLandmarkerHelper.kt تعریف شده‌اند.

مدیریت و نمایش نتایج

ابزار Face Landmarker برای هر اجرای تشخیص، یک شیء FaceLandmarkerResult برمی‌گرداند. شیء نتیجه شامل یک مش چهره برای هر چهره شناسایی‌شده، به همراه مختصات هر نقطه عطف چهره است. به صورت اختیاری، شیء نتیجه می‌تواند شامل شکل‌های ترکیبی (blendshapes) که نشان‌دهنده حالات چهره هستند و یک ماتریس تبدیل چهره برای اعمال جلوه‌های چهره بر روی نقاط عطف شناسایی‌شده نیز باشد.

در زیر نمونه‌ای از داده‌های خروجی این وظیفه نشان داده شده است:

FaceLandmarkerResult:
  face_landmarks:
    NormalizedLandmark #0:
      x: 0.5971359014511108
      y: 0.485361784696579
      z: -0.038440968841314316
    NormalizedLandmark #1:
      x: 0.3302789330482483
      y: 0.29289937019348145
      z: -0.09489090740680695
    ... (478 landmarks for each face)
  face_blendshapes:
    browDownLeft: 0.8296722769737244
    browDownRight: 0.8096957206726074
    browInnerUp: 0.00035583582939580083
    browOuterUpLeft: 0.00035752105759456754
    ... (52 blendshapes for each face)
  facial_transformation_matrixes:
    [9.99158978e-01, -1.23036895e-02, 3.91213447e-02, -3.70770246e-01]
    [1.66496094e-02,  9.93480563e-01, -1.12779640e-01, 2.27719707e+01]
    ...

تصویر زیر، خروجی این وظیفه را به صورت بصری نشان می‌دهد:

مردی که نواحی صورتش به صورت هندسی ترسیم شده تا شکل و ابعاد صورتش را نشان دهد

کد مثال Face Landmarker نحوه نمایش نتایج برگردانده شده از این وظیفه را نشان می‌دهد، برای جزئیات بیشتر به کلاس OverlayView مراجعه کنید.