是的,可以将 Camera2 API 与 Google Vision API 一起使用。
首先,Google Vision API 人脸检测器接收Frame https://developers.google.com/android/reference/com/google/android/gms/vision/Frame.Builder用于分析(检测面部及其地标)的对象。
Camera1 API 提供了 NV21 图像格式的预览帧,这对我们来说是理想的选择。 Google Vision Frame.Builder 同时支持设置图像数据 https://developers.google.com/android/reference/com/google/android/gms/vision/Frame.Builder.html#setImageData(java.nio.ByteBuffer,%20int,%20int,%20int)(NV16、NV21 或 YV12 图像格式的 ByteBuffer)和设置位图 https://developers.google.com/android/reference/com/google/android/gms/vision/Frame.Builder.html#setBitmap(android.graphics.Bitmap)使用位图作为预览帧进行处理。
您的问题是 Camera2 API 提供了不同格式的预览帧。这是YUV_420_888 https://developer.android.com/reference/android/graphics/ImageFormat.html#YUV_420_888。为了使一切正常工作,您必须将预览帧转换为支持的格式之一。
一旦你从你的相机获得了Camera2预览帧图像读取器 https://developer.android.com/reference/android/media/ImageReader.html as Image https://developer.android.com/reference/android/media/Image.html您可以使用此函数将其转换为支持的格式(在本例中为 NV21)。
private byte[] convertYUV420888ToNV21(Image imgYUV420) {
// Converting YUV_420_888 data to YUV_420_SP (NV21).
byte[] data;
ByteBuffer buffer0 = imgYUV420.getPlanes()[0].getBuffer();
ByteBuffer buffer2 = imgYUV420.getPlanes()[2].getBuffer();
int buffer0_size = buffer0.remaining();
int buffer2_size = buffer2.remaining();
data = new byte[buffer0_size + buffer2_size];
buffer0.get(data, 0, buffer0_size);
buffer2.get(data, buffer0_size, buffer2_size);
return data;
}
然后你可以使用返回的 byte[] 创建一个 Google Vision Frame:
outputFrame = new Frame.Builder()
.setImageData(nv21bytes, mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.NV21)
.setId(mPendingFrameId)
.setTimestampMillis(mPendingTimeMillis)
.setRotation(mSensorOrientation)
.build();
最后,您使用创建的框架调用检测器:
mDetector.receiveFrame(outputFrame);
不管怎样,如果你想了解更多信息,你可以在 GitHub 上免费测试我的工作示例:相机视觉 https://github.com/EzequielAdrianM/Camera2Vision。我希望我有所帮助:)