【发布时间】:2021-08-27 19:46:52
【问题描述】:
我有一个 XR 应用程序,其中显示屏显示摄像头(后部)馈送。因此,捕获屏幕与捕获相机馈送几乎相同...... 因此,我截取屏幕截图(位图),然后尝试使用 Google MLKit 检测其中的人脸。
我正在关注official guide 来检测人脸。
为此,我首先启动我的面部检测器:
FaceDetector detector;
public MyFaceDetector(){
FaceDetectorOptions realTimeOpts =
new FaceDetectorOptions.Builder()
.setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
.build();
detector = FaceDetection.getClient(realTimeOpts);
}
然后我有一个传入位图的函数。我首先将位图转换为字节数组。我这样做是因为InputImage.fromBitmap 非常慢,而且 MLKit 实际上告诉我应该使用字节数组:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
接下来,我制作 Bitmap 的可变副本(以便我可以在其上绘制),并设置一个 Canvas 对象,以及在 Bitmap 上绘制时将使用的颜色:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, options);
Canvas canvas = new Canvas(bmp);
Paint p = new Paint();
p.setColor(Color.RED);
所有设置完成后,我使用字节数组创建了一个InputImage(由 FaceDetector 使用):
InputImage image = InputImage.fromByteArray(byteArray, bmp.getWidth(), bmp.getHeight(),0, InputImage.IMAGE_FORMAT_NV21);
注意图像格式...有一个InputImage.IMAGE_FORMAT_BITMAP,但使用它会引发 IllegalArgumentException。无论如何,我接下来尝试处理 Bitmap,检测人脸,用之前定义的颜色填充每个检测到的人脸,然后将 Bitmap 保存到磁盘:
Task<List<Face>> result = detector.process(image).addOnSuccessListener(
new OnSuccessListener<List<Face>>() {
@Override
public void onSuccess(List<Face> faces) {
Log.e("FACE DETECTION APP", "NUMBER OF FACES: " + faces.size());
Thread processor = new Thread(new Runnable() {
@Override
public void run() {
for (Face face : faces) {
Rect destinationRect = face.getBoundingBox();
canvas.drawRect(destinationRect, p);
canvas.save();
Log.e("FACE DETECTION APP", "WE GOT SOME FACCES!!!");
}
File file = new File(someFilePath);
try {
FileOutputStream fOut = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
});
processor.start();
}
})
.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Task failed with an exception
// ...
}
});
}
虽然此代码运行(即没有异常)并且位图已正确写入磁盘,但从未检测到任何人脸 (faces.size() is always 0)。我试过旋转图像。我试过改变位图的质量。我已经尝试使用和不使用线程来处理任何检测到的面孔。我已经尝试了所有我能想到的。
有人有什么想法吗?
【问题讨论】:
-
ML 套件输入图像。 fromByteArray 仅支持 yv12 和 nv21 格式。您需要将位图转换为其中一种格式,以便 ML 套件管道进行处理。此外,如果您拥有的原始图像是位图,您可能只使用 InputImage.fromBitmap 来构造 InputImage。它不应该比您当前的方法慢。
标签: java android bitmap face-detection google-mlkit