คู่มือการตรวจหาจุดสังเกตสำหรับใบหน้าสำหรับ Android

งาน MediaPipe Face Landmarker ช่วยให้คุณตรวจจับจุดสังเกตบนใบหน้าและการแสดงสีหน้าในรูปภาพและวิดีโอได้ คุณสามารถใช้โมเดลนี้เพื่อระบุการแสดงสีหน้าของมนุษย์ ใช้ฟิลเตอร์และเอฟเฟกต์ใบหน้า รวมถึงสร้างอวตารเสมือนได้ งานนี้ใช้โมเดลแมชชีนเลิร์นนิง (ML) ที่ใช้ได้กับรูปภาพเดี่ยวหรือสตรีมรูปภาพต่อเนื่อง งานจะแสดงผลจุดสังเกตบนใบหน้าแบบ 3 มิติ คะแนน Blendshape (สัมประสิทธิ์ที่แสดงถึงการแสดงออกทางสีหน้า) เพื่ออนุมานพื้นผิวใบหน้าแบบละเอียดในแบบเรียลไทม์ และเมทริกซ์การแปลงเพื่อทำการแปลงที่จำเป็นสำหรับการแสดงผลเอฟเฟกต์

ตัวอย่างโค้ดที่อธิบายไว้ในวิธีการเหล่านี้พร้อมให้บริการบน GitHub ดูข้อมูลเพิ่มเติมเกี่ยวกับความสามารถ โมเดล และตัวเลือกการกำหนดค่า ของงานนี้ได้ที่ภาพรวม

ตัวอย่างโค้ด

ตัวอย่างโค้ดของ MediaPipe Tasks เป็นการติดตั้งใช้งานแอป Face Landmarker อย่างง่ายสำหรับ Android ตัวอย่างนี้ใช้กล้องในอุปกรณ์ Android จริงเพื่อ ตรวจจับใบหน้าในวิดีโอสตรีมอย่างต่อเนื่อง นอกจากนี้ แอปยังตรวจจับใบหน้าใน รูปภาพและวิดีโอจากแกลเลอรีของอุปกรณ์ได้ด้วย

คุณสามารถใช้แอปเป็นจุดเริ่มต้นสำหรับแอป Android ของคุณเอง หรือใช้เป็นข้อมูลอ้างอิง เมื่อแก้ไขแอปที่มีอยู่ โค้ดตัวอย่างของ Face Landmarker โฮสต์อยู่ใน GitHub

ดาวน์โหลดรหัส

วิธีการต่อไปนี้จะแสดงวิธีสร้างสำเนาโค้ดตัวอย่างในเครื่องโดยใช้เครื่องมือบรรทัดคำสั่ง git

วิธีดาวน์โหลดโค้ดตัวอย่าง

  1. โคลนที่เก็บ Git โดยใช้คำสั่งต่อไปนี้
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. คุณจะกำหนดค่าอินสแตนซ์ Git ให้ใช้การชำระเงินแบบ Sparse หรือไม่ก็ได้ เพื่อให้มี เฉพาะไฟล์สำหรับแอปตัวอย่าง Face Landmarker
    cd mediapipe-samples
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_landmarker/android
    

หลังจากสร้างโค้ดตัวอย่างเวอร์ชันในเครื่องแล้ว คุณจะนำเข้าโปรเจ็กต์ ไปยัง Android Studio และเรียกใช้แอปได้ ดูวิธีการได้ที่คู่มือการตั้งค่าสำหรับ Android

องค์ประกอบหลัก

ไฟล์ต่อไปนี้มีโค้ดที่สำคัญสำหรับแอปพลิเคชันตัวอย่างการทำเครื่องหมายใบหน้า นี้

  • FaceLandmarkerHelper.kt - Initializes the face landmarker and handles the model and delegate selection.
  • CameraFragment.kt - จัดการกล้องของอุปกรณ์และประมวลผลข้อมูลอินพุตของรูปภาพและวิดีโอ
  • GalleryFragment.kt - โต้ตอบกับ OverlayView เพื่อแสดงรูปภาพหรือวิดีโอเอาต์พุต
  • OverlayView.kt - ใช้การแสดงผลที่มีมาสก์ใบหน้าสำหรับใบหน้าที่ตรวจพบ

ตั้งค่า

ส่วนนี้จะอธิบายขั้นตอนสำคัญในการตั้งค่าสภาพแวดล้อมในการพัฒนาและโปรเจ็กต์โค้ดเพื่อใช้ Face Landmarker โดยเฉพาะ ดูข้อมูลทั่วไปเกี่ยวกับการตั้งค่าสภาพแวดล้อมการพัฒนาเพื่อใช้ MediaPipe Tasks รวมถึงข้อกำหนดด้านเวอร์ชันแพลตฟอร์มได้ที่คู่มือการตั้งค่าสำหรับ Android

แท็กเริ่มการทำงาน

งาน Face Landmarker ใช้ไลบรารี com.google.mediapipe:tasks-vision เพิ่มทรัพยากร Dependency นี้ลงในไฟล์ build.gradle ของแอป Android

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() ยอมรับค่าสำหรับตัวเลือกการกำหนดค่า ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกการกำหนดค่าได้ที่ตัวเลือกการกำหนดค่า

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 ช่วยให้ผู้ใช้สลับระหว่างโหมดการประมวลผลได้ แนวทางนี้ทำให้โค้ดการสร้างงานมีความซับซ้อนมากขึ้นและอาจไม่เหมาะสมกับ Use Case ของคุณ คุณดูโค้ดนี้ได้ในฟังก์ชัน setupFaceLandmarker() ในไฟล์ FaceLandmarkerHelper.kt

ตัวเลือกการกำหนดค่า

งานนี้มีตัวเลือกการกำหนดค่าต่อไปนี้สำหรับแอป Android

ชื่อตัวเลือก คำอธิบาย ช่วงค่า ค่าเริ่มต้น
runningMode ตั้งค่าโหมดการทำงานสำหรับงาน มี 3 โหมด ดังนี้

รูปภาพ: โหมดสำหรับอินพุตรูปภาพเดียว

วิดีโอ: โหมดสำหรับเฟรมที่ถอดรหัสแล้วของวิดีโอ

LIVE_STREAM: โหมดสำหรับไลฟ์สดของข้อมูลอินพุต เช่น จากกล้อง ในโหมดนี้ ต้องเรียกใช้ resultListener เพื่อตั้งค่า Listener ให้รับผลลัพธ์แบบไม่พร้อมกัน
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
numFaces จำนวนใบหน้าสูงสุดที่ FaceLandmarker ตรวจจับได้ การปรับให้เรียบจะมีผลเมื่อตั้งค่า num_faces เป็น 1 เท่านั้น 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 จะแสดงผล Face Blendshape หรือไม่ ระบบจะใช้รูปร่างผสมใบหน้าในการแสดงผลโมเดลใบหน้า 3 มิติ Boolean False
outputFacialTransformationMatrixes กำหนดว่า FaceLandmarker จะแสดงเมตริกซ์การเปลี่ยนรูปแบบใบหน้าหรือไม่ FaceLandmarker ใช้เมทริกซ์ เพื่อเปลี่ยนเครื่องหมายใบหน้าจากโมเดลใบหน้ามาตรฐานเป็น ใบหน้าที่ตรวจพบ เพื่อให้ผู้ใช้ใช้เอฟเฟกต์กับเครื่องหมายที่ตรวจพบได้ Boolean False
resultListener ตั้งค่า Listener ผลลัพธ์เพื่อรับผลลัพธ์ของ Landmarker แบบไม่พร้อมกันเมื่อ 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 สำหรับการตรวจจับแต่ละครั้ง ออบเจ็กต์ผลลัพธ์มี Face Mesh สำหรับใบหน้าที่ตรวจพบแต่ละใบหน้า พร้อม พิกัดสำหรับจุดสังเกตของใบหน้าแต่ละจุด ออบเจ็กต์ผลลัพธ์อาจมีรูปร่างผสมซึ่งแสดงถึงการแสดงออกทางสีหน้า และเมทริกซ์การเปลี่ยนรูปใบหน้าเพื่อใช้เอฟเฟกต์ใบหน้ากับจุดสังเกตที่ตรวจพบด้วย

ตัวอย่างต่อไปนี้แสดงข้อมูลเอาต์พุตจากงานนี้

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