【发布时间】:2019-12-30 14:50:54
【问题描述】:
对于 NVIDIA 盾牌上的个人应用程序,我正在使用 Firebase 的 MLKit 和面部检测功能,但从 OpenCV 传递 Mat 并不能真正起作用。
在我的 android 应用程序中,我使用了一个使用 OpenCV 制作的自定义相机视图,它在它处理的每一帧上创建返回一个 Mat。在这个过程中,我正在检查每一帧的脸。
我尝试的第一件事是使用以下代码将 Mat 转换为 Bitmap:
public static Bitmap bitmapFromMat(Mat mRgba) {
Bitmap bitmap = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mRgba, bitmap);
return bitmap;
}
之后,我将位图传递给使用以下代码的 firebase:
FirebaseVisionImage fbImage = FirebaseVisionImage.fromBitmap(bitmap);
fbDetector.detectInImage(fbImage) ....
这在运行应用程序的前 1 分钟内运行良好。之后,应用程序开始严重滞后并停止工作,没有任何错误消息。在运行日志中,我看到了一条没有使用相机位图的消息。
之后,我一直在寻找将 Mat 转换为 bytearray 和 bytebuffer 的解决方案,但我尝试过的所有解决方案都失败了。 创建元数据的代码:
metadata = new FirebaseVisionImageMetadata.Builder()
.setWidth(mFrame.width())
.setHeight(mFrame.height())
.setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
.setRotation(FirebaseVisionImageMetadata.ROTATION_0)
.build();
(为了确保我将轮换更改为每种可能性并进行了测试)
我用来从 Mat 转换为 bytearray 的代码:
byte[] bytes = new byte[(int) (mFrame.total() * mFrame.channels())];
mFrame.get(0,0, bytes);
FirebaseVisionImage fbImage = FirebaseVisionImage.fromByteArray(bytes, metadata);
(发生的情况是人脸检测返回 0 个人脸)
我用来将位图转换为字节缓冲区的代码:
int size = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer byteBuffer = ByteBuffer.allocate(size);
bitmap.copyPixelsToBuffer(byteBuffer);
FirebaseVisionImage fbImage = FirebaseVisionImage.fromByteBuffer(byteBuffer, metadata);
(发生的情况是人脸检测返回 0 个人脸)
我期望的是每帧都会检测到一张脸,但遗憾的是事实并非如此。当前的结果要么是巨大的延迟导致崩溃,要么是检测到 0 个面孔。
希望有人能帮我解决这个问题!
提前非常感谢!
【问题讨论】:
标签: android firebase opencv firebase-mlkit