用于人脸检测的矩形窗口

时间:2013-08-20 07:26:28

标签: android eclipse face-detection

特别是android的新手。正在制作一个应用程序,我希望我的程序启动相机拍摄图像,然后在我将用于检测面部的脸部周围绘制一个矩形窗口。现在这是我的代码:

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.media.FaceDetector;
import android.media.FaceDetector.Face;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;


public class MainActivity extends Activity {

final int CAMERA_PIC_REQUEST = 0;
private int imageWidth, imageHeight;
private int numberOfFace = 5;
private FaceDetector myFaceDetect; 
private FaceDetector.Face[] myFace;
float myEyesDistance;
int numberOfFaceDetected;
Bitmap thumbnail = null;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);


    Button strt = (Button) findViewById(R.id.start_camera);

        strt.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent camera_intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(camera_intent, CAMERA_PIC_REQUEST);


                BitmapFactory.Options BitmapFactoryOptionsbfo = new BitmapFactory.Options();
                BitmapFactoryOptionsbfo.inPreferredConfig = Bitmap.Config.RGB_565; 
                imageWidth = thumbnail.getWidth();
                imageHeight = thumbnail.getHeight();
                myFace = new FaceDetector.Face[numberOfFace];
                myFaceDetect = new FaceDetector(imageWidth, imageHeight, numberOfFace);
                numberOfFaceDetected = myFaceDetect.findFaces(thumbnail, myFace);


                Canvas canvas = null;

                canvas.drawBitmap(thumbnail, 0, 0, null);

                Paint myPaint = new Paint();
                myPaint.setColor(Color.GREEN);
                myPaint.setStyle(Paint.Style.STROKE); 
               myPaint.setStrokeWidth(3);

                for(int i=0; i < numberOfFaceDetected; i++)
                {
                    Face face = myFace[i];
                    PointF myMidPoint = new PointF();
                    face.getMidPoint(myMidPoint);
                    myEyesDistance = face.eyesDistance();

                    canvas.drawRect(
                            (int)(myMidPoint.x - myEyesDistance),
                            (int)(myMidPoint.y - myEyesDistance),
                            (int)(myMidPoint.x + myEyesDistance),
                            (int)(myMidPoint.y + myEyesDistance),
                            myPaint);
         }                  
                       }
          });

}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch(requestCode){
    case 0:
        if(resultCode==RESULT_OK){

           thumbnail = (Bitmap) data.getExtras().get("data");

            }
    }
}


@Override
protected void onSaveInstanceState(Bundle outState) {

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

}

Logcat显示:

08-20 12:13:16.218: E/AndroidRuntime(26801): FATAL EXCEPTION: main
08-20 12:13:16.218: E/AndroidRuntime(26801): java.lang.RuntimeException: Unable to      resume activity {com.mh9.makeover/com.mh9.makeover.MainActivity}:   java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0,    result=-1, data=Intent { act=inline-data (has extras) }} to activity   {com.mh9.makeover/com.mh9.makeover.MainActivity}: java.lang.NullPointerException
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2124)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2139)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1672)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.os.Looper.loop(Looper.java:130)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.app.ActivityThread.main(ActivityThread.java:3687)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at java.lang.reflect.Method.invokeNative(Native Method)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at java.lang.reflect.Method.invoke(Method.java:507)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at dalvik.system.NativeStart.main(Native Method)
08-20 12:13:16.218: E/AndroidRuntime(26801): Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.mh9.makeover/com.mh9.makeover.MainActivity}: java.lang.NullPointerException
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.app.ActivityThread.deliverResults(ActivityThread.java:2536)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2111)
08-20 12:13:16.218: E/AndroidRuntime(26801):    ... 12 more
08-20 12:13:16.218: E/AndroidRuntime(26801): Caused by: java.lang.NullPointerException
08-20 12:13:16.218: E/AndroidRuntime(26801):    at com.mh9.makeover.MainActivity.onActivityResult(MainActivity.java:78)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.app.Activity.dispatchActivityResult(Activity.java:3908)
08-20 12:13:16.218: E/AndroidRuntime(26801):    at android.app.ActivityThread.deliverResults(ActivityThread.java:2532)
08-20 12:13:16.218: E/AndroidRuntime(26801):    ... 13 more

现在我有两个问题。首先是为什么我得到这个例外是什么意思?纠正解释将不胜感激。第二个问题:我会完成我想做的事吗?我的意思是在拍摄并保存图像后,我想传递它以在脸部周围绘制一个颈椎窗!

1 个答案:

答案 0 :(得分:3)

由于没有来自onActivityResult()方法中相机意图的额外内容而遇到NullPointerException:

thumbnail = (Bitmap) data.getExtras().get("data");

这通常发生在某些(高分辨率)设备中,因为设备需要具有指定文件的摄像头意图,其中应存储捕获的图像。

而不是:

  Intent camera_intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(camera_intent, CAMERA_PIC_REQUEST);

试试这个:

  // create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name

// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);

而不是onactivityresult方法:

  if(resultCode==RESULT_OK){

       thumbnail = (Bitmap) data.getExtras().get("data");

        }

试试这个:

 if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
    if (resultCode == RESULT_OK) {
        // Image captured and saved to fileUri specified in the Intent
        Toast.makeText(this, "Image saved to:\n" +
                 data.getData(), Toast.LENGTH_LONG).show();
    } else if (resultCode == RESULT_CANCELED) {
        // User cancelled the image capture
    } else {
        // Image capture failed, advise user
    }
}

有关详细信息,请访问Documentation

祝你好运!