0

目前我正在使用 Google Mobile Vision API 进行人脸检测。假设屏幕旋转后,Activity 将重新启动,所有变量都将重新初始化。但是,我不知道为什么应用程序停止工作并显示 NullPointerException。这是我的代码。

public class MainActivity extends AppCompatActivity {

    private ImageView mIvDetected;
    private Bitmap mImage;

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

        mIvDetected = (ImageView) findViewById(R.id.iv_detected);

        //Load an image
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inMutable = true;
        mImage = BitmapFactory.decodeResource(getResources(), R.drawable.face2);

        //Configure FaceDetector
        FaceDetector detector = new FaceDetector.Builder(this)
                .setMode(FaceDetector.ACCURATE_MODE)
                .setLandmarkType(FaceDetector.ALL_LANDMARKS)
                .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
                .setTrackingEnabled(false)
                .build();

        if(false == detector.isOperational()){
            Toast.makeText(this, "Face detection service is not ready", Toast.LENGTH_SHORT).show();
            return;
        }

        //Add the image on a Frame object
        Frame frame = new Frame.Builder().setBitmap(mImage).build();

        //Detect all faces from Frame object
        SparseArray<Face> faceArray = detector.detect(frame);

        //Do some drawing on faces
        **Bitmap outBitmap = drawOnFace(faceArray);**
        mIvDetected.setImageBitmap(outBitmap);

        //Releasing the detector object
        detector.release();
    }

    /** Method to do some drawing on faces */
    private Bitmap drawOnFace(SparseArray<Face> faceArray){

        Paint mIdPaint = new Paint();
        mIdPaint.setColor(Color.RED);
        mIdPaint.setTextSize(40.f);

        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);

        Paint mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setDither(true);
        mTextPaint.setTextSize(20);
        mTextPaint.setColor(Color.GREEN);
        mTextPaint.setStyle(Paint.Style.FILL);

        // Create a blank bitmap same size with the source image
        Bitmap outBitmap = Bitmap.createBitmap(mImage.getWidth(), mImage.getHeight(), Bitmap.Config.RGB_565);

        // Put the bitmap on canvas for drawing
        Canvas canvas = new Canvas(outBitmap);
        canvas.drawBitmap(mImage, 0, 0, null);

        for(int i=0; i < faceArray.size(); i++){
            Face face = faceArray.get(i);

            //Drawing rectangle on each face
            **drawRectangle(canvas, face.getPosition(), face.getWidth(), face.getHeight());**

            //Drawing a point on each face features
            for(Landmark landmark : face.getLandmarks()) {
                switch (landmark.getType()){
                    case Landmark.LEFT_EYE:
                        drawPoint(canvas, landmark.getPosition());
                        canvas.drawText("Left eye: " + face.getIsLeftEyeOpenProbability(), landmark.getPosition().x, landmark.getPosition().y - 30, mTextPaint);
                        break;
                    case Landmark.RIGHT_EYE:
                        drawPoint(canvas, landmark.getPosition());
                        canvas.drawText("Right eye: " + face.getIsRightEyeOpenProbability(), landmark.getPosition().x, landmark.getPosition().y - 30, mTextPaint);
                        break;
                    case Landmark.BOTTOM_MOUTH:
                        drawPoint(canvas, landmark.getPosition());
                        canvas.drawText("Smile: " + face.getIsSmilingProbability(), landmark.getPosition().x, landmark.getPosition().y + 40, mTextPaint);
                        break;
                    case Landmark.LEFT_MOUTH:
                        drawPoint(canvas, landmark.getPosition());
                        break;
                    case Landmark.RIGHT_MOUTH:
                        drawPoint(canvas, landmark.getPosition());
                        break;
                    case Landmark.NOSE_BASE:
                        drawPoint(canvas, landmark.getPosition());
                        break;
                    case Landmark.LEFT_CHEEK:
                        drawPoint(canvas, landmark.getPosition());
                        break;
                    case Landmark.RIGHT_CHEEK:
                        drawPoint(canvas, landmark.getPosition());
                        break;
                    case Landmark.LEFT_EAR:
                        drawPoint(canvas, landmark.getPosition());
                        break;
                    case Landmark.LEFT_EAR_TIP:
                        drawPoint(canvas, landmark.getPosition());
                        break;
                    case Landmark.RIGHT_EAR:
                        drawPoint(canvas, landmark.getPosition());
                        break;
                    case Landmark.RIGHT_EAR_TIP:
                        drawPoint(canvas, landmark.getPosition());
                        break;
                }
            }

            /** Other useful details that may be of your interest */
            Log.d("", "FaceDetection- FaceId:" + face.getId()
                    + " Smiling:" + face.getIsSmilingProbability()
                    + " LeftEyeOpen:" + face.getIsLeftEyeOpenProbability()
                    + " RightEyeOpen:" + face.getIsRightEyeOpenProbability());


        }

        return outBitmap;
    }

    /** This method draws a rectangle */
    private void drawRectangle(Canvas canvas, PointF point, float width, float height){
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);

        float x1 = point.x;
        float y1 = point.y;
        float x2 = x1 + width;
        float y2 = y1 + height;

        RectF rect = new RectF(x1, y1, x2, y2);
        canvas.drawRect(rect, paint);
    }

    /** This method draws a point with hole */
    private void drawPoint(Canvas canvas, PointF point){
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStrokeWidth(48);
        paint.setStyle(Paint.Style.STROKE);

        float x = point.x;
        float y = point.y;

        canvas.drawCircle(x, y, 1, paint);
    }
}

这是我的错误。

04-24 12:59:50.231 2865-2865/com.example.andy318.cameraone E/AndroidRuntime: 致命异常: 主进程: com.example.andy318.cameraone, PID: 2865 java.lang.RuntimeException: 无法恢复活动{com.example.andy318.cameraone/com.example.andy318.cameraone.MainActivity}:java.lang.NullPointerException:尝试调用虚拟方法'android.graphics.PointF com.google.android.gms.vision.face.Face .getPosition()' 在 android.app.ActivityThread.performResumeActivity(ActivityThread.java:3103) 在 android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481) 在 android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134) 在 android. app.ActivityThread.-wrap15(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:5417) 在 java.在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 的 lang.reflect.Method.invoke(Native Method):616)原因:java.lang.NullPointerException:尝试在 com.example 的空对象引用上调用虚拟方法 'android.graphics.PointF com.google.android.gms.vision.face.Face.getPosition()'。 andy318.cameraone.MainActivity.drawOnFace(MainActivity.java:106) 在 com.example.andy318.cameraone.MainActivity.onResume(MainActivity.java:69) 在 android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258) 在 android 。应用程序。Activity.performResume(Activity.java:6312) 在 android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092) 在 android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread .java:2481) 在 android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077) 在 android.app.ActivityThread.-wrap15(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:148) 在android.app.ActivityThread.main(ActivityThread.java:5417) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller 的 java.lang.reflect.Method.invoke(Native Method)。在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 运行(ZygoteInit.java:726)

错误发生在

位图 outBitmap = drawOnFace(faceArray);

drawRectangle(canvas, face.getPosition(), face.getWidth(), face.getHeight());

我把 ** 放在编码中。

我知道我的错误在哪里,但我不知道如何解决它。屏幕旋转后,SparseArray faceArray 有空值。我尝试使用 if 来检查 null 条件,但它不会显示检测结果。(只显示原图)

4

2 回答 2

0

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“Face.getPosition()”

你的脸变量是空的!

http://developer.android.com/reference/android/media/FaceDetector.html

你从哪里得到检测()?nvm,找到它: https ://developers.google.com/android/reference/com/google/android/gms/vision/face/FaceDetector.html#public-methods

也许你需要使 SparseArray 最终或里面的所有面或类似的东西?

于 2016-04-24T14:23:32.637 回答
0

您只得到密钥,而不是对象:

https://stackoverflow.com/a/8006994/6247492

使用此代码:

for(int i = 0; i < faceArray.size(); i++) {
   int key = faceArray.keyAt(i);
   // get the object by the key.
   Face face = faceArray.get(key);
}
于 2016-04-24T15:05:20.517 回答