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