[英]How to get each frame data using camera2 API in Android5.0 in realtime
我現在正在使用camera2Basic並試圖讓每個幀數據進行一些圖像處理。 我在Android5.0中使用camera2 API,當只進行相機預覽並且它是流暢的時候一切都很好。 但是當我使用ImageReader.OnImageAvailableListener
回調來獲取每個幀數據時,預覽會ImageReader.OnImageAvailableListener
,這會導致糟糕的用戶體驗。 以下是我的相關代碼:
這是攝像頭和ImageReader的設置,我設置的圖像格式是YUV_420_888
public<T> Size setUpCameraOutputs(CameraManager cameraManager,Class<T> kClass, int width, int height) {
boolean flagSuccess = true;
try {
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
// choose the front or back camera
if (FLAG_CAMERA.BACK_CAMERA == mChosenCamera &&
CameraCharacteristics.LENS_FACING_BACK != characteristics.get(CameraCharacteristics.LENS_FACING)) {
continue;
}
if (FLAG_CAMERA.FRONT_CAMERA == mChosenCamera &&
CameraCharacteristics.LENS_FACING_FRONT != characteristics.get(CameraCharacteristics.LENS_FACING)) {
continue;
}
StreamConfigurationMap map = characteristics.get(
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size largestSize = Collections.max(
Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),
new CompareSizesByArea());
mImageReader = ImageReader.newInstance(largestSize.getWidth(), largestSize.getHeight(),
ImageFormat.YUV_420_888, 3);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
...
mCameraId = cameraId;
}
} catch (CameraAccessException e) {
e.printStackTrace();
} catch (NullPointerException e) {
}
......
}
當相機成功打開時,我創建一個CameraCaptureSession進行相機預覽
private void createCameraPreviewSession() {
if (null == mTexture) {
return;
}
// We configure the size of default buffer to be the size of camera preview we want.
mTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
// This is the output Surface we need to start preview
Surface surface = new Surface(mTexture);
// We set up a CaptureRequest.Builder with the output Surface.
try {
mPreviewRequestBuilder =
mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
mPreviewRequestBuilder.addTarget(surface);
// We create a CameraCaptureSession for camera preview
mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
if (null == mCameraDevice) {
return;
}
// when the session is ready, we start displaying the preview
mCaptureSession = session;
// Finally, we start displaying the camera preview
mPreviewRequest = mPreviewRequestBuilder.build();
try {
mCaptureSession.setRepeatingRequest(mPreviewRequest,
mCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
最后一個是ImageReader.OnImageAvailableListener
回調
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Log.d(TAG, "The onImageAvailable thread id: " + Thread.currentThread().getId());
Image readImage = reader.acquireLatestImage();
readImage.close();
}
};
也許我做錯了設置,但我嘗試了幾次,但它不起作用。 也許有另一種獲取幀數據的方法而不是ImageReader,但我不知道。 有誰知道如何實時獲取每個幀數據?
我不相信陳是正確的。 圖像格式對我測試的設備的速度幾乎沒有影響。 相反,問題似乎與圖像大小有關。 在圖像格式為YUV_420_888
的Xperia Z3 Compact上,我在StreamConfigurationMap
的getOutputSizes
方法中提供了許多不同的選項:
[1600x1200, 1280x720, 960x720, 720x480, 640x480, 480x320, 320x240, 176x144]
對於這些相應的尺寸,最大FPS我得到的設置時mImageReader.getSurface()
作為目標mPreviewRequestBuilder
是:
[13, 18, 25, 28, 30, 30, 30, 30 ]
因此,一種解決方案是使用較低的分辨率來實現您想要的速率。 對於好奇......請注意,這些時間似乎不受線路的影響
mPreviewRequestBuilder.addTarget(surface);
...
mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
我擔心在屏幕上添加表面可能會增加開銷,但如果我刪除第一行並將第二行更改為
mCameraDevice.createCaptureSession(Arrays.asList(mImageReader.getSurface()),
然后我看到時間變化小於1 fps。 因此,您是否也在屏幕上顯示圖像似乎並不重要。
我認為在camera2 API或ImageReader的框架中只有一些開銷,這使得無法獲得TextureView明顯獲得的全部速率。
最令人失望的事情之一是,如果您切換回不推薦使用的Camera API,您可以通過Camera.setPreviewCallbackWithBuffer
方法設置PreviewCallback
,輕松獲得30 fps。 使用該方法,無論分辨率如何,我都能獲得30fps。 具體來說,雖然它不直接提供1600x1200,但它確實提供1920x1080,甚至是30fps。
我正在嘗試相同的事情,我想你可能會改變格式
mImageReader = ImageReader.newInstance(largestSize.getWidth(),
largestSize.getHeight(),
ImageFormat.FLEX_RGB_888, 3);
因為使用YUV可能會導致CPU壓縮數據,並且可能需要一些時間。 RGB可以直接顯示在設備上。 並且從圖像中檢測到臉部應該放入其他線程中你必須知道它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.