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

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

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

نمونه کد

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

می‌توانید از برنامه به‌عنوان نقطه شروع برای برنامه اندرویدی خود استفاده کنید یا هنگام تغییر برنامه موجود به آن مراجعه کنید. کد نمونه 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/android
    

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

اجزای کلیدی

فایل‌های زیر حاوی کد حیاتی برای این برنامه کاربردی تشخیص چهره هستند:

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

برپایی

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

وابستگی ها

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

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

مدل

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

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

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

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

val modelName = "face_detection_short_range.tflite"
baseOptionsBuilder.setModelAssetPath(modelName)

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

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

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

تصویر

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

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

ویدئو

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

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

پخش زنده

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

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

پیاده‌سازی کد نمونه Face Detector به کاربر اجازه می‌دهد بین حالت‌های پردازش سوئیچ کند. این رویکرد کد ایجاد کار را پیچیده‌تر می‌کند و ممکن است برای مورد استفاده شما مناسب نباشد. می توانید این کد را در تابع setupFaceDetector() در فایل FaceDetectorHelper.kt مشاهده کنید.

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

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

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

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

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

LIVE_STREAM: حالت پخش زنده داده های ورودی، مانند دوربین. در این حالت، resultListener باید فراخوانی شود تا شنونده ای را برای دریافت نتایج به صورت ناهمزمان تنظیم کند.
{ IMAGE, VIDEO, LIVE_STREAM } IMAGE
minDetectionConfidence حداقل امتیاز اطمینان برای تشخیص چهره موفق در نظر گرفته شود. Float [0,1] 0.5
minSuppressionThreshold حداقل آستانه غیر حداکثری سرکوب برای تشخیص چهره که باید همپوشانی در نظر گرفته شود. Float [0,1] 0.3
resultListener شنونده نتیجه را طوری تنظیم می کند که وقتی آشکارساز چهره در حالت پخش زنده است، نتایج تشخیص را به صورت ناهمزمان دریافت کند. فقط زمانی قابل استفاده است که حالت اجرا روی LIVE_STREAM تنظیم شده باشد. N/A Not set
errorListener یک شنونده خطای اختیاری را تنظیم می کند. N/A Not set

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

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

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

تصویر

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 Detector، آماده سازی داده ها در فایل FaceDetectorHelper.kt انجام می شود.

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

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

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

تصویر

val result = faceDetector.detect(mpImage)
    

ویدئو

val timestampMs = i * inferenceIntervalMs

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

پخش زنده

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

faceDetector.detectAsync(mpImage, frameTime)
    

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

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

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

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

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 نحوه نمایش نتایج بازگشتی از کار را نشان می دهد، برای جزئیات بیشتر به کلاس OverlayView مراجعه کنید.