问题
My goal is to get as high FPS as possible. I will be happy with BW small frames, but FPS should be maximum.
getSupportedPreviewFpsRange
on HTC WildFire S returns (9, 30). But when I try to draw preview image with most simple processing it visually get at about 12-15 FPS max.
After setting Parameters and startPreview()
method call I do this:
camera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] bytes, Camera camera) {
Bitmap bitmap = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888);
int[] colors = new int[size.width * size.height];
for (int i=0; i < colors.length; i++){
colors[i] = getBWColor(bytes[i]);
}
bitmap.setPixels(colors, 0, size.width, 0, 0, size.width, size.height);
secondView.setImageBitmap(bitmap);
}
});
}
private static int getBWColor(byte b){
int res = 255;
for(int i=0;i<3;i++){
res = (res << 8) + b;
}
return res;
}
Is there way to get it as fast as possible? =(
回答1:
First, use setPreviewCallbackWithBuffer(), it reuses one buffer and does not have to allocate new buffer on every frame. Check my older answer, there is an example how to use it.
Than, do not do any expensive opeartion in onPreviewFrame(), the time of the data is limited, it is rewritten on each new frame. You should do the processing in another thread.
And of course do not create new bitmap a the colors array on each frame, do it just once.
回答2:
I don't really understand what you're doing, but I'd guess you're killing yourself in processing.
1) Do not create a new bitmap every time. Reuse 1 bitmap. 2) Manipulate your bitmaps in C/C++ with the NDK. Look at the "plasma" example. Its MUCH faster than Java. Not because its C++ really, but because the Java version of the API tends to transform the whole thing whenever you push in a data array for pixels. In the C++ version, you can directly manipulate the pixel values.
回答3:
Im not exactly sure what your goal is for this app but the way I added in camera functionality was created a custom surfaceView class and set up my camera inside there. After i chose the front facing (if available) or the back facing, I set up the parameters and then called setPreviewDisplay and passed in the SurfaceHolder I created(code below). After that simply call startpreview() and everything worked beautifully. I had good framerate for it and it all looked fine. If you want me to elaborate more or post some code let me know.
SufaceHolder mHolder;
mHolder = getHolder();
mHolder.addCallback(this); // this is the SurfaceView class
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mHolder.setKeepScreenOn(true);
来源:https://stackoverflow.com/questions/8649751/ways-of-getting-high-fps-for-real-time-computer-vision-processing