Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/193.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 减慢摄影机对象的setPreviewCallback方法_Java_Android_Callback_Camera - Fatal编程技术网

Java 减慢摄影机对象的setPreviewCallback方法

Java 减慢摄影机对象的setPreviewCallback方法,java,android,callback,camera,Java,Android,Callback,Camera,我在摄影机对象(mCamera)上运行以下代码,以检测摄影机指向的任何对象中的人脸。问题是,虽然这个过程非常快,但它确实会减慢应用程序的其他部分,即当我在运行人脸检测时按下按钮执行某项操作时,注册它大约需要半秒钟。我的想法是,如果我在一定时间内以某种方式减慢或减少回拨的次数,那么按下此按钮的速度会快得多: Thread thread = new Thread(new Runnable() { public void run() { // TODO Auto-generat

我在摄影机对象(mCamera)上运行以下代码,以检测摄影机指向的任何对象中的人脸。问题是,虽然这个过程非常快,但它确实会减慢应用程序的其他部分,即当我在运行人脸检测时按下按钮执行某项操作时,注册它大约需要半秒钟。我的想法是,如果我在一定时间内以某种方式减慢或减少回拨的次数,那么按下此按钮的速度会快得多:

Thread thread = new Thread(new Runnable() {
    public void run() {
        // TODO Auto-generated method stub
        mCamera.setPreviewCallback(new PreviewCallback() {
            public void onPreviewFrame(final byte[] _data, Camera _camera) {
                Camera.Parameters parameters = mCamera.getParameters();
                int format = parameters.getPreviewFormat();
                // YUV formats require more conversion
                if (format == ImageFormat.NV21) {
                    int w = parameters.getPreviewSize().width;
                    int h = parameters.getPreviewSize().height;
                    // Get the YuV image
                    YuvImage yuv_image = new YuvImage(_data, format, w, h, null);
                    // Convert YuV to Jpeg
                    Rect rect = new Rect(5 * w / 10, 1 * h / 5, 8 * w / 10, 4 * h / 5);
                    final ByteArrayOutputStream output_stream = new ByteArrayOutputStream();
                    yuv_image.compressToJpeg(rect, 10, output_stream);
                    // Convert from Jpeg to Bitmap
                    Bitmap bmp = Bitmap.createScaledBitmap(BitmapFactory.decodeByteArray(output_stream.toByteArray(), 0, output_stream.size()), 3 * w / 10, 3 * h / 5, true);
                    detectFaces(bmp, w, h);
                }
            }
        });
    }
});
thread.start();

它已经在一个线程中,我认为这可能会有所帮助,但实际上没有。是否仍有更改回拨频率的方法?

您可以尝试在
onPreviewFrame
方法中插入一些
Thread.sleep()
调用,以便代码的其他部分也获得一些cpu时间。上面的代码看起来可能会占用onPreview代码中几乎所有的cpu时间


你可能需要调整睡眠时间,因为睡眠过多会降低预览速度。

我已经做了一些工作,让人脸检测实时发生,下面是我在这一过程中学到的一些东西:

  • API人脸检测器速度的最大影响因素是被检查图像的大小。您可以考虑使用最小的合理相机.GETFoestTeaVIEW()来帮助加快速度。请注意,预览大小和图片大小是独立的参数,因此您不必牺牲捕获的图片质量,除非您将预览帧保存为捕获
  • 此外,如果有任何方法可以假定面应该在帧的某个边界区域内,则可以通过将预览帧裁剪到这些边界,然后将该位图交给面检测器来获得一些性能
  • 避免在处理预览帧的循环中分配任何新对象。需要进行的分配和最终的垃圾收集可能会花费大量时间。使用单例、静态或成员变量保存可以重用的内容,而不是分配新内容
  • 最后,一旦你已经尽了最大的努力,考虑线程不尝试处理每一帧,但可能每隔几秒钟处理一次。将名为mLastFrameAnalzedTime的成员变量添加到线程类中。存储上次成功解码/检测int的时间,然后每次获得新帧时,检查是否有足够的时间来处理下一帧

希望其中有一些帮助。

您可以看一看。

请查看以下摄像头方法的文档。参数

getSupportedPreviewFpsRange getPreviewFpsRange setPreviewFpsRange

在我的Nexus上,我有3个可能的预览FPS 最小15fps,最大15fps 最小15fps,最大30fps 最低24帧,最高30帧

注意: getSupportedPreviewFpsRange的返回值按1000缩放——我不知道为什么

我不确定这是否有效,因为我测量了两次调用onPreviewFrame之间的时间,得到了FPS1000。。。。也许我的测量有误