获取摄像头数据是实现图像处理的基础步骤之一。在android中,获取摄像头数据可以通过使用Camera API 或者 Camera2 API进行。Camera API 相对来说更简单易懂,但是功能较少;而相比之下,Camera2 API更加的灵活,但是需要较高的编程能力进行开发。无论使用哪种API,获取摄像头数据,格式化,都是必须掌握的内容。
获取摄像头数据:
在android中通过API的方式获取摄像头数据是较为常见的方式。Camera类和Camera2类分别对应这两种API,下面分别进行介绍。
Camera API:
Camera类可以通过 setPreviewCallback() 方法获取预览数据。setPreviewCallback() 方法中传入的参数是一个 PreviewCallback 接口,该接口实现了一个方法 onPreviewFrame(),在该方法中,可以获取到摄像头预览画面数据。onPreviewFrame()产生的数据是一个字节数组,包含了摄像头输出的图像数据,但是只能获取回顶部的图像数据。代码类似下面这样:
```
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// 图像处理代码
// data就是获取到的图像数据
}
});
```
Camera2 API:
在Camera2 API中,可以通过 CameraCaptureSession 类和 ImageReader 类获取摄像头数据。在使用Camera2 API时,需要先进行初始化:
```
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
cameraDevice = cameraManager.openCamera(cameraId, deviceStateCallback, null);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
```
使用CameraCaptureSession 捕捉图像:
```
imageReader = ImageReader.newInstance(
1080, 1920, format, /*maxImages*/2);
imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireNextImage();
// 将摄像头数据交给OpenGL处理
image.close();
}
}, mBackgroundHandler);
// 配置你的捕捉请求
List
surfaceList.add(mPreviewView.getHolder().getSurface());
surfaceList.add(imageReader.getSurface());
captureRequestBuilder.addTarget(mPreviewView.getHolder().getSurface());
captureRequestBuilder.addTarget(imageReader.getSurface());
```
通过 ImageReader 类获取摄像头数据:
```
Image image = imageReader.acquireLatestImage();
if(image == null) return;
int width = image.getWidth();
int height = image.getHeight();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
image.close();
```
摄像头数据格式化:
获取到的摄像头数据是一个byte数组,在使用时,需要将其进行格式化。常用的格式化方式有以下几种:
1. RGB格式数据:
在一个 RGB 图像中,每个像素由一个红色、绿色和蓝色三色组成。将RGB数据格式化成单通道灰度图像,可以通过求RGB三分量的平均值获得。
```
for (int i = 0; i < widht*height; i++) {
byte grey = (byte) ((data[i * 3] & 0xFF + data[i * 3 + 1] & 0xFF + data[i * 3 + 2] & 0xFF) / 3);
// 处理数据
}
```
2. YUV格式数据:
在一个YUV图像中,每个像素由一个亮度值(Y)和两个色度值(U、V)组成。YUV数据的格式化,可以通过使用色度约束矩阵来计算每个像素的亮度。在android中,比较常用的格式有YCbCr和YUV420。
```
byte[] yuv = new byte[width * height * 3 / 2];
YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, width, height, null);
yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, new ByteArrayOutputStream());
new ByteArrayInputStream(out.toByteArray()).read(yuv, 0, yuv.length);
```
总结:
通过Camera API或者Camera2 API获取到的摄像头数据都是未格式化的,需要进行格式化后,才能进行图像处理。在格式化时,常用的有RGB格式化和YUV格式化两种方式,在使用时,需要根据实际情况进行选择。