คำแนะนำในการตรวจจับใบหน้าสำหรับ Android

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

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

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

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

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

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

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

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

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

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

คอมโพเนนต์หลัก

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

  • FaceDetectorHelper.kt - เริ่มต้นตัวตรวจจับใบหน้า รวมถึงจัดการโมเดลและการเลือกผู้รับมอบสิทธิ์
  • CameraFragment.kt - จัดการกล้องของอุปกรณ์และประมวลผลข้อมูลอินพุตรูปภาพและวิดีโอ
  • GalleryFragment.kt - โต้ตอบกับ OverlayView เพื่อแสดงรูปภาพหรือวิดีโอเอาต์พุต
  • OverlayView.kt - ใช้จอแสดงผลที่มีกล่องขอบเขตสำหรับใบหน้าที่ตรวจพบ

ตั้งค่า

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

การอ้างอิง

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

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

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

รูปภาพ

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

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

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

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

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

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

LIVE_STREAM: โหมดสตรีมแบบสดของข้อมูลอินพุต เช่น จากกล้อง ในโหมดนี้ คุณต้องเรียกใช้ resultListener เพื่อตั้งค่า Listener เพื่อรับผลลัพธ์แบบไม่พร้อมกัน
{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

เตรียมข้อมูล

เครื่องมือตรวจจับใบหน้าใช้งานได้กับรูปภาพ ไฟล์วิดีโอ และสตรีมวิดีโอสด งานจะจัดการการประมวลผลข้อมูลอินพุตก่อนการประมวลผล ซึ่งรวมถึงการปรับขนาด การหมุน และการปรับค่าให้เป็นไปตามมาตรฐาน

โค้ดต่อไปนี้แสดงวิธีส่งต่อข้อมูลเพื่อประมวลผล ตัวอย่างเหล่านี้มีรายละเอียดเกี่ยวกับวิธีจัดการข้อมูลจากรูปภาพ ไฟล์วิดีโอ และสตรีมวิดีโอสด

รูปภาพ

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()
    

ในโค้ดตัวอย่างโปรแกรมตรวจจับใบหน้า ระบบจะจัดการการเตรียมข้อมูลในไฟล์ 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 จะแสดงผลทันทีและไม่บล็อกเธรดปัจจุบัน โดยจะเรียกใช้โปรแกรมรับฟังผลลัพธ์พร้อมผลการตรวจจับทุกครั้งที่ประมวลผลเฟรมอินพุตเสร็จสิ้น หากมีการเรียกใช้ฟังก์ชันการตรวจจับเมื่องานตัวตรวจจับใบหน้ากำลังประมวลผลเฟรมอื่นอยู่ งานจะละเว้นเฟรมอินพุตใหม่

ในโค้ดตัวอย่างโปรแกรมตรวจจับใบหน้า ฟังก์ชัน detect, detectForVideo และ detectAsync จะกำหนดไว้ในไฟล์ FaceDetectorHelper.kt

จัดการและแสดงผลลัพธ์

เครื่องมือตรวจจับใบหน้าจะแสดงผลออบเจ็กต์ 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)

รูปภาพต่อไปนี้แสดงภาพเอาต์พุตของงาน

เด็ก 2 คนที่มีกล่องขอบเขตรอบใบหน้า

สำหรับรูปภาพที่ไม่มีกรอบล้อมรอบ โปรดดูรูปภาพต้นฉบับ

โค้ดตัวอย่างของ Face Detector แสดงวิธีแสดงผลลัพธ์ที่ได้จากงาน ดูรายละเอียดเพิ่มเติมได้ที่คลาส OverlayView