ตรวจจับใบหน้าด้วย ML Kit บน Android

คุณสามารถใช้ ML Kit เพื่อตรวจจับใบหน้าในรูปภาพและวิดีโอ

ก่อนที่คุณจะเริ่ม

  1. หากคุณยังไม่ได้ เพิ่ม Firebase ในโครงการ Android ของคุณ
  2. เพิ่มการพึ่งพาสำหรับไลบรารี ML Kit Android ให้กับไฟล์ Gradle ของโมดูล (ระดับแอป) (โดยปกติคือ app/build.gradle ):
    apply plugin: 'com.android.application'
    apply plugin: 'com.google.gms.google-services'
    
    dependencies {
      // ...
    
      implementation 'com.google.firebase:firebase-ml-vision:24.0.3'
      // If you want to detect face contours (landmark detection and classification
      // don't require this additional model):
      implementation 'com.google.firebase:firebase-ml-vision-face-model:20.0.1'
    }
    
  3. ไม่บังคับแต่แนะนำ : กำหนดค่าแอปของคุณให้ดาวน์โหลดโมเดล ML ลงในอุปกรณ์โดยอัตโนมัติหลังจากติดตั้งแอปจาก Play Store

    โดยเพิ่มการประกาศต่อไปนี้ลงในไฟล์ AndroidManifest.xml ของแอปของคุณ:

    <application ...>
      ...
      <meta-data
          android:name="com.google.firebase.ml.vision.DEPENDENCIES"
          android:value="face" />
      <!-- To use multiple models: android:value="face,model2,model3" -->
    </application>
    
    หากคุณไม่เปิดใช้งานการดาวน์โหลดโมเดลเวลาติดตั้ง โมเดลจะถูกดาวน์โหลดในครั้งแรกที่คุณเรียกใช้ตัวตรวจจับ คำขอที่คุณทำก่อนที่การดาวน์โหลดจะเสร็จสิ้นจะไม่ได้รับผลลัพธ์

แนวทางการป้อนรูปภาพ

เพื่อให้ ML Kit ตรวจจับใบหน้าได้อย่างแม่นยำ รูปภาพที่ป้อนจะต้องมีใบหน้าที่แสดงด้วยข้อมูลพิกเซลที่เพียงพอ โดยทั่วไป แต่ละใบหน้าที่คุณต้องการตรวจจับในรูปภาพควรมีขนาดอย่างน้อย 100x100 พิกเซล หากคุณต้องการตรวจจับรูปทรงของใบหน้า ML Kit ต้องใช้อินพุตที่มีความละเอียดสูงกว่า โดยแต่ละใบหน้าควรมีขนาดอย่างน้อย 200x200 พิกเซล

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

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

การวางแนวของใบหน้าที่สัมพันธ์กับกล้องอาจส่งผลต่อลักษณะใบหน้าที่ ML Kit ตรวจพบได้เช่นกัน ดู แนวคิดการตรวจจับใบหน้า

1. กำหนดค่าเครื่องตรวจจับใบหน้า

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

การตั้งค่า
โหมดประสิทธิภาพ FAST (ค่าเริ่มต้น) | ACCURATE

ชอบความเร็วหรือความแม่นยำเมื่อตรวจจับใบหน้า

ตรวจจับจุดสังเกต NO_LANDMARKS (ค่าเริ่มต้น) | ALL_LANDMARKS

ไม่ว่าจะพยายามระบุ "จุดสังเกต" บนใบหน้า: ตา หู จมูก แก้ม ปาก และอื่นๆ

ตรวจจับรูปทรง NO_CONTOURS (ค่าเริ่มต้น) | ALL_CONTOURS

ไม่ว่าจะตรวจจับรูปทรงของใบหน้า ตรวจพบรูปทรงเฉพาะใบหน้าที่โดดเด่นที่สุดในรูปภาพเท่านั้น

จำแนกใบหน้า NO_CLASSIFICATIONS (ค่าเริ่มต้น) | ALL_CLASSIFICATIONS

ไม่ว่าจะจัดประเภทใบหน้าเป็นหมวดหมู่ เช่น "ยิ้ม" และ "ลืมตา" หรือไม่

ขนาดใบหน้าขั้นต่ำ float (ค่าเริ่มต้น: 0.1f )

ขนาดขั้นต่ำของใบหน้าที่จะตรวจจับซึ่งสัมพันธ์กับรูปภาพ

เปิดใช้งานการติดตามใบหน้า false (ค่าเริ่มต้น) | true

ไม่ว่าจะกำหนด ID ใบหน้าหรือไม่ ซึ่งสามารถใช้เพื่อติดตามใบหน้าในรูปภาพต่างๆ

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

ตัวอย่างเช่น:

Java

// High-accuracy landmark detection and face classification
FirebaseVisionFaceDetectorOptions highAccuracyOpts =
        new FirebaseVisionFaceDetectorOptions.Builder()
                .setPerformanceMode(FirebaseVisionFaceDetectorOptions.ACCURATE)
                .setLandmarkMode(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS)
                .setClassificationMode(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS)
                .build();

// Real-time contour detection of multiple faces
FirebaseVisionFaceDetectorOptions realTimeOpts =
        new FirebaseVisionFaceDetectorOptions.Builder()
                .setContourMode(FirebaseVisionFaceDetectorOptions.ALL_CONTOURS)
                .build();

Kotlin+KTX

// High-accuracy landmark detection and face classification
val highAccuracyOpts = FirebaseVisionFaceDetectorOptions.Builder()
        .setPerformanceMode(FirebaseVisionFaceDetectorOptions.ACCURATE)
        .setLandmarkMode(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS)
        .setClassificationMode(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS)
        .build()

// Real-time contour detection of multiple faces
val realTimeOpts = FirebaseVisionFaceDetectorOptions.Builder()
        .setContourMode(FirebaseVisionFaceDetectorOptions.ALL_CONTOURS)
        .build()

2. เรียกใช้เครื่องตรวจจับใบหน้า

หากต้องการตรวจจับใบหน้าในรูปภาพ ให้สร้างออบเจ็กต์ FirebaseVisionImage จาก Bitmap , media.Image , ByteBuffer , อาร์เรย์ไบต์ หรือไฟล์บนอุปกรณ์ จากนั้น ส่งออบเจ็กต์ FirebaseVisionImage ไปยังเมธอด detectInImage ของ FirebaseVisionFaceDetector

สำหรับการจดจำใบหน้า คุณควรใช้รูปภาพที่มีขนาดอย่างน้อย 480x360 พิกเซล หากคุณกำลังจดจำใบหน้าแบบเรียลไทม์ การจับภาพเฟรมที่ความละเอียดขั้นต่ำนี้สามารถช่วยลดเวลาแฝงได้

  1. สร้างวัตถุ FirebaseVisionImage จากรูปภาพของคุณ

    • หากต้องการสร้างออบเจ็กต์ FirebaseVisionImage จากออบเจ็ media.Image เช่น เมื่อถ่ายภาพจากกล้องของอุปกรณ์ ให้ส่งอ media.Image และการหมุนของรูปภาพไปที่ FirebaseVisionImage.fromMediaImage()

      หากคุณใช้ไลบรารี CameraX คลาส OnImageCapturedListener และ ImageAnalysis.Analyzer จะคำนวณค่าการหมุนให้กับคุณ ดังนั้น คุณเพียงแค่ต้องแปลงการหมุนให้เป็นค่าคงที่ ROTATION_ ของ ML Kit ก่อนที่จะเรียกใช้ FirebaseVisionImage.fromMediaImage() :

      Java

      private class YourAnalyzer implements ImageAnalysis.Analyzer {
      
          private int degreesToFirebaseRotation(int degrees) {
              switch (degrees) {
                  case 0:
                      return FirebaseVisionImageMetadata.ROTATION_0;
                  case 90:
                      return FirebaseVisionImageMetadata.ROTATION_90;
                  case 180:
                      return FirebaseVisionImageMetadata.ROTATION_180;
                  case 270:
                      return FirebaseVisionImageMetadata.ROTATION_270;
                  default:
                      throw new IllegalArgumentException(
                              "Rotation must be 0, 90, 180, or 270.");
              }
          }
      
          @Override
          public void analyze(ImageProxy imageProxy, int degrees) {
              if (imageProxy == null || imageProxy.getImage() == null) {
                  return;
              }
              Image mediaImage = imageProxy.getImage();
              int rotation = degreesToFirebaseRotation(degrees);
              FirebaseVisionImage image =
                      FirebaseVisionImage.fromMediaImage(mediaImage, rotation);
              // Pass image to an ML Kit Vision API
              // ...
          }
      }
      

      Kotlin+KTX

      private class YourImageAnalyzer : ImageAnalysis.Analyzer {
          private fun degreesToFirebaseRotation(degrees: Int): Int = when(degrees) {
              0 -> FirebaseVisionImageMetadata.ROTATION_0
              90 -> FirebaseVisionImageMetadata.ROTATION_90
              180 -> FirebaseVisionImageMetadata.ROTATION_180
              270 -> FirebaseVisionImageMetadata.ROTATION_270
              else -> throw Exception("Rotation must be 0, 90, 180, or 270.")
          }
      
          override fun analyze(imageProxy: ImageProxy?, degrees: Int) {
              val mediaImage = imageProxy?.image
              val imageRotation = degreesToFirebaseRotation(degrees)
              if (mediaImage != null) {
                  val image = FirebaseVisionImage.fromMediaImage(mediaImage, imageRotation)
                  // Pass image to an ML Kit Vision API
                  // ...
              }
          }
      }
      

      หากคุณไม่ได้ใช้ไลบรารีกล้องที่ให้การหมุนภาพ คุณสามารถคำนวณได้จากการหมุนของอุปกรณ์และการวางแนวของเซ็นเซอร์กล้องในอุปกรณ์:

      Java

      private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
      static {
          ORIENTATIONS.append(Surface.ROTATION_0, 90);
          ORIENTATIONS.append(Surface.ROTATION_90, 0);
          ORIENTATIONS.append(Surface.ROTATION_180, 270);
          ORIENTATIONS.append(Surface.ROTATION_270, 180);
      }
      
      /**
       * Get the angle by which an image must be rotated given the device's current
       * orientation.
       */
      @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
      private int getRotationCompensation(String cameraId, Activity activity, Context context)
              throws CameraAccessException {
          // Get the device's current rotation relative to its "native" orientation.
          // Then, from the ORIENTATIONS table, look up the angle the image must be
          // rotated to compensate for the device's rotation.
          int deviceRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
          int rotationCompensation = ORIENTATIONS.get(deviceRotation);
      
          // On most devices, the sensor orientation is 90 degrees, but for some
          // devices it is 270 degrees. For devices with a sensor orientation of
          // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees.
          CameraManager cameraManager = (CameraManager) context.getSystemService(CAMERA_SERVICE);
          int sensorOrientation = cameraManager
                  .getCameraCharacteristics(cameraId)
                  .get(CameraCharacteristics.SENSOR_ORIENTATION);
          rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360;
      
          // Return the corresponding FirebaseVisionImageMetadata rotation value.
          int result;
          switch (rotationCompensation) {
              case 0:
                  result = FirebaseVisionImageMetadata.ROTATION_0;
                  break;
              case 90:
                  result = FirebaseVisionImageMetadata.ROTATION_90;
                  break;
              case 180:
                  result = FirebaseVisionImageMetadata.ROTATION_180;
                  break;
              case 270:
                  result = FirebaseVisionImageMetadata.ROTATION_270;
                  break;
              default:
                  result = FirebaseVisionImageMetadata.ROTATION_0;
                  Log.e(TAG, "Bad rotation value: " + rotationCompensation);
          }
          return result;
      }

      Kotlin+KTX

      private val ORIENTATIONS = SparseIntArray()
      
      init {
          ORIENTATIONS.append(Surface.ROTATION_0, 90)
          ORIENTATIONS.append(Surface.ROTATION_90, 0)
          ORIENTATIONS.append(Surface.ROTATION_180, 270)
          ORIENTATIONS.append(Surface.ROTATION_270, 180)
      }
      /**
       * Get the angle by which an image must be rotated given the device's current
       * orientation.
       */
      @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
      @Throws(CameraAccessException::class)
      private fun getRotationCompensation(cameraId: String, activity: Activity, context: Context): Int {
          // Get the device's current rotation relative to its "native" orientation.
          // Then, from the ORIENTATIONS table, look up the angle the image must be
          // rotated to compensate for the device's rotation.
          val deviceRotation = activity.windowManager.defaultDisplay.rotation
          var rotationCompensation = ORIENTATIONS.get(deviceRotation)
      
          // On most devices, the sensor orientation is 90 degrees, but for some
          // devices it is 270 degrees. For devices with a sensor orientation of
          // 270, rotate the image an additional 180 ((270 + 270) % 360) degrees.
          val cameraManager = context.getSystemService(CAMERA_SERVICE) as CameraManager
          val sensorOrientation = cameraManager
                  .getCameraCharacteristics(cameraId)
                  .get(CameraCharacteristics.SENSOR_ORIENTATION)!!
          rotationCompensation = (rotationCompensation + sensorOrientation + 270) % 360
      
          // Return the corresponding FirebaseVisionImageMetadata rotation value.
          val result: Int
          when (rotationCompensation) {
              0 -> result = FirebaseVisionImageMetadata.ROTATION_0
              90 -> result = FirebaseVisionImageMetadata.ROTATION_90
              180 -> result = FirebaseVisionImageMetadata.ROTATION_180
              270 -> result = FirebaseVisionImageMetadata.ROTATION_270
              else -> {
                  result = FirebaseVisionImageMetadata.ROTATION_0
                  Log.e(TAG, "Bad rotation value: $rotationCompensation")
              }
          }
          return result
      }

      จากนั้นส่งผ่านวัตถุ media.Image และค่าการหมุนไปที่ FirebaseVisionImage.fromMediaImage() :

      Java

      FirebaseVisionImage image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation);

      Kotlin+KTX

      val image = FirebaseVisionImage.fromMediaImage(mediaImage, rotation)
    • หากต้องการสร้างออบเจ็กต์ FirebaseVisionImage จากไฟล์ URI ให้ส่งบริบทของแอปและ URI ไฟล์ไปที่ FirebaseVisionImage.fromFilePath() สิ่งนี้มีประโยชน์เมื่อคุณใช้เจตนา ACTION_GET_CONTENT เพื่อแจ้งให้ผู้ใช้เลือกรูปภาพจากแอปแกลเลอรีของตน

      Java

      FirebaseVisionImage image;
      try {
          image = FirebaseVisionImage.fromFilePath(context, uri);
      } catch (IOException e) {
          e.printStackTrace();
      }

      Kotlin+KTX

      val image: FirebaseVisionImage
      try {
          image = FirebaseVisionImage.fromFilePath(context, uri)
      } catch (e: IOException) {
          e.printStackTrace()
      }
    • หากต้องการสร้างออบเจ็กต์ FirebaseVisionImage จาก ByteBuffer หรืออาร์เรย์ไบต์ ขั้นแรกให้คำนวณการหมุนรูปภาพตามที่อธิบายไว้ข้างต้นสำหรับอินพุต media.Image

      จากนั้น สร้างออบเจ็กต์ FirebaseVisionImageMetadata ที่มีความสูง ความกว้าง รูปแบบการเข้ารหัสสี และการหมุนของรูปภาพ ดังนี้

      Java

      FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
              .setWidth(480)   // 480x360 is typically sufficient for
              .setHeight(360)  // image recognition
              .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
              .setRotation(rotation)
              .build();

      Kotlin+KTX

      val metadata = FirebaseVisionImageMetadata.Builder()
              .setWidth(480) // 480x360 is typically sufficient for
              .setHeight(360) // image recognition
              .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
              .setRotation(rotation)
              .build()

      ใช้บัฟเฟอร์หรืออาร์เรย์ และวัตถุข้อมูลเมตา เพื่อสร้างวัตถุ FirebaseVisionImage :

      Java

      FirebaseVisionImage image = FirebaseVisionImage.fromByteBuffer(buffer, metadata);
      // Or: FirebaseVisionImage image = FirebaseVisionImage.fromByteArray(byteArray, metadata);

      Kotlin+KTX

      val image = FirebaseVisionImage.fromByteBuffer(buffer, metadata)
      // Or: val image = FirebaseVisionImage.fromByteArray(byteArray, metadata)
    • หากต้องการสร้างวัตถุ FirebaseVisionImage จากวัตถุ Bitmap :

      Java

      FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(bitmap);

      Kotlin+KTX

      val image = FirebaseVisionImage.fromBitmap(bitmap)
      รูปภาพที่แสดงโดยวัตถุ Bitmap จะต้องตั้งตรง โดยไม่ต้องหมุนเพิ่มเติม
  2. รับอินสแตนซ์ของ FirebaseVisionFaceDetector :

    Java

    FirebaseVisionFaceDetector detector = FirebaseVision.getInstance()
            .getVisionFaceDetector(options);

    Kotlin+KTX

    val detector = FirebaseVision.getInstance()
            .getVisionFaceDetector(options)
  3. สุดท้าย ส่งภาพไปยังเมธอด detectInImage :

    Java

    Task<List<FirebaseVisionFace>> result =
            detector.detectInImage(image)
                    .addOnSuccessListener(
                            new OnSuccessListener<List<FirebaseVisionFace>>() {
                                @Override
                                public void onSuccess(List<FirebaseVisionFace> faces) {
                                    // Task completed successfully
                                    // ...
                                }
                            })
                    .addOnFailureListener(
                            new OnFailureListener() {
                                @Override
                                public void onFailure(@NonNull Exception e) {
                                    // Task failed with an exception
                                    // ...
                                }
                            });

    Kotlin+KTX

    val result = detector.detectInImage(image)
            .addOnSuccessListener { faces ->
                // Task completed successfully
                // ...
            }
            .addOnFailureListener { e ->
                // Task failed with an exception
                // ...
            }

3. รับข้อมูลเกี่ยวกับใบหน้าที่ตรวจพบ

หากการดำเนินการจดจำใบหน้าสำเร็จ รายการวัตถุ FirebaseVisionFace จะถูกส่งไปยัง Listener ที่สำเร็จ ออบเจ็กต์ FirebaseVisionFace แต่ละรายการแสดงถึงใบหน้าที่ตรวจพบในรูปภาพ สำหรับแต่ละใบหน้า คุณสามารถรับพิกัดขอบเขตในภาพที่ป้อน รวมถึงข้อมูลอื่น ๆ ที่คุณกำหนดค่าให้เครื่องตรวจจับใบหน้าค้นหา ตัวอย่างเช่น:

Java

for (FirebaseVisionFace face : faces) {
    Rect bounds = face.getBoundingBox();
    float rotY = face.getHeadEulerAngleY();  // Head is rotated to the right rotY degrees
    float rotZ = face.getHeadEulerAngleZ();  // Head is tilted sideways rotZ degrees

    // If landmark detection was enabled (mouth, ears, eyes, cheeks, and
    // nose available):
    FirebaseVisionFaceLandmark leftEar = face.getLandmark(FirebaseVisionFaceLandmark.LEFT_EAR);
    if (leftEar != null) {
        FirebaseVisionPoint leftEarPos = leftEar.getPosition();
    }

    // If contour detection was enabled:
    List<FirebaseVisionPoint> leftEyeContour =
            face.getContour(FirebaseVisionFaceContour.LEFT_EYE).getPoints();
    List<FirebaseVisionPoint> upperLipBottomContour =
            face.getContour(FirebaseVisionFaceContour.UPPER_LIP_BOTTOM).getPoints();

    // If classification was enabled:
    if (face.getSmilingProbability() != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) {
        float smileProb = face.getSmilingProbability();
    }
    if (face.getRightEyeOpenProbability() != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) {
        float rightEyeOpenProb = face.getRightEyeOpenProbability();
    }

    // If face tracking was enabled:
    if (face.getTrackingId() != FirebaseVisionFace.INVALID_ID) {
        int id = face.getTrackingId();
    }
}

Kotlin+KTX

for (face in faces) {
    val bounds = face.boundingBox
    val rotY = face.headEulerAngleY // Head is rotated to the right rotY degrees
    val rotZ = face.headEulerAngleZ // Head is tilted sideways rotZ degrees

    // If landmark detection was enabled (mouth, ears, eyes, cheeks, and
    // nose available):
    val leftEar = face.getLandmark(FirebaseVisionFaceLandmark.LEFT_EAR)
    leftEar?.let {
        val leftEarPos = leftEar.position
    }

    // If contour detection was enabled:
    val leftEyeContour = face.getContour(FirebaseVisionFaceContour.LEFT_EYE).points
    val upperLipBottomContour = face.getContour(FirebaseVisionFaceContour.UPPER_LIP_BOTTOM).points

    // If classification was enabled:
    if (face.smilingProbability != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) {
        val smileProb = face.smilingProbability
    }
    if (face.rightEyeOpenProbability != FirebaseVisionFace.UNCOMPUTED_PROBABILITY) {
        val rightEyeOpenProb = face.rightEyeOpenProbability
    }

    // If face tracking was enabled:
    if (face.trackingId != FirebaseVisionFace.INVALID_ID) {
        val id = face.trackingId
    }
}

ตัวอย่างรูปทรงใบหน้า

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

รูปภาพต่อไปนี้แสดงให้เห็นว่าจุดเหล่านี้แมปกับใบหน้าอย่างไร (คลิกที่ภาพเพื่อขยาย):

การตรวจจับใบหน้าแบบเรียลไทม์

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

  • กำหนดค่าเครื่องตรวจจับใบหน้า เพื่อใช้การตรวจจับรูปร่างใบหน้าหรือการจำแนกประเภทและการตรวจจับจุดสังเกต แต่ไม่ใช่ทั้งสองอย่าง:

    การตรวจจับรูปร่าง
    การตรวจจับจุดสังเกต
    การจัดหมวดหมู่
    การตรวจจับและจำแนกจุดสังเกต
    การตรวจจับรูปร่างและการตรวจจับจุดสังเกต
    การตรวจจับและการจำแนกรูปร่าง
    การตรวจจับรูปร่าง การตรวจจับจุดสังเกต และการจำแนกประเภท

  • เปิดใช้งานโหมด FAST (เปิดใช้งานตามค่าเริ่มต้น)

  • ลองถ่ายภาพด้วยความละเอียดที่ต่ำกว่า อย่างไรก็ตาม โปรดคำนึงถึงข้อกำหนดด้านมิติรูปภาพของ API นี้ด้วย

  • คันเร่งเรียกไปที่เครื่องตรวจจับ หากมีเฟรมวิดีโอใหม่ในขณะที่ตัวตรวจจับกำลังทำงานอยู่ ให้ปล่อยเฟรมนั้น
  • หากคุณใช้เอาต์พุตของตัวตรวจจับเพื่อวางซ้อนกราฟิกบนรูปภาพอินพุต อันดับแรกรับผลลัพธ์จาก ML Kit จากนั้นเรนเดอร์รูปภาพและโอเวอร์เลย์ในขั้นตอนเดียว การทำเช่นนี้ คุณจะเรนเดอร์ไปยังพื้นผิวจอแสดงผลเพียงครั้งเดียวสำหรับแต่ละเฟรมอินพุต
  • หากคุณใช้ Camera2 API ให้จับภาพในรูปแบบ ImageFormat.YUV_420_888

    หากคุณใช้ Camera API รุ่นเก่า ให้จับภาพในรูปแบบ ImageFormat.NV21