web-dev-qa-db-ja.com

MLKit Firebase Android-FirebaseVisionFaceを画像オブジェクト(ビットマップなど)に変換する方法は?

MLkitFaceDetectionをAndroidアプリケーションに統合しました。以下のURLを参照しました

https://firebase.google.com/docs/ml-kit/Android/detect-faces

顔検出プロセッサクラスのコードは

import Java.io.IOException;
import Java.util.List;

/** Face Detector Demo. */
public class FaceDetectionProcessor extends VisionProcessorBase<List<FirebaseVisionFace>> {

  private static final String TAG = "FaceDetectionProcessor";

  private final FirebaseVisionFaceDetector detector;

  public FaceDetectionProcessor() {

    FirebaseVisionFaceDetectorOptions options =
        new FirebaseVisionFaceDetectorOptions.Builder()
            .setClassificationType(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS)
            .setLandmarkType(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS)
            .setTrackingEnabled(true)
            .build();

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

  @Override
  public void stop() {
    try {
      detector.close();
    } catch (IOException e) {
      Log.e(TAG, "Exception thrown while trying to close Face Detector: " + e);
    }
  }

  @Override
  protected Task<List<FirebaseVisionFace>> detectInImage(FirebaseVisionImage image) {
    return detector.detectInImage(image);
  }

  @Override
  protected void onSuccess(
      @NonNull List<FirebaseVisionFace> faces,
      @NonNull FrameMetadata frameMetadata,
      @NonNull GraphicOverlay graphicOverlay) {
      graphicOverlay.clear();

    for (int i = 0; i < faces.size(); ++i) {
      FirebaseVisionFace face = faces.get(i);
      FaceGraphic faceGraphic = new FaceGraphic(graphicOverlay);
      graphicOverlay.add(faceGraphic);
      faceGraphic.updateFace(face, frameMetadata.getCameraFacing());
    }




  }

  @Override
  protected void onFailure(@NonNull Exception e) {
    Log.e(TAG, "Face detection failed " + e);
  }
}

ここ「onSuccess」リスナーでは、faceの「BoundingBox」を持つ「FirebaseVisionFace」クラスオブジェクトの配列を取得します。

@Override
      protected void onSuccess(
          @NonNull List<FirebaseVisionFace> faces,
          @NonNull FrameMetadata frameMetadata,
          @NonNull GraphicOverlay graphicOverlay) {
          graphicOverlay.clear();

        for (int i = 0; i < faces.size(); ++i) {
          FirebaseVisionFace face = faces.get(i);
          FaceGraphic faceGraphic = new FaceGraphic(graphicOverlay);
          graphicOverlay.add(faceGraphic);
          faceGraphic.updateFace(face, frameMetadata.getCameraFacing());
        }
      }

このFirebaseVisionFaceオブジェクトをビットマップに変換する方法を知りたいです。顔画像を抽出してImageViewに表示したい。誰か助けてくれませんか。前もって感謝します。

注:MLKitのサンプルソースコードをダウンロードしましたAndroid以下のURLから

https://github.com/firebase/quickstart-Android/tree/master/mlkit

9
Mani murugan

ビットマップからFirebaseVisionImageを作成しました。検出が戻った後、各FirebaseVisionFaceは、元のビットマップから検出された顔を抽出するために使用できるRectとして境界ボックスを記述します。 Bitmap.createBitmap() を使用します。

5
gnuf

受け入れられた答えは十分に具体的ではなかったので、私は私がしたことを説明しようとします。

1.-次のようにLivePreviewActivityでImageViewを作成します。

private ImageView imageViewTest;

2.-アクティビティxmlで作成し、Javaファイルにリンクします。サンプルコードの直前に配置したので、カメラフィードの上に表示できます。

3.-FaceDetectionProcessorを作成するときに、imageViewのインスタンスを渡して、オブジェクト内にソース画像を設定できるようにします。

FaceDetectionProcessor processor = new FaceDetectionProcessor(imageViewTest);

4.-FaceDetectionProcessorのコンストラクターを変更して、ImageViewをパラメーターとして受け取り、そのインスタンスを保存するグローバル変数を作成できるようにします。

public FaceDetectionProcessor(ImageView imageView) {
    FirebaseVisionFaceDetectorOptions options =
            new FirebaseVisionFaceDetectorOptions.Builder()
                    .setClassificationType(FirebaseVisionFaceDetectorOptions.ALL_CLASSIFICATIONS)
                    .setTrackingEnabled(true)
                    .build();

    detector = FirebaseVision.getInstance().getVisionFaceDetector(options);
    this.imageView  = imageView;
}

5.-ビットマップとRectを使用して顔だけに焦点を合わせるcropメソッドを作成しました。だから先に進んで同じことをしてください。

    public static Bitmap cropBitmap(Bitmap bitmap, Rect rect) {
    int w = rect.right - rect.left;
    int h = rect.bottom - rect.top;
    Bitmap ret = Bitmap.createBitmap(w, h, bitmap.getConfig());
    Canvas canvas = new Canvas(ret);
    canvas.drawBitmap(bitmap, -rect.left, -rect.top, null);
    return ret;
}

6.-detectInImageメソッドを変更して、検出されているビットマップのインスタンスを保存し、グローバル変数に保存します。

    @Override
protected Task<List<FirebaseVisionFace>> detectInImage(FirebaseVisionImage image) {
    imageBitmap = image.getBitmapForDebugging();
    return detector.detectInImage(image);
}

7.-最後に、cropingメソッドを呼び出してOnSuccessメソッドを変更し、結果をimageViewに割り当てます。

    @Override
protected void onSuccess(
        @NonNull List<FirebaseVisionFace> faces,
        @NonNull FrameMetadata frameMetadata,
        @NonNull GraphicOverlay graphicOverlay) {
    graphicOverlay.clear();
    for (int i = 0; i < faces.size(); ++i) {
        FirebaseVisionFace face = faces.get(i);
        FaceGraphic faceGraphic = new FaceGraphic(graphicOverlay);
        graphicOverlay.add(faceGraphic);
        faceGraphic.updateFace(face, frameMetadata.getCameraFacing());
        croppedImage = cropBitmap(imageBitmap, face.getBoundingBox());
    }
    imageView.setImageBitmap(croppedImage);
}
1
Jmz

これは、ML Kitを使用して顔を検出し、OpenCVを使用して検出された顔の画像処理を実行しようとしている場合に役立ちます。この特定の例では、onSuccess内に元のカメラビットマップが必要であることに注意してください。

ビットマップなしでこれを行う方法を見つけられず、正直に言ってまだ検索しています。

@Override
protected void onSuccess(@NonNull List<FirebaseVisionFace> faces, @NonNull FrameMetadata frameMetadata, @NonNull GraphicOverlay graphicOverlay) {
  graphicOverlay.clear();

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

    /* Original implementation has original image. Original Image represents the camera preview from the live camera */

    // Create Mat representing the live camera itself
    Mat rgba = new Mat(originalCameraImage.getHeight(), originalCameraImage.getWidth(), CvType.CV_8UC4);

    // The box with a Imgproc affect made by OpenCV
    Mat rgbaInnerWindow;
    Mat mIntermediateMat = new Mat();

    // Make box for Imgproc the size of the detected face
    int rows = (int) face.getBoundingBox().height();
    int cols = (int) face.getBoundingBox().width();

    int left = cols / 8;
    int top = rows / 8;

    int width = cols * 3 / 4;
    int height = rows * 3 / 4;

    // Create a new bitmap based on live preview
    // which will show the actual image processing
    Bitmap newBitmap = Bitmap.createBitmap(originalCameraImage);

    // Bit map to Mat
    Utils.bitmapToMat(newBitmap, rgba);

    // Imgproc stuff. In this examply I'm doing Edge detection.
    rgbaInnerWindow = rgba.submat(top, top + height, left, left + width);
    Imgproc.Canny(rgbaInnerWindow, mIntermediateMat, 80, 90);
    Imgproc.cvtColor(mIntermediateMat, rgbaInnerWindow, Imgproc.COLOR_GRAY2BGRA, 4);
    rgbaInnerWindow.release();

    // After processing image, back to bitmap
    Utils.matToBitmap(rgba, newBitmap);

    // Load the bitmap
    CameraImageGraphic imageGraphic = new CameraImageGraphic(graphicOverlay, newBitmap);
    graphicOverlay.add(imageGraphic);

    FaceGraphic faceGraphic;
    faceGraphic = new FaceGraphic(graphicOverlay, face, null);
    graphicOverlay.add(faceGraphic);


    FaceGraphic faceGraphic = new FaceGraphic(graphicOverlay);
    graphicOverlay.add(faceGraphic);


    // I can't speak for this
    faceGraphic.updateFace(face, frameMetadata.getCameraFacing());
  }

}
1
cookiemonster

実際には、ByteBufferを読み取るだけで、OutputStreamを使用して必要なオブジェクトファイルに書き込むための配列を取得できます。もちろん、getBoundingBox()からも取得できます。

0
AnsorKazama