콘솔로 이동

Android에서 ML Kit를 사용하여 얼굴 감지

ML Kit를 사용하면 기기별 모델 또는 클라우드 모델을 사용하여 이미지 및 동영상에서 얼굴을 감지할 수 있습니다. 각 방법의 이점에 대해 알아보려면 개요를 참조하세요.

시작하기 전에

  1. Firebase 프로젝트를 설정합니다.
    1. Firebase 프로젝트가 없으면 Firebase 콘솔에서 프로젝트를 만듭니다. 모바일 앱에 연결된 기존 Google 프로젝트가 있으면 Google 프로젝트 가져오기를 클릭합니다. 기존 프로젝트가 없으면 프로젝트 추가를 클릭합니다.
    2. Android 앱에 Firebase 추가를 클릭하고 설정 단계를 따릅니다. 기존 Google 프로젝트를 가져오는 경우 이 단계가 자동으로 수행될 수 있으며 구성 파일만 다운로드하면 됩니다.
    3. 메시지가 표시되면 앱의 패키지 이름을 입력합니다. 앱에서 사용하고 있는 패키지 이름을 입력해야 합니다. 이 설정은 Firebase 프로젝트에 앱을 추가할 때만 가능합니다.
    4. 마지막으로 google-services.json 파일을 다운로드합니다. 언제든지 다시 구성 파일을 다운로드할 수 있습니다.
    5. 이 파일을 프로젝트의 모듈 폴더(일반적으로 app/)에 복사하여 붙여넣기합니다.
  2. EAP 담당자에게서 받은 SDK의 압축을 풉니다.
    unzip -d $SDK_DIR 3p_sdk.m2repo.zip
    
  3. SDK의 압축을 푼 디렉토리와 google-services 플러그인을 프로젝트 수준의 build.gradle에 추가합니다.
    buildscript {
      // ...
      dependencies {
          // ...
          classpath 'com.google.gms:google-services:3.2.0' // google-services plugin
      }
    }
    
    allprojects {
      repositories {
        // Add this
        maven {
          url "$SDK_DIR"
        }
        // This should already be here
        jcenter()
    
        ...
      }
    }
    
  4. 그런 다음 ML Kit 종속 항목을 포함하고 apply plugin 행을 앱 수준 build.gradle 파일에 추가합니다.

    dependencies {
      // ...
      compile 'com.google.firebase:firebase-core:12.8.0-SNAPSHOT'
      compile 'com.google.firebase:firebase-ml-vision:12.8.0-SNAPSHOT'
    }
    
    // ADD THIS AT THE BOTTOM OF THE FILE
    apply plugin: 'com.google.gms.google-services'
    

이제 기기별 모델 또는 클라우드 기반 모델을 사용하여 얼굴을 감지할 수 있습니다.

기기별 얼굴 감지

얼굴 감지기 구성

이미지에 얼굴 감지 기능을 적용하기 전에, 얼굴 감지기의 기본 설정을 변경하려면 FirebaseVisionFaceDetectorOptions 객체를 사용하여 이러한 설정을 지정하세요. 다음과 같은 설정을 변경할 수 있습니다.

설정
감지 모드 FAST_MODE (기본값) | ACCURATE_MODE

얼굴을 감지할 때 속도 또는 정확도를 우선시합니다.

특징 감지 NO_LANDMARKS (기본값) | ALL_LANDMARKS

눈, 귀, 코, 뺨, 입과 같은 얼굴의 '특징'을 식별할 것인지 여부

얼굴 분류 NO_CLASSIFICATIONS (기본값) | ALL_CLASSIFICATIONS

얼굴을 '웃고 있음' 및 '눈을 뜸'과 같은 카테고리로 분류할 것인지 여부

최소 얼굴 크기 float (기본값: 0.1f)

이미지를 기준으로, 감지할 얼굴의 최소 크기

얼굴 추적 사용 false (기본값) | true

얼굴에 ID를 할당할 것인지 여부. 이는 이미지에서 얼굴을 추적하는 데 사용할 수 있습니다.

예를 들어 모든 기본 설정을 변경하려면 다음 예와 같이 FirebaseVisionFaceDetectorOptions 객체를 빌드합니다.

FirebaseVisionFaceDetectorOptions options =
    new FirebaseVisionFaceDetectorOptions.Builder()
        .setModeType(FirebaseVisionFaceDetectorOptions.ACCURATE_MODE)
        .setLandmarkType(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS)
        .setClassificationType(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS)
        .setMinFaceSize(0.2f)
        .setTrackingEnabled(true)
        .build();

얼굴 감지기 실행

이미지 속 얼굴을 인식하려면 이미지를 ByteBuffer 객체로 FirebaseVisionFaceDetectordetectInBuffer 메소드에 전달하거나 이미지를 android.graphics.Bitmap 객체로 detectInImage 메소드에 전달합니다.

  1. FirebaseVisionFaceDetector의 인스턴스를 가져옵니다.

    FirebaseVisionFaceDetector detector = FirebaseVision.getInstance()
        .getVisionFaceDetector(options);
    
  2. 이미지의 메타데이터가 포함된 FirebaseVisionImageMetadata 객체를 만듭니다.

    이미지를 ByteBuffer로 전달하는 경우 이미지의 높이, 너비, 색상 인코딩 형식, 방향을 지정해야 합니다.

    FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
        .setWidth(1280)
        .setHeight(720)
        .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
        .setRotation(FirebaseVisionImageMetadata.ROTATION_0)
        .build();
    

    이미지를 Bitmap으로 전달하는 경우에는 이미지의 방향만 지정하면 됩니다.

    FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
        .setRotation(FirebaseVisionImageMetadata.ROTATION_0)
        .build();
    
  3. 마지막으로 이미지를 detectInBuffer 또는 detectInImage 메소드에 전달합니다.

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

감지된 얼굴에 관한 정보 얻기

얼굴 인식 작업이 성공하면 FirebaseVisionFace 객체의 배열이 성공 리스너에 전달됩니다. 각 FirebaseVisionFace 객체는 이미지에서 감지된 얼굴을 나타냅니다. 얼굴별로 입력 이미지의 경계 좌표 및 얼굴 감지기가 찾도록 구성한 다른 정보를 얻을 수 있습니다. 예:

for(int i = 0; i < faces.size(); i++) {
  FirebaseVisionFace face = faces.valueAt(i);

  Rect bounds = face.getBoundingBox();
  if (face.hasHeadEulerAngleY()) {
    float rotY = face.getHeadEulerAngleY();  // Head is rotated to the right rotY degrees
  }
  if (face.hasHeadEulerAngleZ()) {
    float rotZ = face.getHeadEulerAngleZ();  // Head is rotated upward rotZ degrees
  }

  // If landmark detection was enabled (mouth, ears, eyes, cheeks, and
  // nose available):
  if (face.hasLeftEarPosition()) {
    PointF leftEarPos = face.getLeftEarPosition();
  }
  if (face.hasNoseBasePosition()) {
    PointF nosePos = face.getNoseBasePosition();
  }

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

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

클라우드 얼굴 감지

얼굴 감지기 구성

기본적으로 클라우드 감지기에서는 모델의 STABLE 버전을 사용하여 최대 10개의 결과를 반환합니다. 이러한 설정을 변경하려면 FirebaseVisionCloudDetectorOptions 객체를 사용하여 설정을 지정합니다.

예를 들어 두 기본 설정을 모두 변경하려면 다음 예와 같이 FirebaseVisionCloudDetectorOptions 객체를 빌드합니다.

FirebaseVisionCloudDetectorOptions options =
    new FirebaseVisionCloudDetectorOptions.Builder()
        .setModelType(FirebaseVisionCloudDetectorOptions.LATEST_MODEL)
        .setMaxResults(15)
        .build();

기본 설정을 사용하려면 다음 단계에 나오는 FirebaseVisionCloudDetectorOptions.DEFAULT를 사용하면 됩니다.

얼굴 감지기 실행

이미지 속 얼굴을 인식하려면 이미지를 ByteBuffer 객체로 FirebaseVisionCloudFaceDetectordetectInBuffer 메소드에 전달하거나 이미지를 android.graphics.Bitmap 객체로 detectInImage 메소드에 전달합니다.

  1. FirebaseVisionCloudFaceDetector의 인스턴스를 가져옵니다.

    FirebaseVisionCloudFaceDetector detector = FirebaseMachineLearning.getInstance()
        .getVisionFaceDetector(options);
    
  2. 이미지의 메타데이터가 포함된 FirebaseVisionImageMetadata 객체를 만듭니다.

    이미지를 ByteBuffer로 전달하는 경우 이미지의 높이, 너비, 색상 인코딩 형식, 방향을 지정해야 합니다.

    FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
        .setWidth(1280)
        .setHeight(720)
        .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
        .setRotation(FirebaseVisionImageMetadata.ROTATION_0)
        .build();
    

    이미지를 Bitmap으로 전달하는 경우에는 이미지의 방향만 지정하면 됩니다.

    FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
        .setRotation(FirebaseVisionImageMetadata.ROTATION_0)
        .build();
    
  3. 마지막으로 이미지를 detectInBuffer 또는 detectInImage 메소드에 전달합니다.

    Task<SparseArray<FirebaseVisionCloudFace>> result =
        detector.detectInImage(image, metadata)  // or detectInBuffer(buffer, metadata)
        .addOnSuccessListener(
            this,
            new OnSuccessListener<SparseArray<FirebaseVisionCloudFace>>() {
              @Override
              public void onSuccess(SparseArray<FirebaseVisionCloudFace> faces) {
                // Task completed successfully
                // ...
              }
            })
        .addOnFailureListener(
            this,
            new OnFailureListener() {
              @Override
              public void onFailure(@NonNull Exception e) {
                // Task failed with an exception
                // ...
              }
            });
    

감지된 얼굴에 관한 정보 얻기

얼굴 인식 작업이 성공하면 FirebaseVisionCloudFace 객체의 배열이 성공 리스너에 전달됩니다. 각 FirebaseVisionCloudFace 객체는 이미지에서 감지된 얼굴을 나타냅니다. 얼굴별로 입력 이미지 내 경계 좌표, 카메라에 대한 회전 방향, 인식된 얼굴 특징의 위치를 얻을 수 있습니다. 예:

for(int i = 0; i < faces.size(); i++) {
  FirebaseVisionFace face = faces.valueAt(i);

  // Face position and rotation
  Rect bounds = face.getBoundingBox();
  float rotY = face.getHeadEulerAngleY();  // Head is rotated to the right rotY degrees
  float rotZ = face.getHeadEulerAngleZ();  // Head is rotated upward rotZ degrees

  // Facial features
  PointF leftEarPos = face.getLeftEarPosition();
  PointF nosePos = face.getNoseBasePosition();

  // Face classification
  float sorrowProb = face.getSorrowProbability();
  float rightEyeOpenProb = face.getRightEyeOpenProbability();
}