使用Google Vision API进行面部检测通过VideoView进行展示

时间:2016-01-31 11:17:46

标签: android android-camera android-videoview android-vision

我一直在我的应用程序中使用Google Play服务的Vision API,并且一切正常在我的设备上运行(Nexus 7 2012与Android 5.1,以及更便宜的平板电脑与Android 4.2.2),但在某些生产设备。

我们的应用程序处于打开状态时,我们的视觉API与面部检测框架一起运行,因此当面部检测检测到他时,应用程序会更改内容。

问题是当我们在面部检测工作的同时显示一些VideoView的视频时,因为我们注意到某些“幽灵”出现在VideoView的顶部,我们已经看到这个“幽灵”是人脸检测实时得到的预览。

解释起来很复杂,所以我们录制了一个更好地说明问题的视频:Video

此时,我尝试过这个:

  • 更改.setRequestedPreviewSize(int, int)的尺寸,我们已经看到基于此尺寸,“幽灵”也改变了它的尺寸,因此我们意识到预览尺寸是导致问题的尺寸

  • 从我们在内部看到的.setRequestedPreviewSize(int, int)中删除了CameraSource.Builder的来电,它将其尺寸默认为1024x768,正如您在CameraSource上看到的那样“幽灵”用这个填充整个屏幕。

  • 尝试使用另一个框架来播放视频,移除VideoView并使用另一个基于TextureView的框架也没有帮助,它仍然显示的是幽灵。

  • 使用不同的视频格式也没有帮助

我认为当SurfaceView或SurfaceTexture不仅仅是同时工作时,这可能是一种问题,一个在另一个上面,但这是我第一次使用面向多媒体的应用程序。

有人知道可能出现什么问题?

提前致谢。

修改

只是为了澄清我发布使用的代码。

这是我在应用中使用的方法正在视频中显示:

private void setupFaceDetector() {
        Log.d(TAG, "setupFaceDetector");
        faceDetector = new FaceDetector.Builder(this)
                .setProminentFaceOnly(true)
                .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
                .build();
        if (!faceDetector.isOperational()) {
            retryIn(1000);
        } else {
            faceDetector.setProcessor(new LargestFaceFocusingProcessor(faceDetector, new FaceTracker(this)));
            if (BuildConfig.FLAVOR.equals("withPreview")) {
                mCameraSource = new CameraSource.Builder(this, faceDetector)
                        .setFacing(CameraSource.CAMERA_FACING_FRONT)
                        .setRequestedPreviewSize(320, 240)
                        .build();
            } else {
                mCameraSource = new CameraSource.Builder(this, faceDetector)
                        .setFacing(CameraSource.CAMERA_FACING_FRONT)
                        .build();
            }
        }

    }

我使用一种味道来玩不同类型的东西,这个项目只是为了能够更容易地测试这个功能。

调用onResume()方法时,我正在加载来自File的视频并启动CameraSource实例

private void initializeVideo() {
  mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
      mp.start();
    }
  });

  mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
      Log.d(TAG, "Error playing the video");
      return false;
    }
  });
  mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mp) {
      playVideo();
    }
  });
}

private void startCameraSource() {
  try {
    mCameraSource.start();
  } catch (IOException e) {
    e.printStackTrace();
  }
}

只是为了澄清:

  • 我们正在使用FaceTracker来检测面部,并使用它public void onNewItem(int id, Face face)public void onMissing(Detector.Detections<Face> detections)

  • 显示VideoView的xml布局为:

    <VideoView
        android:id="@+id/videoView"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3"/>
    
    <ScrollView
        android:id="@+id/scroll"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1">
    
        <TextView
            android:id="@+id/tv_log"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="@android:color/white"/>
    </ScrollView>
    

1 个答案:

答案 0 :(得分:4)

我不太确定,但这里有一些建议:

这里有一个开源版本的CameraSource,您可以根据需要在应用中使用和修改:

https://github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ui/camera/CameraSource.java

这有一些表面实例变量mDummySurfaceView和mDummySurfaceTexture,它们用于在没有预览显示的情况下处理相机预览。这些设置在这里:

https://github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ui/camera/CameraSource.java#L346

我猜测在您的应用中,这些虚拟表面会以某种方式干扰您的视频。您可能会看到您的应用是否可以使用其他策略来处理不需要这些虚拟表面的相机。

您也可以使用您提供的特定SurfaceHolder启动相机源,如下所示:

https://github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ui/camera/CameraSource.java#L370

您可以尝试尝试创建替代曲面,看看是否有办法避免干扰您的视频。

如果这些都不起作用,您也可以尝试自己编写相机控制代码,类似于CameraSource提供的代码,但使用较新的&#34; camera2&#34; API(我们使用&#34; camera1&#34; API运送CameraSource,因为当时这个API与旧相机的向后兼容性稍好一些,但是这一点已经通过camera2改进了)。如果这样做,您可以采用类似的方法将预览图像传递给检测器,如下所示:

https://github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ui/camera/CameraSource.java#L1191