从相机保存位图并执行面部裁剪和生物识别统计

Save bitmap from camera and perform facecrop and biometric stats

所以我正在做一个项目,我从画廊或相机中获取图像,并从图像中获得一系列统计数据(亮度、对比度、清晰度等)。目前我在画廊工作。我可以打开图库,拉出图像,如果检测到人脸,它将在第二个图像视图中被裁剪。统计数据是从裁剪后的图像中收集的(请参阅图库按钮区域中的 showimage(bitmap))。上周我一直在努力尝试从相机中获得同样的效果。

我目前正在使用以下开源项目从图库中获取图像并从图像中裁剪面部:

https://github.com/hanscappelle/SO-2169649

https://github.com/lafosca/AndroidFaceCropper

我取得了一些进步,但后来又多次后退,因为我认为我尝试做错了。这是我目前用于 JUST gallery 的工作代码:

public class MainActivity extends AppCompatActivity {

// this is the action code we use in our intent,
// this way we know we're looking at the response from our own action
private static final int SELECT_SINGLE_PICTURE = 101;

public static final String IMAGE_TYPE = "image/*";

/* Get the reference to the text label */
TextView label = null;


private ImageView selectedImagePreview;
private ImageView imageViewFace;


void showImage(Bitmap image)
{

    /* Get the starting time */
    long startTime = 0;

    startTime = System.nanoTime();

    /* Get the image statistics */
    ImageStats imageStats = new ImageStats(image);

    System.out.println("Execution time: " + (((double)(System.nanoTime() - startTime))/1000000000.0) + " seconds!");

     /* Get the image statistics */
    double[] stats = imageStats.getStats();

    /*  Decide whether or not the image is of good quality */
    String results = imageStats.result;

     /* Create the labels */
    String[] labels = new String[]{"Standard Luminosity: ", "Contrast: ", "Face orientation: ", "Sharpness: "};

     /* The string of statistics */
    StringBuffer strStatsBuff = new StringBuffer();

     /* Go through all the statistics */
    for(int statIndex = 0; statIndex < stats.length; ++statIndex)
    {
          /* Add the statistics */
        strStatsBuff.append(labels[statIndex]);
        strStatsBuff.append(String.valueOf(stats[statIndex]));
        strStatsBuff.append("\n");
    }

     /* Add the file name */
    strStatsBuff.append("\n");
    strStatsBuff.append(results);

      /* Set the label and show the cropped image */
    label.setText(strStatsBuff.toString());
    FaceCropper mFaceCropper = new FaceCropper();
    mFaceCropper.setEyeDistanceFactorMargin(0);
    image = mFaceCropper.getCroppedImage(image);
    imageViewFace.setImageBitmap(image);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // no need to cast to button view here since we can add a listener to any view, this
    // is the single image selection
    label = (TextView)findViewById(R.id.label);

    findViewById(R.id.buttonGallery).setOnClickListener(new View.OnClickListener() {

        public void onClick(View arg0) {

            // in onCreate or any event where your want the user to
            // select a file
            Intent intent = new Intent();
            intent.setType(IMAGE_TYPE);
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent,
                    "Select image"), SELECT_SINGLE_PICTURE);
        }
    });

    selectedImagePreview = (ImageView)findViewById(R.id.imageView1);
    imageViewFace = (ImageView)findViewById(R.id.imageViewFace);
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_SINGLE_PICTURE) {

            Uri selectedImageUri = data.getData();

            try {
                Bitmap bitmap;
                selectedImagePreview.setImageBitmap(new UserPicture(selectedImageUri, getContentResolver()).getBitmap());
                bitmap=BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImageUri));
                showImage(bitmap);

            } catch (IOException e) {
                Log.e(MainActivity.class.getSimpleName(), "Failed to load image", e);
                e.printStackTrace();
            }

        }

    } else {
        // report failure
        Toast.makeText(getApplicationContext(),"failed to get intent data", Toast.LENGTH_LONG).show();
        Log.d(MainActivity.class.getSimpleName(), "Failed to get intent data, result code is " + resultCode);
    }
}

}

我的"closest to working"方法从相机中拉取了一张图像,但是原始图像视图和应该被裁剪到面部的图像视图都只显示原始图像。

我在 oncreate 下包含了以下内容 -

        findViewById(R.id.buttonCamera).setOnClickListener(new View.OnClickListener(){
        public void onClick(View arg0 ){
            Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(cameraIntent, CAMERA_REQUEST);
        }
    });

这包含在 onactivityresult 中 -

 else if (requestCode==CAMERA_REQUEST && resultCode == RESULT_OK){
            Bitmap bitmap = (Bitmap) data.getExtras().get("data");
            selectedImagePreview.setImageBitmap(bitmap);
           showImage(bitmap);

        }

欢迎提出任何建议!如果您需要更多信息或者我没有提供明显的信息,请告诉我。我是 Whosebug、java 和 android 的新手。谢谢!

我现在有办法了。如果有人需要做相同或类似的事情,这就是我的样子:

public class MainActivity extends AppCompatActivity {

// this is the action code we use in our intent,
// this way we know we're looking at the response from our own action
private static final int SELECT_SINGLE_PICTURE = 101;

private static final int CAMERA_REQUEST = 102;

public static final String IMAGE_TYPE = "image/*";

private final int RequestCode = 20;

Uri mImageCaptureUri1;

/* Get the reference to the text label */
TextView label = null;

ImageView selectedImagePreview;
ImageView imageViewFace;



void showImage(Bitmap image)
{
    imageViewFace.setImageBitmap(null);
    FaceCropper mFaceCropper = new FaceCropper();
    mFaceCropper.setMaxFaces(1);
    mFaceCropper.setEyeDistanceFactorMargin(0);
    image = mFaceCropper.getCroppedImage(image);

    String faceFound;
    if (mFaceCropper.faceDetected==true){
        faceFound = "Face Detected!";
    }else faceFound ="No face detected!";

    /* Get the starting time */
    long startTime = 0;

    startTime = System.nanoTime();

    /* Get the image statistics */
    ImageStats imageStats = new ImageStats(image);

    System.out.println("Execution time: " + (((double)(System.nanoTime() - startTime))/1000000000.0) + " seconds!");

     /* Get the image statistics */
    double[] stats = imageStats.getStats();

    /*  Decide whether or not the image is of good quality */
    String results = imageStats.result;


     /* Create the labels */
    String[] labels = new String[]{"Standard Luminosity: ", "Contrast: ", "Face orientation: ", "Sharpness: "};

     /* The string of statistics */
    StringBuffer strStatsBuff = new StringBuffer();

     /* Go through all the statistics */
    for(int statIndex = 0; statIndex < stats.length; ++statIndex)
    {
          /* Add the statistics */
        strStatsBuff.append(labels[statIndex]);
        strStatsBuff.append(String.valueOf(stats[statIndex]));
        strStatsBuff.append("\n");
    }

     /* Add the file name */
   strStatsBuff.append(faceFound);


      /* Set the label and show the cropped image */
    label.setText(strStatsBuff.toString());


    if (mFaceCropper.faceDetected == true)
    {
        imageViewFace.setImageBitmap(image);

    }

}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // no need to cast to button view here since we can add a listener to any view, this
    // is the single image selection
    label = (TextView)findViewById(R.id.label);



    findViewById(R.id.buttonGallery).setOnClickListener(new View.OnClickListener() {
        public void onClick(View arg0) {

            // in onCreate or any event where your want the user to
            // select a file
            Intent intent = new Intent();
            intent.setType(IMAGE_TYPE);
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent,
                    "Select image"), SELECT_SINGLE_PICTURE);
        }
    });

    findViewById(R.id.buttonCamera).setOnClickListener(new View.OnClickListener(){
        public void onClick(View arg0 ){
            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            mImageCaptureUri1 = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
                    "tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));

            cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri1);
            cameraIntent.putExtra("return-data", true);
            startActivityForResult(cameraIntent, CAMERA_REQUEST);
        }
    });

    selectedImagePreview = (ImageView)findViewById(R.id.imageView1);
    imageViewFace = (ImageView)findViewById(R.id.imageViewFace);
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_SINGLE_PICTURE) {

            Uri selectedImageUri = data.getData();

            try {
                Bitmap bitmap;
                selectedImagePreview.setImageBitmap(new UserPicture(selectedImageUri, getContentResolver()).getBitmap());
                bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImageUri));
                selectedImagePreview.setImageBitmap(bitmap);

                showImage(bitmap);

            } catch (IOException e) {
                Log.e(MainActivity.class.getSimpleName(), "Failed to load image", e);
                e.printStackTrace();
            }

        }
        else if (requestCode==CAMERA_REQUEST){

            try {
                Bitmap bitmap;
                selectedImagePreview.setImageBitmap(new UserPicture(mImageCaptureUri1, getContentResolver()).getBitmap());
                bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(mImageCaptureUri1));
                selectedImagePreview.setImageBitmap(bitmap);
                String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());


                showImage(bitmap);

            } catch (IOException e) {
                Log.e(MainActivity.class.getSimpleName(), "Failed to load image", e);
                e.printStackTrace();
            }



        }

    }



    else {
        // report failure
        Toast.makeText(getApplicationContext(),"failed to get intent data", Toast.LENGTH_LONG).show();
        Log.d(MainActivity.class.getSimpleName(), "Failed to get intent data, result code is " + resultCode);
    }
}
}