FaceDetector无法正确识别面部

时间:2018-02-06 14:25:54

标签: java android camera google-play-services face-detection

我想使用FaceDetector播放服务在Android中捕获具有不同面部滤镜的图像。

FaceDetector未在Face中显示正确的过滤器设置。图像:

enter image description here

Research in different projects in GitHub 1 2 3 但没有得到最佳解决方案。

示例项目代码:

MainActivity.java

import android.content.Intent; 
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Environment;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.widget.ImageView;

import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.face.Face;
import com.google.android.gms.vision.face.FaceDetector;

import java.io.File;
import java.io.FileOutputStream;

public class MainActivity extends AppCompatActivity {

ImageView imageView;

private void init() {
    imageView = (ImageView) findViewById(R.id.img);
}

Bitmap b;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    init();
    final FaceDetector detector = new FaceDetector.Builder(getApplicationContext())
            .setTrackingEnabled(false)
            .setMode(FaceDetector.FAST_MODE)
            .setLandmarkType(FaceDetector.NO_LANDMARKS)
            .setClassificationType(FaceDetector.NO_CLASSIFICATIONS)
            .build();
    Runnable r = new Runnable() {
        @Override
        public void run() {
            imageView.buildDrawingCache();
            b = imageView.getDrawingCache();
            Frame frame = new Frame.Builder().setBitmap(b).build();
            imageView.getDrawingCache(false);
            Detector<Face> safeDetector = new SafeFaceDetector(detector);
            Log.d("PRI", "Detector started");

            SparseArray<Face> faceSparseArray = detector.detect(frame);
            Log.d("PRI", "Detector complete");

            Log.d("PRI", String.valueOf(faceSparseArray.size()));
            if (!safeDetector.isOperational()) {
                // Note: The first time that an app using face API is installed on a device, GMS will
                // download a native library to the device in order to do detection.  Usually this
                // completes before the app is run for the first time.  But if that download has not yet
                // completed, then the above call will not detect any faces.
                //
                // isOperational() can be used to check if the required native library is currently
                // available.  The detector will automatically become operational once the library
                // download completes on device.

                // Check for low storage.  If there is low storage, the native library will not be
                // downloaded, so detection will not become operational.
                IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
                boolean hasLowStorage = registerReceiver(null, lowstorageFilter) != null;

                if (hasLowStorage) {
                    //Toast.makeText(this, R.string.low_storage_error, Toast.LENGTH_LONG).show();
                }
            } else {
                createImage(b, faceSparseArray);
            }
            detector.release();

        }

    };
    new Handler().postDelayed(r, 500);
}

private void createImage(Bitmap b, SparseArray<Face> faceSparseArray) {
    Log.d("PRI", "Create Image Started");

    Bitmap bmOverlay = Bitmap.createBitmap(b.getWidth(), b.getHeight(), b.getConfig());
    Canvas canvas = new Canvas(bmOverlay);
    canvas.drawBitmap(b, new Matrix(), null);
    Log.d("PRI", String.valueOf(faceSparseArray.size()));
    for (int i = 0; i < faceSparseArray.size(); i++) {
        Face face = faceSparseArray.valueAt(i);
        Log.d("PRI1", String.valueOf(face));

        Bitmap b2 = BitmapFactory.decodeResource(getResources(), R.drawable.mask4);
        Bitmap b3 = Bitmap.createScaledBitmap(b2, (int) face.getWidth(),
                (int) ((b2.getHeight() * face.getWidth()) / b2.getWidth()), false);

        float x = face.getPosition().x + face.getWidth() / 2;
        float y = face.getPosition().y + face.getHeight() / 2;

        float xOffset = face.getWidth() / 2.0f;
        float yOffset = face.getHeight() / 2.0f;


        canvas.drawBitmap(b3, x - xOffset, y - yOffset, new Paint());
        Log.d("PRI", "Create Image Complete");

    }
    imageView.setImageBitmap(bmOverlay);
    try {
        // Use the compress method on the Bitmap object to write image to
        // the OutputStream
        File f = new File(Environment.getExternalStorageDirectory() + "/tempImage.png");
        if (!f.canWrite())
            f.setWritable(true);
        FileOutputStream fos = new FileOutputStream(f);

        // Writing the bitmap to the output stream
        bmOverlay.compress(Bitmap.CompressFormat.PNG, 2, fos);
        fos.close();
        Log.e("saveToInternalStorage()", "DONE");

    } catch (Exception e) {
        Log.e("saveToInternalStorage()", e.getMessage());
    }
}

}

MainActivity.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="face_camera.lyrebirdstudio.com.facedefaultimage.MainActivity">

    <ImageView
        android:id="@+id/img"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/data" />
</RelativeLayout>

0 个答案:

没有答案