android - Google Vision API - 空对象引用上的人脸方法

标签 android api detection face-detection vision

我正在尝试更改 Google 为 Android 上的人脸检测提供的示例应用程序。

FaceDetector detector = new FaceDetector.Builder(getApplicationContext())
                .setTrackingEnabled(false)
                .setMode(FaceDetector.ACCURATE_MODE) // Accurate mode allows to get better face detection and better position (but the detection will be slower)
                .setLandmarkType(FaceDetector.ALL_LANDMARKS)
                .build();

        // This is a temporary workaround for a bug in the face detector with respect to operating
        // on very small images.  This will be fixed in a future release.  But in the near term, use
        // of the SafeFaceDetector class will patch the issue.
        Detector<Face> safeDetector = new SafeFaceDetector(detector);

        // Create a frame from the bitmap and run face detection on the frame.
        Bitmap bitmap = ((BitmapDrawable)ivPhoto.getDrawable()).getBitmap();
        Frame frame = new Frame.Builder().setBitmap(bitmap).build();
        SparseArray<Face> faces = safeDetector.detect(frame);

        if (!safeDetector.isOperational()) {
            Log.w(TAG, "Face detector dependencies are not yet available.");

            // Check for low storage.  If there is low storage, the 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();
                Log.w(TAG, getString(R.string.low_storage_error));
            }
        }

我的问题是,当我尝试在检测到的人脸上调用方法时,例如:

for(int i = 0; i < faces.size(); i++) {
            Face face = faces.get(i);    
            float x = face.getPosition().x + (face.getWidth() / 2);
            float y = face.getPosition().y + (face.getHeight() / 2);
}

然后有时我会在应用程序崩溃时遇到此异常:

04-01 09:07:23.154 30199-30199/ch.epfl.proshare E/AndroidRuntime: FATAL EXCEPTION: main
                                                                  Process: ch.epfl.proshare, PID: 30199
                                                                  java.lang.RuntimeException: Unable to start activity ComponentInfo{ch.epfl.proshare/ch.epfl.proshare.main.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.AppCompatActivity.setSupportActionBar(android.support.v7.widget.Toolbar)' on a null object reference
                                                                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2306)
                                                                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2366)
                                                                      at android.app.ActivityThread.access$800(ActivityThread.java:149)
                                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
                                                                      at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                      at android.os.Looper.loop(Looper.java:135)
                                                                      at android.app.ActivityThread.main(ActivityThread.java:5297)
                                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                                      at java.lang.reflect.Method.invoke(Method.java:372)
                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
                                                                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.AppCompatActivity.setSupportActionBar(android.support.v7.widget.Toolbar)' on a null object reference
                                                                      at ch.epfl.proshare.main.MainFragment.onCreateView(MainFragment.java:169)
                                                                      at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
                                                                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
                                                                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
                                                                      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1230)
                                                                      at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2042)
                                                                      at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:165)
                                                                      at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:543)
                                                                      at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1220)
                                                                      at android.app.Activity.performStart(Activity.java:6036)
                                                                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
                                                                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2366) 
                                                                      at android.app.ActivityThread.access$800(ActivityThread.java:149) 
                                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284) 
                                                                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                      at android.os.Looper.loop(Looper.java:135) 
                                                                      at android.app.ActivityThread.main(ActivityThread.java:5297) 
                                                                      at java.lang.reflect.Method.invoke(Native Method) 
                                                                      at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908) 
                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703) 

我真的不明白为什么 SafeDetector 会返回一个面孔为空的稀疏数组。有人遇到过这个问题吗?

最佳答案

实际上,我刚刚找到了解决问题的方法。 人脸存储在一个 SparseArray 中,这实际上类似于从整数 (id) 到人脸的映射。因此,获取面孔应通过以下方式完成:

Face face = faces.valueAt(i);

代替

Face face = faces.get(i);

关于android - Google Vision API - 空对象引用上的人脸方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36350139/

相关文章:

android - 从谷歌示例复制粘贴代码后 list 中的错误

c# - Uri.EscapeUriString - 如何使用它?

ios - 如何使用 `AVFoundation` 检测相机是否存在?

windows - 检测windows服务故障

android - ondestroy不总是被调用吗?

Android 日志级别

android - 获取联系人的名字和姓氏而不是单个显示名称?

javascript - Node.JS:处理服务器每分钟最大请求的最佳方式

javascript - Angular 7如何将内联JS脚本包含到组件中?

C++ OpenCV 手势识别